aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorUbitUmarov2017-08-16 05:05:57 +0100
committerUbitUmarov2017-08-16 05:05:57 +0100
commit6d4b0a8ce3713eb45170f50b71d295ebaef0e51d (patch)
treeba57d22e92ae6cadef8af599a2aa4f2a78057fce /OpenSim
parentfix merge issues (diff)
parentMerge branch 'master' into BulletSim2017 (diff)
downloadopensim-SC-6d4b0a8ce3713eb45170f50b71d295ebaef0e51d.zip
opensim-SC-6d4b0a8ce3713eb45170f50b71d295ebaef0e51d.tar.gz
opensim-SC-6d4b0a8ce3713eb45170f50b71d295ebaef0e51d.tar.bz2
opensim-SC-6d4b0a8ce3713eb45170f50b71d295ebaef0e51d.tar.xz
Merge branch 'master' into httptests
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/SQLite/SQLiteXInventoryData.cs10
-rw-r--r--OpenSim/Framework/AnimationSet.cs22
-rw-r--r--OpenSim/Framework/IMoneyModule.cs1
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs12
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs120
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs15
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs24
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs32
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs118
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs351
-rw-r--r--OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs7
-rwxr-xr-xOpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs24
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs39
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs8
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs392
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs2
-rw-r--r--OpenSim/Services/HypergridService/GatekeeperService.cs7
-rw-r--r--OpenSim/Tests/Permissions/DirectTransferTests.cs7
-rw-r--r--OpenSim/Tests/Permissions/IndirectTransferTests.cs9
25 files changed, 735 insertions, 484 deletions
diff --git a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
index 7f44a65..4ef1f30 100644
--- a/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
+++ b/OpenSim/Data/SQLite/SQLiteXInventoryData.cs
@@ -305,17 +305,11 @@ namespace OpenSim.Data.SQLite
305 305
306 using (SqliteCommand cmd = new SqliteCommand()) 306 using (SqliteCommand cmd = new SqliteCommand())
307 { 307 {
308 cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = ?folderID"; 308 cmd.CommandText = "update inventoryfolders set version=version+1 where folderID = :folderID";
309 cmd.Parameters.Add(new SqliteParameter(":folderID", folderID)); 309 cmd.Parameters.Add(new SqliteParameter(":folderID", folderID));
310 310
311 try 311 if(ExecuteNonQuery(cmd, m_Connection) == 0)
312 {
313 cmd.ExecuteNonQuery();
314 }
315 catch (Exception)
316 {
317 return false; 312 return false;
318 }
319 } 313 }
320 314
321 return true; 315 return true;
diff --git a/OpenSim/Framework/AnimationSet.cs b/OpenSim/Framework/AnimationSet.cs
index 87c4a78..8753088 100644
--- a/OpenSim/Framework/AnimationSet.cs
+++ b/OpenSim/Framework/AnimationSet.cs
@@ -31,7 +31,8 @@ using OpenMetaverse;
31 31
32namespace OpenSim.Framework 32namespace OpenSim.Framework
33{ 33{
34 public delegate bool AnimationSetValidator(UUID animID); 34// public delegate bool AnimationSetValidator(UUID animID);
35 public delegate uint AnimationSetValidator(UUID animID);
35 36
36 public class AnimationSet 37 public class AnimationSet
37 { 38 {
@@ -141,7 +142,7 @@ namespace OpenSim.Framework
141 assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key); 142 assetData += String.Format("{0} {1} {2}\n", kvp.Key, kvp.Value.Value.ToString(), kvp.Value.Key);
142 return System.Text.Encoding.ASCII.GetBytes(assetData); 143 return System.Text.Encoding.ASCII.GetBytes(assetData);
143 } 144 }
144 145/*
145 public bool Validate(AnimationSetValidator val) 146 public bool Validate(AnimationSetValidator val)
146 { 147 {
147 if (m_parseError) 148 if (m_parseError)
@@ -164,5 +165,22 @@ namespace OpenSim.Framework
164 165
165 return allOk; 166 return allOk;
166 } 167 }
168*/
169 public uint Validate(AnimationSetValidator val)
170 {
171 if (m_parseError)
172 return 0;
173
174 uint ret = 0x7fffffff;
175 uint t;
176 foreach (KeyValuePair<string, KeyValuePair<string, UUID>> kvp in m_animations)
177 {
178 t = val(kvp.Value.Value);
179 if (t == 0)
180 return 0;
181 ret &= t;
182 }
183 return ret;
184 }
167 } 185 }
168} 186}
diff --git a/OpenSim/Framework/IMoneyModule.cs b/OpenSim/Framework/IMoneyModule.cs
index be45438..c72c742 100644
--- a/OpenSim/Framework/IMoneyModule.cs
+++ b/OpenSim/Framework/IMoneyModule.cs
@@ -41,6 +41,7 @@ namespace OpenSim.Framework
41 void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = ""); 41 void ApplyCharge(UUID agentID, int amount, MoneyTransactionType type, string extraData = "");
42 void ApplyUploadCharge(UUID agentID, int amount, string text); 42 void ApplyUploadCharge(UUID agentID, int amount, string text);
43 void MoveMoney(UUID fromUser, UUID toUser, int amount, string text); 43 void MoveMoney(UUID fromUser, UUID toUser, int amount, string text);
44 bool MoveMoney(UUID fromUser, UUID toUser, int amount, MoneyTransactionType type, string text);
44 45
45 int UploadCharge { get; } 46 int UploadCharge { get; }
46 int GroupCreationCharge { get; } 47 int GroupCreationCharge { get; }
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index ce4503c..ca67d84 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -1970,7 +1970,7 @@ namespace OpenSim.Framework.Servers.HttpServer
1970 Hashtable headerdata = (Hashtable)responsedata["headers"]; 1970 Hashtable headerdata = (Hashtable)responsedata["headers"];
1971 1971
1972 foreach (string header in headerdata.Keys) 1972 foreach (string header in headerdata.Keys)
1973 response.AddHeader(header, (string)headerdata[header]); 1973 response.AddHeader(header, headerdata[header].ToString());
1974 } 1974 }
1975 1975
1976 byte[] buffer; 1976 byte[] buffer;
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
index 5011c44..9cfa488 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -491,7 +491,7 @@ namespace OpenSim.Region.ClientStack.Linden
491 catch (Exception e) 491 catch (Exception e)
492 { 492 {
493 m_log.ErrorFormat( 493 m_log.ErrorFormat(
494 "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {3}", 494 "[INVENTORY]: Failed to process queued inventory request {0} for {1}. Exception {2}",
495 poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e); 495 poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", e);
496 } 496 }
497 } 497 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 861b79e..6dd3885 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -6399,6 +6399,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6399 ParcelGodMarkAsContentPacket ParcelGodMarkAsContent = 6399 ParcelGodMarkAsContentPacket ParcelGodMarkAsContent =
6400 (ParcelGodMarkAsContentPacket)Packet; 6400 (ParcelGodMarkAsContentPacket)Packet;
6401 6401
6402 if(SessionId != ParcelGodMarkAsContent.AgentData.SessionID || AgentId != ParcelGodMarkAsContent.AgentData.AgentID)
6403 return false;
6404
6402 ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark; 6405 ParcelGodMark ParcelGodMarkAsContentHandler = OnParcelGodMark;
6403 if (ParcelGodMarkAsContentHandler != null) 6406 if (ParcelGodMarkAsContentHandler != null)
6404 { 6407 {
@@ -6414,6 +6417,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6414 { 6417 {
6415 FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet; 6418 FreezeUserPacket FreezeUser = (FreezeUserPacket)Packet;
6416 6419
6420 if(SessionId != FreezeUser.AgentData.SessionID || AgentId != FreezeUser.AgentData.AgentID)
6421 return false;
6422
6417 FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser; 6423 FreezeUserUpdate FreezeUserHandler = OnParcelFreezeUser;
6418 if (FreezeUserHandler != null) 6424 if (FreezeUserHandler != null)
6419 { 6425 {
@@ -6431,6 +6437,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6431 EjectUserPacket EjectUser = 6437 EjectUserPacket EjectUser =
6432 (EjectUserPacket)Packet; 6438 (EjectUserPacket)Packet;
6433 6439
6440 if(SessionId != EjectUser.AgentData.SessionID || AgentId != EjectUser.AgentData.AgentID)
6441 return false;
6442
6434 EjectUserUpdate EjectUserHandler = OnParcelEjectUser; 6443 EjectUserUpdate EjectUserHandler = OnParcelEjectUser;
6435 if (EjectUserHandler != null) 6444 if (EjectUserHandler != null)
6436 { 6445 {
@@ -6448,6 +6457,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6448 ParcelBuyPassPacket ParcelBuyPass = 6457 ParcelBuyPassPacket ParcelBuyPass =
6449 (ParcelBuyPassPacket)Packet; 6458 (ParcelBuyPassPacket)Packet;
6450 6459
6460 if(SessionId != ParcelBuyPass.AgentData.SessionID || AgentId != ParcelBuyPass.AgentData.AgentID)
6461 return false;
6462
6451 ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass; 6463 ParcelBuyPass ParcelBuyPassHandler = OnParcelBuyPass;
6452 if (ParcelBuyPassHandler != null) 6464 if (ParcelBuyPassHandler != null)
6453 { 6465 {
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index d2aa177..52b9d0e 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -258,24 +258,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
258 { 258 {
259 m_uploadState = UploadState.Complete; 259 m_uploadState = UploadState.Complete;
260 260
261 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); 261 bool sucess = true;
262
263 if (m_createItem) 262 if (m_createItem)
264 { 263 {
265 CompleteCreateItem(m_createItemCallback); 264 sucess = CompleteCreateItem(m_createItemCallback);
266 } 265 }
267 else if (m_updateItem) 266 else if (m_updateItem)
268 { 267 {
269 CompleteItemUpdate(m_updateItemData); 268 sucess = CompleteItemUpdate(m_updateItemData);
270 } 269 }
271 else if (m_updateTaskItem) 270 else if (m_updateTaskItem)
272 { 271 {
273 CompleteTaskItemUpdate(m_updateTaskItemData); 272 sucess = CompleteTaskItemUpdate(m_updateTaskItemData);
274 } 273 }
275 else if (m_asset.Local) 274 else if (m_asset.Local)
276 { 275 {
277 m_Scene.AssetService.Store(m_asset); 276 m_Scene.AssetService.Store(m_asset);
278 } 277 }
278 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, sucess, m_asset.FullID);
279 } 279 }
280 280
281 m_log.DebugFormat( 281 m_log.DebugFormat(
@@ -411,46 +411,70 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
411 /// Store the asset for the given item when it has been uploaded. 411 /// Store the asset for the given item when it has been uploaded.
412 /// </summary> 412 /// </summary>
413 /// <param name="item"></param> 413 /// <param name="item"></param>
414 private void CompleteItemUpdate(InventoryItemBase item) 414 private bool CompleteItemUpdate(InventoryItemBase item)
415 { 415 {
416// m_log.DebugFormat( 416// m_log.DebugFormat(
417// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", 417// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
418// m_asset.FullID, item.Name, ourClient.Name); 418// m_asset.FullID, item.Name, ourClient.Name);
419 419
420 ValidateAssets(); 420 uint perms = ValidateAssets();
421 m_Scene.AssetService.Store(m_asset); 421 if(perms == 0)
422 if (m_asset.FullID != UUID.Zero)
423 { 422 {
424 item.AssetID = m_asset.FullID; 423 string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', update failed", item.Name);
425 m_Scene.InventoryService.UpdateItem(item); 424 ourClient.SendAlertMessage(error);
425 m_transactions.RemoveXferUploader(m_transactionID);
426 ourClient.SendBulkUpdateInventory(item); // invalid the change item on viewer cache
427 }
428 else
429 {
430 m_Scene.AssetService.Store(m_asset);
431 if (m_asset.FullID != UUID.Zero)
432 {
433 item.AssetID = m_asset.FullID;
434 m_Scene.InventoryService.UpdateItem(item);
435 }
436 ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0);
437 m_transactions.RemoveXferUploader(m_transactionID);
438 m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0);
426 } 439 }
427 440
428 ourClient.SendInventoryItemCreateUpdate(item, m_transactionID, 0); 441 return perms != 0;
429
430 m_transactions.RemoveXferUploader(m_transactionID);
431
432 m_Scene.EventManager.TriggerOnNewInventoryItemUploadComplete(item, 0);
433 } 442 }
434 443
435 /// <summary> 444 /// <summary>
436 /// Store the asset for the given task item when it has been uploaded. 445 /// Store the asset for the given task item when it has been uploaded.
437 /// </summary> 446 /// </summary>
438 /// <param name="taskItem"></param> 447 /// <param name="taskItem"></param>
439 private void CompleteTaskItemUpdate(TaskInventoryItem taskItem) 448 private bool CompleteTaskItemUpdate(TaskInventoryItem taskItem)
440 { 449 {
441// m_log.DebugFormat( 450// m_log.DebugFormat(
442// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}", 451// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier task item update for {1} for {2}",
443// m_asset.FullID, taskItem.Name, ourClient.Name); 452// m_asset.FullID, taskItem.Name, ourClient.Name);
444 453
445 ValidateAssets(); 454 if(ValidateAssets() == 0)
446 m_Scene.AssetService.Store(m_asset); 455 {
456 m_transactions.RemoveXferUploader(m_transactionID);
457 string error = string.Format("Not enough permissions on asset(s) referenced by task item '{0}', update failed", taskItem.Name);
458 ourClient.SendAlertMessage(error);
459 // force old asset to viewers ??
460 return false;
461 }
447 462
463 m_Scene.AssetService.Store(m_asset);
448 m_transactions.RemoveXferUploader(m_transactionID); 464 m_transactions.RemoveXferUploader(m_transactionID);
465 return true;
449 } 466 }
450 467
451 private void CompleteCreateItem(uint callbackID) 468 private bool CompleteCreateItem(uint callbackID)
452 { 469 {
453 ValidateAssets(); 470 if(ValidateAssets() == 0)
471 {
472 m_transactions.RemoveXferUploader(m_transactionID);
473 string error = string.Format("Not enough permissions on asset(s) referenced by item '{0}', creation failed", m_name);
474 ourClient.SendAlertMessage(error);
475 return false;
476 }
477
454 m_Scene.AssetService.Store(m_asset); 478 m_Scene.AssetService.Store(m_asset);
455 479
456 InventoryItemBase item = new InventoryItemBase(); 480 InventoryItemBase item = new InventoryItemBase();
@@ -480,35 +504,40 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
480 ourClient.SendAlertMessage("Unable to create inventory item"); 504 ourClient.SendAlertMessage("Unable to create inventory item");
481 505
482 m_transactions.RemoveXferUploader(m_transactionID); 506 m_transactions.RemoveXferUploader(m_transactionID);
507 return true;
483 } 508 }
484 509
485 510 private uint ValidateAssets()
486 private void ValidateAssets()
487 { 511 {
512 uint retPerms = 0x7fffffff;
513// if(m_Scene.Permissions.BypassPermissions())
514// return retPerms;
515
488 if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet) 516 if (m_asset.Type == (sbyte)CustomAssetType.AnimationSet)
489 { 517 {
518
490 AnimationSet animSet = new AnimationSet(m_asset.Data); 519 AnimationSet animSet = new AnimationSet(m_asset.Data);
491 520
492 bool allOk = animSet.Validate(x => { 521 retPerms &= animSet.Validate(x => {
493 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x); 522 const uint required = (uint)(PermissionMask.Transfer | PermissionMask.Copy);
494 int required = (int)(PermissionMask.Transfer | PermissionMask.Copy); 523 uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, x);
524 // currrent yes/no rule
495 if ((perms & required) != required) 525 if ((perms & required) != required)
496 return false; 526 return 0;
497 return true; 527 return perms;
498 }); 528 });
499 529
500 if (!allOk) 530 return retPerms;
501 m_asset.Data = animSet.ToBytes();
502 } 531 }
503 532
504 if (m_asset.Type == (sbyte)AssetType.Clothing || 533 if (m_asset.Type == (sbyte)AssetType.Clothing ||
505 m_asset.Type == (sbyte)AssetType.Bodypart) 534 m_asset.Type == (sbyte)AssetType.Bodypart)
506 { 535 {
536 const uint texturesfullPermMask = (uint)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
507 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data); 537 string content = System.Text.Encoding.ASCII.GetString(m_asset.Data);
508 string[] lines = content.Split(new char[] {'\n'}); 538 string[] lines = content.Split(new char[] {'\n'});
509 539
510 List<string> validated = new List<string>(); 540 // on current requiriment of full rigths assume old assets where accepted
511
512 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData(); 541 Dictionary<int, UUID> allowed = ExtractTexturesFromOldData();
513 542
514 int textures = 0; 543 int textures = 0;
@@ -518,10 +547,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
518 try 547 try
519 { 548 {
520 if (line.StartsWith("textures ")) 549 if (line.StartsWith("textures "))
521 {
522 textures = Convert.ToInt32(line.Substring(9)); 550 textures = Convert.ToInt32(line.Substring(9));
523 validated.Add(line); 551
524 }
525 else if (textures > 0) 552 else if (textures > 0)
526 { 553 {
527 string[] parts = line.Split(new char[] {' '}); 554 string[] parts = line.Split(new char[] {' '});
@@ -532,42 +559,35 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
532 if (defaultIDs.Contains(tx) || tx == UUID.Zero || 559 if (defaultIDs.Contains(tx) || tx == UUID.Zero ||
533 (allowed.ContainsKey(id) && allowed[id] == tx)) 560 (allowed.ContainsKey(id) && allowed[id] == tx))
534 { 561 {
535 validated.Add(parts[0] + " " + tx.ToString()); 562 continue;
536 } 563 }
537 else 564 else
538 { 565 {
539 int perms = m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx); 566 uint perms = (uint)m_Scene.InventoryService.GetAssetPermissions(ourClient.AgentId, tx);
540 int full = (int)(PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Copy);
541 567
542 if ((perms & full) != full) 568 if ((perms & texturesfullPermMask) != texturesfullPermMask)
543 { 569 {
544 m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId); 570 m_log.ErrorFormat("[ASSET UPLOADER]: REJECTED update with texture {0} from {1} because they do not own the texture", tx, ourClient.AgentId);
545 validated.Add(parts[0] + " " + UUID.Zero.ToString()); 571 return 0;
546 } 572 }
547 else 573 else
548 { 574 {
549 validated.Add(line); 575 retPerms &= perms;
550 } 576 }
551 } 577 }
552 textures--; 578 textures--;
553 } 579 }
554 else
555 {
556 validated.Add(line);
557 }
558 } 580 }
559 catch 581 catch
560 { 582 {
561 // If it's malformed, skip it 583 // If it's malformed, skip it
562 } 584 }
563 } 585 }
564
565 string final = String.Join("\n", validated.ToArray());
566
567 m_asset.Data = System.Text.Encoding.ASCII.GetBytes(final);
568 } 586 }
587 return retPerms;
569 } 588 }
570 589
590/* not in use
571 /// <summary> 591 /// <summary>
572 /// Get the asset data uploaded in this transfer. 592 /// Get the asset data uploaded in this transfer.
573 /// </summary> 593 /// </summary>
@@ -582,7 +602,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
582 602
583 return null; 603 return null;
584 } 604 }
585 605*/
586 public void SetOldData(byte[] d) 606 public void SetOldData(byte[] d)
587 { 607 {
588 m_oldData = d; 608 m_oldData = d;
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index f1409bb..788ed1c 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -299,15 +299,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
299 else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet) 299 else if ((CustomInventoryType)item.InvType == CustomInventoryType.AnimationSet)
300 { 300 {
301 AnimationSet animSet = new AnimationSet(data); 301 AnimationSet animSet = new AnimationSet(data);
302 if (!animSet.Validate(x => { 302 uint res = animSet.Validate(x => {
303 const int required = (int)(PermissionMask.Transfer | PermissionMask.Copy);
303 int perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x); 304 int perms = m_Scene.InventoryService.GetAssetPermissions(remoteClient.AgentId, x);
304 int required = (int)(PermissionMask.Transfer | PermissionMask.Copy); 305 // enforce previus perm rule
305 if ((perms & required) != required) 306 if ((perms & required) != required)
306 return false; 307 return 0;
307 return true; 308 return (uint) perms;
308 })) 309 });
310 if(res == 0)
309 { 311 {
310 data = animSet.ToBytes(); 312 remoteClient.SendAgentAlertMessage("Not enought permissions on asset(s) referenced by animation set '{0}', update failed", false);
313 return UUID.Zero;
311 } 314 }
312 } 315 }
313 316
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
index 5efdd9b..7a4f981 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs
@@ -250,7 +250,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
250 if (inventoryURL != null && inventoryURL != string.Empty) 250 if (inventoryURL != null && inventoryURL != string.Empty)
251 { 251 {
252 inventoryURL = inventoryURL.Trim(new char[] { '/' }); 252 inventoryURL = inventoryURL.Trim(new char[] { '/' });
253 m_InventoryURLs[userID] = inventoryURL; 253 lock (m_InventoryURLs)
254 m_InventoryURLs[userID] = inventoryURL;
254 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL); 255 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
255 return; 256 return;
256 } 257 }
@@ -268,35 +269,42 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
268 if (!string.IsNullOrEmpty(inventoryURL)) 269 if (!string.IsNullOrEmpty(inventoryURL))
269 { 270 {
270 inventoryURL = inventoryURL.Trim(new char[] { '/' }); 271 inventoryURL = inventoryURL.Trim(new char[] { '/' });
271 m_InventoryURLs.Add(userID, inventoryURL); 272 lock (m_InventoryURLs)
273 m_InventoryURLs[userID] = inventoryURL;
272 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL); 274 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
273 } 275 }
274
275 } 276 }
276
277 } 277 }
278 } 278 }
279 279
280 private void DropInventoryServiceURL(UUID userID) 280 private void DropInventoryServiceURL(UUID userID)
281 { 281 {
282 lock (m_InventoryURLs) 282 lock (m_InventoryURLs)
283 {
283 if (m_InventoryURLs.ContainsKey(userID)) 284 if (m_InventoryURLs.ContainsKey(userID))
284 { 285 {
285 string url = m_InventoryURLs[userID]; 286 string url = m_InventoryURLs[userID];
286 m_InventoryURLs.Remove(userID); 287 m_InventoryURLs.Remove(userID);
287 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Removed {0} from the cache of inventory URLs", url); 288 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Removed {0} from the cache of inventory URLs", url);
288 } 289 }
290 }
289 } 291 }
290 292
291 public string GetInventoryServiceURL(UUID userID) 293 public string GetInventoryServiceURL(UUID userID)
292 { 294 {
293 if (m_InventoryURLs.ContainsKey(userID)) 295 lock (m_InventoryURLs)
294 return m_InventoryURLs[userID]; 296 {
297 if (m_InventoryURLs.ContainsKey(userID))
298 return m_InventoryURLs[userID];
299 }
295 300
296 CacheInventoryServiceURL(userID); 301 CacheInventoryServiceURL(userID);
297 302
298 if (m_InventoryURLs.ContainsKey(userID)) 303 lock (m_InventoryURLs)
299 return m_InventoryURLs[userID]; 304 {
305 if (m_InventoryURLs.ContainsKey(userID))
306 return m_InventoryURLs[userID];
307 }
300 308
301 return null; //it means that the methods should forward to local grid's inventory 309 return null; //it means that the methods should forward to local grid's inventory
302 310
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index 6ba8cec..99ff9b5 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -286,6 +286,11 @@ namespace OpenSim.Region.CoreModules.World.Archiver
286 /// </summary> 286 /// </summary>
287 public void DearchiveRegion() 287 public void DearchiveRegion()
288 { 288 {
289 DearchiveRegion(true);
290 }
291
292 public void DearchiveRegion(bool shouldStartScripts)
293 {
289 int successfulAssetRestores = 0; 294 int successfulAssetRestores = 0;
290 int failedAssetRestores = 0; 295 int failedAssetRestores = 0;
291 296
@@ -425,22 +430,25 @@ namespace OpenSim.Region.CoreModules.World.Archiver
425 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so 430 // Start the scripts. We delayed this because we want the OAR to finish loading ASAP, so
426 // that users can enter the scene. If we allow the scripts to start in the loop above 431 // that users can enter the scene. If we allow the scripts to start in the loop above
427 // then they significantly increase the time until the OAR finishes loading. 432 // then they significantly increase the time until the OAR finishes loading.
428 WorkManager.RunInThread(o => 433 if (shouldStartScripts)
429 { 434 {
430 Thread.Sleep(15000); 435 WorkManager.RunInThread(o =>
431 m_log.Info("[ARCHIVER]: Starting scripts in scene objects");
432
433 foreach (DearchiveContext sceneContext in sceneContexts.Values)
434 { 436 {
435 foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects) 437 Thread.Sleep(15000);
438 m_log.Info("[ARCHIVER]: Starting scripts in scene objects");
439
440 foreach (DearchiveContext sceneContext in sceneContexts.Values)
436 { 441 {
437 sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart 442 foreach (SceneObjectGroup sceneObject in sceneContext.SceneObjects)
438 sceneObject.ResumeScripts(); 443 {
439 } 444 sceneObject.CreateScriptInstances(0, false, sceneContext.Scene.DefaultScriptEngine, 0); // StateSource.RegionStart
445 sceneObject.ResumeScripts();
446 }
440 447
441 sceneContext.SceneObjects.Clear(); 448 sceneContext.SceneObjects.Clear();
442 } 449 }
443 }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId)); 450 }, null, string.Format("ReadArchiveStartScripts (request {0})", m_requestId));
451 }
444 452
445 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive"); 453 m_log.InfoFormat("[ARCHIVER]: Successfully loaded archive");
446 454
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index c7e58e5..760f621 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -41,6 +41,7 @@ using OpenSim.Framework;
41using OpenSim.Framework.Capabilities; 41using OpenSim.Framework.Capabilities;
42using OpenSim.Framework.Console; 42using OpenSim.Framework.Console;
43using OpenSim.Framework.Servers; 43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Monitoring;
44using OpenSim.Framework.Servers.HttpServer; 45using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces; 46using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 47using OpenSim.Region.Framework.Scenes;
@@ -216,6 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Land
216 client.OnParcelEjectUser += ClientOnParcelEjectUser; 217 client.OnParcelEjectUser += ClientOnParcelEjectUser;
217 client.OnParcelFreezeUser += ClientOnParcelFreezeUser; 218 client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
218 client.OnSetStartLocationRequest += ClientOnSetHome; 219 client.OnSetStartLocationRequest += ClientOnSetHome;
220 client.OnParcelBuyPass += ClientParcelBuyPass;
219 } 221 }
220 222
221 public void EventMakeChildAgent(ScenePresence avatar) 223 public void EventMakeChildAgent(ScenePresence avatar)
@@ -537,6 +539,118 @@ namespace OpenSim.Region.CoreModules.World.Land
537 } 539 }
538 } 540 }
539 541
542 public void ClientParcelBuyPass(IClientAPI remote_client, UUID targetID, int landLocalID)
543 {
544 ILandObject land;
545 lock (m_landList)
546 {
547 m_landList.TryGetValue(landLocalID, out land);
548 }
549 // trivial checks
550 if(land == null)
551 return;
552
553 LandData ldata = land.LandData;
554
555 if(ldata == null)
556 return;
557
558 if(ldata.OwnerID == targetID)
559 return;
560
561 if(ldata.PassHours == 0)
562 return;
563
564 // don't allow passes on group owned until we can give money to groups
565 if(ldata.IsGroupOwned)
566 {
567 remote_client.SendAgentAlertMessage("pass to group owned parcel not suported", false);
568 return;
569 }
570
571 if((ldata.Flags & (uint)ParcelFlags.UsePassList) == 0)
572 return;
573
574 int cost = ldata.PassPrice;
575
576 int idx = land.LandData.ParcelAccessList.FindIndex(
577 delegate(LandAccessEntry e)
578 {
579 if (e.AgentID == targetID && e.Flags == AccessList.Access)
580 return true;
581 return false;
582 });
583 int now = Util.UnixTimeSinceEpoch();
584 int expires = (int)(3600.0 * ldata.PassHours + 0.5f);
585 int currenttime = -1;
586 if (idx != -1)
587 {
588 if(ldata.ParcelAccessList[idx].Expires == 0)
589 {
590 remote_client.SendAgentAlertMessage("You already have access to parcel", false);
591 return;
592 }
593
594 currenttime = ldata.ParcelAccessList[idx].Expires - now;
595 if(currenttime > (int)(0.25f * expires + 0.5f))
596 {
597 if(currenttime > 3600)
598 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.###} hours",
599 currenttime/3600f), false);
600 else if(currenttime > 60)
601 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.##} minutes",
602 currenttime/60f), false);
603 else
604 remote_client.SendAgentAlertMessage(string.Format("You already have a pass valid for {0:0.#} seconds",
605 currenttime), false);
606 return;
607 }
608 }
609
610 LandAccessEntry entry = new LandAccessEntry();
611 entry.AgentID = targetID;
612 entry.Flags = AccessList.Access;
613 entry.Expires = now + expires;
614 if(currenttime > 0)
615 entry.Expires += currenttime;
616 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
617 if(cost != 0 && mm != null)
618 {
619 WorkManager.RunInThreadPool(
620 delegate
621 {
622 string regionName = m_scene.RegionInfo.RegionName;
623
624 if (!mm.AmountCovered(remote_client.AgentId, cost))
625 {
626 remote_client.SendAgentAlertMessage(String.Format("Insufficient funds in region '{0}' money system", regionName), true);
627 return;
628 }
629
630 string payDescription = String.Format("Parcel '{0}' at region '{1} {2:0.###} hours access pass", ldata.Name, regionName, ldata.PassHours);
631
632 if(!mm.MoveMoney(remote_client.AgentId, ldata.OwnerID, cost,MoneyTransactionType.LandPassSale, payDescription))
633 {
634 remote_client.SendAgentAlertMessage("Sorry pass payment processing failed, please try again later", true);
635 return;
636 }
637
638 if (idx != -1)
639 ldata.ParcelAccessList.RemoveAt(idx);
640 ldata.ParcelAccessList.Add(entry);
641 m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
642 return;
643 }, null, "ParcelBuyPass");
644 }
645 else
646 {
647 if (idx != -1)
648 ldata.ParcelAccessList.RemoveAt(idx);
649 ldata.ParcelAccessList.Add(entry);
650 m_scene.EventManager.TriggerLandObjectUpdated((uint)land.LandData.LocalID, land);
651 }
652 }
653
540 public void ClientOnParcelAccessListRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID, 654 public void ClientOnParcelAccessListRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID,
541 int landLocalID, IClientAPI remote_client) 655 int landLocalID, IClientAPI remote_client)
542 { 656 {
@@ -1292,7 +1406,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1292 { 1406 {
1293 if (!temp.Contains(currentParcel)) 1407 if (!temp.Contains(currentParcel))
1294 { 1408 {
1295 if (!currentParcel.IsEitherBannedOrRestricted(remote_client.AgentId)) 1409 if (!currentParcel.IsBannedFromLand(remote_client.AgentId))
1296 { 1410 {
1297 currentParcel.ForceUpdateLandInfo(); 1411 currentParcel.ForceUpdateLandInfo();
1298 temp.Add(currentParcel); 1412 temp.Add(currentParcel);
@@ -1766,7 +1880,7 @@ namespace OpenSim.Region.CoreModules.World.Land
1766 land_update.MusicURL = properties.MusicURL; 1880 land_update.MusicURL = properties.MusicURL;
1767 land_update.Name = properties.Name; 1881 land_update.Name = properties.Name;
1768 land_update.ParcelFlags = (uint) properties.ParcelFlags; 1882 land_update.ParcelFlags = (uint) properties.ParcelFlags;
1769 land_update.PassHours = (int) properties.PassHours; 1883 land_update.PassHours = properties.PassHours;
1770 land_update.PassPrice = (int) properties.PassPrice; 1884 land_update.PassPrice = (int) properties.PassPrice;
1771 land_update.SalePrice = (int) properties.SalePrice; 1885 land_update.SalePrice = (int) properties.SalePrice;
1772 land_update.SnapshotID = properties.SnapshotID; 1886 land_update.SnapshotID = properties.SnapshotID;
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index 74b10ed..07d11f9 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -540,7 +540,8 @@ namespace OpenSim.Region.CoreModules.World.Land
540 ParcelFlags.UseEstateVoiceChan); 540 ParcelFlags.UseEstateVoiceChan);
541 } 541 }
542 542
543 if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false)) 543 // don't allow passes on group owned until we can give money to groups
544 if (!newData.IsGroupOwned && m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId,this, GroupPowers.LandManagePasses, false))
544 { 545 {
545 newData.PassHours = args.PassHours; 546 newData.PassHours = args.PassHours;
546 newData.PassPrice = args.PassPrice; 547 newData.PassPrice = args.PassPrice;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 6f46a92..53b7ced 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -657,6 +657,9 @@ namespace OpenSim.Region.Framework.Scenes
657 } 657 }
658 } 658 }
659 659
660// if(!m_scene.IsRunning)
661// return sog;
662
660 if (root.KeyframeMotion != null) 663 if (root.KeyframeMotion != null)
661 root.KeyframeMotion.StartCrossingCheck(); 664 root.KeyframeMotion.StartCrossingCheck();
662 665
@@ -3018,12 +3021,13 @@ namespace OpenSim.Region.Framework.Scenes
3018 3021
3019 // If we somehow got here to updating the SOG and its root part is not scheduled for update, 3022 // If we somehow got here to updating the SOG and its root part is not scheduled for update,
3020 // check to see if the physical position or rotation warrant an update. 3023 // check to see if the physical position or rotation warrant an update.
3024/*
3021 if (m_rootPart.UpdateFlag == UpdateRequired.NONE) 3025 if (m_rootPart.UpdateFlag == UpdateRequired.NONE)
3022 { 3026 {
3023 // rootpart SendScheduledUpdates will check if a update is needed 3027 // rootpart SendScheduledUpdates will check if a update is needed
3024 m_rootPart.UpdateFlag = UpdateRequired.TERSE; 3028 m_rootPart.UpdateFlag = UpdateRequired.TERSE;
3025 } 3029 }
3026 3030*/
3027 if (IsAttachment) 3031 if (IsAttachment)
3028 { 3032 {
3029 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar); 3033 ScenePresence sp = m_scene.GetScenePresence(AttachedAvatar);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index f0a3fab..0370c41 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -238,12 +238,6 @@ namespace OpenSim.Region.Framework.Scenes
238 /// </remarks> 238 /// </remarks>
239 public bool SoundQueueing { get; set; } 239 public bool SoundQueueing { get; set; }
240 240
241 public uint TimeStampFull;
242
243 public uint TimeStampLastActivity; // Will be used for AutoReturn
244
245 public uint TimeStampTerse;
246
247 [XmlIgnore] 241 [XmlIgnore]
248 public Quaternion AttachRotation = Quaternion.Identity; 242 public Quaternion AttachRotation = Quaternion.Identity;
249 243
@@ -1219,6 +1213,7 @@ namespace OpenSim.Region.Framework.Scenes
1219 } 1213 }
1220 1214
1221 public UpdateRequired UpdateFlag { get; set; } 1215 public UpdateRequired UpdateFlag { get; set; }
1216 private object UpdateFlagLock = new object();
1222 1217
1223 /// <summary> 1218 /// <summary>
1224 /// Used for media on a prim. 1219 /// Used for media on a prim.
@@ -1641,8 +1636,10 @@ namespace OpenSim.Region.Framework.Scenes
1641 PhysActor.SetMaterial((int)value); 1636 PhysActor.SetMaterial((int)value);
1642 } 1637 }
1643 if(ParentGroup != null) 1638 if(ParentGroup != null)
1639 {
1644 ParentGroup.HasGroupChanged = true; 1640 ParentGroup.HasGroupChanged = true;
1645 ScheduleFullUpdateIfNone(); 1641 ScheduleFullUpdate();
1642 }
1646 } 1643 }
1647 } 1644 }
1648 } 1645 }
@@ -1675,7 +1672,7 @@ namespace OpenSim.Region.Framework.Scenes
1675 get 1672 get
1676 { 1673 {
1677 byte pst = PhysicsShapeType; 1674 byte pst = PhysicsShapeType;
1678 if(pst == (byte) PhysShapeType.none || pst == (byte) PhysShapeType.convex || HasMesh()) 1675 if(pst == (byte) PhysShapeType.none || HasMesh())
1679 return true; 1676 return true;
1680 return false; 1677 return false;
1681 } 1678 }
@@ -1730,7 +1727,12 @@ namespace OpenSim.Region.Framework.Scenes
1730 1727
1731 public byte PhysicsShapeType 1728 public byte PhysicsShapeType
1732 { 1729 {
1733 get { return m_physicsShapeType; } 1730 get
1731 {
1732// if (PhysActor != null)
1733// m_physicsShapeType = PhysActor.PhysicsShapeType;
1734 return m_physicsShapeType;
1735 }
1734 set 1736 set
1735 { 1737 {
1736 byte oldv = m_physicsShapeType; 1738 byte oldv = m_physicsShapeType;
@@ -1781,10 +1783,12 @@ namespace OpenSim.Region.Framework.Scenes
1781 { 1783 {
1782 m_density = value; 1784 m_density = value;
1783 1785
1784 ScheduleFullUpdateIfNone();
1785 1786
1786 if (ParentGroup != null) 1787 if (ParentGroup != null)
1788 {
1787 ParentGroup.HasGroupChanged = true; 1789 ParentGroup.HasGroupChanged = true;
1790 ScheduleFullUpdate();
1791 }
1788 1792
1789 PhysicsActor pa = PhysActor; 1793 PhysicsActor pa = PhysActor;
1790 if (pa != null) 1794 if (pa != null)
@@ -1802,10 +1806,11 @@ namespace OpenSim.Region.Framework.Scenes
1802 { 1806 {
1803 m_gravitymod = value; 1807 m_gravitymod = value;
1804 1808
1805 ScheduleFullUpdateIfNone();
1806
1807 if (ParentGroup != null) 1809 if (ParentGroup != null)
1810 {
1808 ParentGroup.HasGroupChanged = true; 1811 ParentGroup.HasGroupChanged = true;
1812 ScheduleFullUpdate();
1813 }
1809 1814
1810 PhysicsActor pa = PhysActor; 1815 PhysicsActor pa = PhysActor;
1811 if (pa != null) 1816 if (pa != null)
@@ -1823,10 +1828,11 @@ namespace OpenSim.Region.Framework.Scenes
1823 { 1828 {
1824 m_friction = value; 1829 m_friction = value;
1825 1830
1826 ScheduleFullUpdateIfNone();
1827
1828 if (ParentGroup != null) 1831 if (ParentGroup != null)
1832 {
1829 ParentGroup.HasGroupChanged = true; 1833 ParentGroup.HasGroupChanged = true;
1834 ScheduleFullUpdate();
1835 }
1830 1836
1831 PhysicsActor pa = PhysActor; 1837 PhysicsActor pa = PhysActor;
1832 if (pa != null) 1838 if (pa != null)
@@ -1844,10 +1850,11 @@ namespace OpenSim.Region.Framework.Scenes
1844 { 1850 {
1845 m_bounce = value; 1851 m_bounce = value;
1846 1852
1847 ScheduleFullUpdateIfNone();
1848
1849 if (ParentGroup != null) 1853 if (ParentGroup != null)
1854 {
1850 ParentGroup.HasGroupChanged = true; 1855 ParentGroup.HasGroupChanged = true;
1856 ScheduleFullUpdate();
1857 }
1851 1858
1852 PhysicsActor pa = PhysActor; 1859 PhysicsActor pa = PhysActor;
1853 if (pa != null) 1860 if (pa != null)
@@ -1876,7 +1883,8 @@ namespace OpenSim.Region.Framework.Scenes
1876 /// </summary> 1883 /// </summary>
1877 public void ClearUpdateSchedule() 1884 public void ClearUpdateSchedule()
1878 { 1885 {
1879 UpdateFlag = UpdateRequired.NONE; 1886 lock(UpdateFlagLock)
1887 UpdateFlag = UpdateRequired.NONE;
1880 } 1888 }
1881 1889
1882 /// <summary> 1890 /// <summary>
@@ -3239,17 +3247,6 @@ namespace OpenSim.Region.Framework.Scenes
3239 APIDActive = false; 3247 APIDActive = false;
3240 } 3248 }
3241 3249
3242 public void ScheduleFullUpdateIfNone()
3243 {
3244 if (ParentGroup == null)
3245 return;
3246
3247// ??? ParentGroup.HasGroupChanged = true;
3248
3249 if (UpdateFlag != UpdateRequired.FULL)
3250 ScheduleFullUpdate();
3251 }
3252
3253 /// <summary> 3250 /// <summary>
3254 /// Schedules this prim for a full update 3251 /// Schedules this prim for a full update
3255 /// </summary> 3252 /// </summary>
@@ -3260,30 +3257,21 @@ namespace OpenSim.Region.Framework.Scenes
3260 if (ParentGroup == null) 3257 if (ParentGroup == null)
3261 return; 3258 return;
3262 3259
3263 ParentGroup.QueueForUpdateCheck(); 3260 lock(UpdateFlagLock)
3264
3265 int timeNow = Util.UnixTimeSinceEpoch();
3266
3267 // If multiple updates are scheduled on the same second, we still need to perform all of them
3268 // So we'll force the issue by bumping up the timestamp so that later processing sees these need
3269 // to be performed.
3270 if (timeNow <= TimeStampFull)
3271 { 3261 {
3272 TimeStampFull += 1; 3262 ParentGroup.QueueForUpdateCheck(); // just in case
3273 } 3263 if(UpdateFlag != UpdateRequired.FULL)
3274 else 3264 {
3275 { 3265 UpdateFlag = UpdateRequired.FULL;
3276 TimeStampFull = (uint)timeNow;
3277 }
3278
3279 UpdateFlag = UpdateRequired.FULL;
3280 3266
3281 // m_log.DebugFormat( 3267 // m_log.DebugFormat(
3282 // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", 3268 // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}",
3283 // UUID, Name, TimeStampFull); 3269 // UUID, Name, TimeStampFull);
3284 3270
3285 if (ParentGroup.Scene != null) 3271 if (ParentGroup.Scene != null)
3286 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true); 3272 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, true);
3273 }
3274 }
3287 } 3275 }
3288 3276
3289 /// <summary> 3277 /// <summary>
@@ -3304,21 +3292,23 @@ namespace OpenSim.Region.Framework.Scenes
3304 return; 3292 return;
3305 } 3293 }
3306 3294
3307 if (UpdateFlag == UpdateRequired.NONE) 3295 lock(UpdateFlagLock)
3308 { 3296 {
3309 ParentGroup.HasGroupChanged = true; 3297 if (UpdateFlag == UpdateRequired.NONE)
3310 ParentGroup.QueueForUpdateCheck(); 3298 {
3299 ParentGroup.HasGroupChanged = true;
3300 ParentGroup.QueueForUpdateCheck();
3311 3301
3312 TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); 3302 UpdateFlag = UpdateRequired.TERSE;
3313 UpdateFlag = UpdateRequired.TERSE;
3314 3303
3315 // m_log.DebugFormat( 3304 // m_log.DebugFormat(
3316 // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", 3305 // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}",
3317 // UUID, Name, TimeStampTerse); 3306 // UUID, Name, TimeStampTerse);
3318 } 3307 }
3319 3308
3320 if (ParentGroup.Scene != null) 3309 if (ParentGroup.Scene != null)
3321 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false); 3310 ParentGroup.Scene.EventManager.TriggerSceneObjectPartUpdated(this, false);
3311 }
3322 } 3312 }
3323 3313
3324 public void ScriptSetPhysicsStatus(bool UsePhysics) 3314 public void ScriptSetPhysicsStatus(bool UsePhysics)
@@ -3362,12 +3352,15 @@ namespace OpenSim.Region.Framework.Scenes
3362 return; 3352 return;
3363 3353
3364 // Update the "last" values 3354 // Update the "last" values
3365 m_lastPosition = AbsolutePosition; 3355 lock(UpdateFlagLock)
3366 m_lastRotation = RotationOffset; 3356 {
3367 m_lastVelocity = Velocity; 3357 m_lastPosition = AbsolutePosition;
3368 m_lastAcceleration = Acceleration; 3358 m_lastRotation = RotationOffset;
3369 m_lastAngularVelocity = AngularVelocity; 3359 m_lastVelocity = Velocity;
3370 m_lastUpdateSentTime = Util.GetTimeStampMS(); 3360 m_lastAcceleration = Acceleration;
3361 m_lastAngularVelocity = AngularVelocity;
3362 m_lastUpdateSentTime = Util.GetTimeStampMS();
3363 }
3371 3364
3372 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 3365 ParentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
3373 { 3366 {
@@ -3381,12 +3374,15 @@ namespace OpenSim.Region.Framework.Scenes
3381 return; 3374 return;
3382 3375
3383 // Update the "last" values 3376 // Update the "last" values
3384 m_lastPosition = AbsolutePosition; 3377 lock(UpdateFlagLock)
3385 m_lastRotation = RotationOffset; 3378 {
3386 m_lastVelocity = Velocity; 3379 m_lastPosition = AbsolutePosition;
3387 m_lastAcceleration = Acceleration; 3380 m_lastRotation = RotationOffset;
3388 m_lastAngularVelocity = AngularVelocity; 3381 m_lastVelocity = Velocity;
3389 m_lastUpdateSentTime = Util.GetTimeStampMS(); 3382 m_lastAcceleration = Acceleration;
3383 m_lastAngularVelocity = AngularVelocity;
3384 m_lastUpdateSentTime = Util.GetTimeStampMS();
3385 }
3390 3386
3391 if (ParentGroup.IsAttachment) 3387 if (ParentGroup.IsAttachment)
3392 { 3388 {
@@ -3442,108 +3438,118 @@ namespace OpenSim.Region.Framework.Scenes
3442 /// Tell all the prims which have had updates scheduled 3438 /// Tell all the prims which have had updates scheduled
3443 /// </summary> 3439 /// </summary>
3444 public void SendScheduledUpdates() 3440 public void SendScheduledUpdates()
3445 { 3441 {
3446 switch (UpdateFlag) 3442 UpdateRequired currentUpdate;
3443 lock(UpdateFlagLock)
3444 {
3445 currentUpdate = UpdateFlag;
3446 ClearUpdateSchedule();
3447 }
3448
3449 switch (currentUpdate)
3447 { 3450 {
3448 case UpdateRequired.NONE: 3451 case UpdateRequired.NONE:
3449 ClearUpdateSchedule();
3450 break; 3452 break;
3451 3453
3452 case UpdateRequired.TERSE: 3454 case UpdateRequired.TERSE:
3453
3454 ClearUpdateSchedule();
3455 bool needupdate = true; 3455 bool needupdate = true;
3456 double now = Util.GetTimeStampMS(); 3456 lock(UpdateFlagLock)
3457 Vector3 curvel = Velocity;
3458 Vector3 curacc = Acceleration;
3459 Vector3 angvel = AngularVelocity;
3460
3461 while(true) // just to avoid ugly goto
3462 { 3457 {
3463 double elapsed = now - m_lastUpdateSentTime; 3458 double now = Util.GetTimeStampMS();
3464 if (elapsed > TIME_MS_TOLERANCE) 3459 Vector3 curvel = Velocity;
3465 break; 3460 Vector3 curacc = Acceleration;
3461 Vector3 angvel = AngularVelocity;
3466 3462
3467 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE || 3463 while(true) // just to avoid ugly goto
3468 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE || 3464 {
3469 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE) 3465 double elapsed = now - m_lastUpdateSentTime;
3470 break; 3466 if (elapsed > TIME_MS_TOLERANCE)
3467 break;
3471 3468
3472 // velocity change is also direction not only norm) 3469 if( Math.Abs(curacc.X - m_lastAcceleration.X) > VELOCITY_TOLERANCE ||
3473 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE || 3470 Math.Abs(curacc.Y - m_lastAcceleration.Y) > VELOCITY_TOLERANCE ||
3474 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE || 3471 Math.Abs(curacc.Z - m_lastAcceleration.Z) > VELOCITY_TOLERANCE)
3475 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE) 3472 break;
3476 break;
3477
3478 float vx = Math.Abs(curvel.X);
3479 if(vx > 128.0)
3480 break;
3481 float vy = Math.Abs(curvel.Y);
3482 if(vy > 128.0)
3483 break;
3484 float vz = Math.Abs(curvel.Z);
3485 if(vz > 128.0)
3486 break;
3487 3473
3488 if ( 3474 // velocity change is also direction not only norm)
3489 vx < VELOCITY_TOLERANCE && 3475 if( Math.Abs(curvel.X - m_lastVelocity.X) > VELOCITY_TOLERANCE ||
3490 vy < VELOCITY_TOLERANCE && 3476 Math.Abs(curvel.Y - m_lastVelocity.Y) > VELOCITY_TOLERANCE ||
3491 vz < VELOCITY_TOLERANCE 3477 Math.Abs(curvel.Z - m_lastVelocity.Z) > VELOCITY_TOLERANCE)
3492 )
3493 {
3494 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
3495 break; 3478 break;
3479
3480 float vx = Math.Abs(curvel.X);
3481 if(vx > 128.0)
3482 break;
3483 float vy = Math.Abs(curvel.Y);
3484 if(vy > 128.0)
3485 break;
3486 float vz = Math.Abs(curvel.Z);
3487 if(vz > 128.0)
3488 break;
3489
3490 if (
3491 vx < VELOCITY_TOLERANCE &&
3492 vy < VELOCITY_TOLERANCE &&
3493 vz < VELOCITY_TOLERANCE
3494 )
3495 {
3496 if(!AbsolutePosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
3497 break;
3496 3498
3497 if (vx < 1e-4 && 3499 if (vx < 1e-4 &&
3498 vy < 1e-4 && 3500 vy < 1e-4 &&
3499 vz < 1e-4 && 3501 vz < 1e-4 &&
3500 ( 3502 (
3501 Math.Abs(m_lastVelocity.X) > 1e-4 || 3503 Math.Abs(m_lastVelocity.X) > 1e-4 ||
3502 Math.Abs(m_lastVelocity.Y) > 1e-4 || 3504 Math.Abs(m_lastVelocity.Y) > 1e-4 ||
3503 Math.Abs(m_lastVelocity.Z) > 1e-4 3505 Math.Abs(m_lastVelocity.Z) > 1e-4
3504 )) 3506 ))
3507 break;
3508 }
3509
3510 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > VELOCITY_TOLERANCE ||
3511 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > VELOCITY_TOLERANCE ||
3512 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > VELOCITY_TOLERANCE)
3505 break; 3513 break;
3506 }
3507 3514
3508 if( Math.Abs(angvel.X - m_lastAngularVelocity.X) > VELOCITY_TOLERANCE || 3515 // viewer interpolators have a limit of 128m/s
3509 Math.Abs(angvel.Y - m_lastAngularVelocity.Y) > VELOCITY_TOLERANCE || 3516 float ax = Math.Abs(angvel.X);
3510 Math.Abs(angvel.Z - m_lastAngularVelocity.Z) > VELOCITY_TOLERANCE) 3517 if(ax > 64.0)
3511 break; 3518 break;
3519 float ay = Math.Abs(angvel.Y);
3520 if(ay > 64.0)
3521 break;
3522 float az = Math.Abs(angvel.Z);
3523 if(az > 64.0)
3524 break;
3512 3525
3513 // viewer interpolators have a limit of 128m/s 3526 if (
3514 float ax = Math.Abs(angvel.X); 3527 ax < VELOCITY_TOLERANCE &&
3515 if(ax > 64.0) 3528 ay < VELOCITY_TOLERANCE &&
3516 break; 3529 az < VELOCITY_TOLERANCE &&
3517 float ay = Math.Abs(angvel.Y); 3530 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3518 if(ay > 64.0) 3531 )
3519 break; 3532 break;
3520 float az = Math.Abs(angvel.Z); 3533
3521 if(az > 64.0) 3534 needupdate = false;
3522 break; 3535 break;
3536 }
3523 3537
3524 if ( 3538 if(needupdate)
3525 ax < VELOCITY_TOLERANCE && 3539 {
3526 ay < VELOCITY_TOLERANCE &&
3527 az < VELOCITY_TOLERANCE &&
3528 !RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
3529 )
3530 break;
3531 3540
3532 needupdate = false; 3541 // Update the "last" values
3533 break; 3542 m_lastPosition = AbsolutePosition;
3543 m_lastRotation = RotationOffset;
3544 m_lastVelocity = curvel;
3545 m_lastAcceleration = curacc;
3546 m_lastAngularVelocity = angvel;
3547 m_lastUpdateSentTime = now;
3548 }
3534 } 3549 }
3535 3550
3536 if(needupdate) 3551 if(needupdate)
3537 { 3552 {
3538
3539 // Update the "last" values
3540 m_lastPosition = AbsolutePosition;
3541 m_lastRotation = RotationOffset;
3542 m_lastVelocity = curvel;
3543 m_lastAcceleration = curacc;
3544 m_lastAngularVelocity = angvel;
3545 m_lastUpdateSentTime = now;
3546
3547 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3553 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3548 { 3554 {
3549 SendTerseUpdateToClient(client); 3555 SendTerseUpdateToClient(client);
@@ -3552,7 +3558,6 @@ namespace OpenSim.Region.Framework.Scenes
3552 break; 3558 break;
3553 3559
3554 case UpdateRequired.FULL: 3560 case UpdateRequired.FULL:
3555 ClearUpdateSchedule();
3556 SendFullUpdateToAllClientsInternal(); 3561 SendFullUpdateToAllClientsInternal();
3557 break; 3562 break;
3558 } 3563 }
@@ -3567,15 +3572,19 @@ namespace OpenSim.Region.Framework.Scenes
3567 if (ParentGroup == null || ParentGroup.Scene == null) 3572 if (ParentGroup == null || ParentGroup.Scene == null)
3568 return; 3573 return;
3569 3574
3570 ClearUpdateSchedule(); 3575 lock(UpdateFlagLock)
3576 {
3577 if(UpdateFlag != UpdateRequired.NONE)
3578 return;
3571 3579
3572 // Update the "last" values 3580 // Update the "last" values
3573 m_lastPosition = AbsolutePosition; 3581 m_lastPosition = AbsolutePosition;
3574 m_lastRotation = RotationOffset; 3582 m_lastRotation = RotationOffset;
3575 m_lastVelocity = Velocity; 3583 m_lastVelocity = Velocity;
3576 m_lastAcceleration = Acceleration; 3584 m_lastAcceleration = Acceleration;
3577 m_lastAngularVelocity = AngularVelocity; 3585 m_lastAngularVelocity = AngularVelocity;
3578 m_lastUpdateSentTime = Util.GetTimeStampMS(); 3586 m_lastUpdateSentTime = Util.GetTimeStampMS();
3587 }
3579 3588
3580 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) 3589 ParentGroup.Scene.ForEachClient(delegate(IClientAPI client)
3581 { 3590 {
@@ -3588,15 +3597,19 @@ namespace OpenSim.Region.Framework.Scenes
3588 if (ParentGroup == null || ParentGroup.Scene == null) 3597 if (ParentGroup == null || ParentGroup.Scene == null)
3589 return; 3598 return;
3590 3599
3591 ClearUpdateSchedule(); 3600 lock(UpdateFlagLock)
3601 {
3602 if(UpdateFlag != UpdateRequired.NONE)
3603 return;
3592 3604
3593 // Update the "last" values 3605 // Update the "last" values
3594 m_lastPosition = AbsolutePosition; 3606 m_lastPosition = AbsolutePosition;
3595 m_lastRotation = RotationOffset; 3607 m_lastRotation = RotationOffset;
3596 m_lastVelocity = Velocity; 3608 m_lastVelocity = Velocity;
3597 m_lastAcceleration = Acceleration; 3609 m_lastAcceleration = Acceleration;
3598 m_lastAngularVelocity = AngularVelocity; 3610 m_lastAngularVelocity = AngularVelocity;
3599 m_lastUpdateSentTime = Util.GetTimeStampMS(); 3611 m_lastUpdateSentTime = Util.GetTimeStampMS();
3612 }
3600 3613
3601 if (ParentGroup.IsAttachment) 3614 if (ParentGroup.IsAttachment)
3602 { 3615 {
diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
index 47edeb9..3666c3f 100644
--- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
+++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs
@@ -844,9 +844,14 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule
844 module.BuyObject(remoteClient, categoryID, localID, saleType, salePrice); 844 module.BuyObject(remoteClient, categoryID, localID, saleType, salePrice);
845 } 845 }
846 846
847 public void MoveMoney(UUID fromAgentID, UUID toAgentID, int amount, string text) 847 public void MoveMoney(UUID fromUser, UUID toUser, int amount, string text)
848 { 848 {
849 } 849 }
850
851 public bool MoveMoney(UUID fromUser, UUID toUser, int amount, MoneyTransactionType type, string text)
852 {
853 return true;
854 }
850 } 855 }
851 856
852 public enum TransactionType : int 857 public enum TransactionType : int
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
index 42fc11b..f72ad28 100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
@@ -141,14 +141,30 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
141 } 141 }
142 142
143 // The passed position is relative to the base of the region. 143 // The passed position is relative to the base of the region.
144 // There are many assumptions herein that the heightmap increment is 1.
144 public override float GetTerrainHeightAtXYZ(Vector3 pos) 145 public override float GetTerrainHeightAtXYZ(Vector3 pos)
145 { 146 {
146 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; 147 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
147 148
148 int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; 149 try {
149 try 150 int baseX = (int)pos.X;
150 { 151 int baseY = (int)pos.Y;
151 ret = m_mapInfo.heightMap[mapIndex]; 152 int maxX = (int)m_mapInfo.sizeX;
153 int maxY = (int)m_mapInfo.sizeY;
154 float diffX = pos.X - (float)baseX;
155 float diffY = pos.Y - (float)baseY;
156
157 float mapHeight1 = m_mapInfo.heightMap[baseY * maxY + baseX];
158 float mapHeight2 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + baseX];
159 float mapHeight3 = m_mapInfo.heightMap[baseY * maxY + Math.Min(baseX + 1, maxX - 1)];
160 float mapHeight4 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + Math.Min(baseX + 1, maxX - 1)];
161
162 float Xrise = (mapHeight4 - mapHeight3) * diffX;
163 float Yrise = (mapHeight2 - mapHeight1) * diffY;
164
165 ret = mapHeight1 + ((Xrise + Yrise) / 2f);
166 // m_physicsScene.DetailLog("{0},BSTerrainHeightMap,GetTerrainHeightAtXYZ,pos={1},{2}/{3}/{4}/{5},ret={6}",
167 // BSScene.DetailLogZero, pos, mapHeight1, mapHeight2, mapHeight3, mapHeight4, ret);
152 } 168 }
153 catch 169 catch
154 { 170 {
diff --git a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
index 4f95554..0d4b6b9 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Region.PhysicsModule.Meshing
66 66
67 private bool cacheSculptMaps = true; 67 private bool cacheSculptMaps = true;
68 private string decodedSculptMapPath = null; 68 private string decodedSculptMapPath = null;
69 private bool useMeshiesPhysicsMesh = false; 69 private bool useMeshiesPhysicsMesh = true;
70 70
71 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 71 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
72 72
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs
index dc87a78..5465035 100644
--- a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs
@@ -62,6 +62,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
62 public byte shapetype; 62 public byte shapetype;
63 public bool hasOBB; 63 public bool hasOBB;
64 public bool hasMeshVolume; 64 public bool hasMeshVolume;
65 public bool isTooSmall;
65 public MeshState meshState; 66 public MeshState meshState;
66 public UUID? assetID; 67 public UUID? assetID;
67 public meshWorkerCmnds comand; 68 public meshWorkerCmnds comand;
@@ -69,16 +70,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde
69 70
70 public class ODEMeshWorker 71 public class ODEMeshWorker
71 { 72 {
72
73 private ILog m_log; 73 private ILog m_log;
74 private ODEScene m_scene; 74 private ODEScene m_scene;
75 private IMesher m_mesher; 75 private IMesher m_mesher;
76 76
77 public bool meshSculptedPrim = true; 77 public bool meshSculptedPrim = true;
78 public bool forceSimplePrimMeshing = false;
79 public float meshSculptLOD = 32; 78 public float meshSculptLOD = 32;
80 public float MeshSculptphysicalLOD = 32; 79 public float MeshSculptphysicalLOD = 32;
81 80 public float MinSizeToMeshmerize = 0.1f;
82 81
83 private OpenSim.Framework.BlockingQueue<ODEPhysRepData> workQueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>(); 82 private OpenSim.Framework.BlockingQueue<ODEPhysRepData> workQueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>();
84 private bool m_running; 83 private bool m_running;
@@ -93,9 +92,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
93 92
94 if (pConfig != null) 93 if (pConfig != null)
95 { 94 {
96 forceSimplePrimMeshing = pConfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
97 meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim); 95 meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
98 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD); 96 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
97 MinSizeToMeshmerize = pConfig.GetFloat("mesh_min_size", MinSizeToMeshmerize);
99 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD); 98 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
100 } 99 }
101 m_running = true; 100 m_running = true;
@@ -288,6 +287,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
288 { 287 {
289 PrimitiveBaseShape pbs = repData.pbs; 288 PrimitiveBaseShape pbs = repData.pbs;
290 // check sculpts or meshs 289 // check sculpts or meshs
290
291 Vector3 scale = pbs.Scale;
292 if(scale.X <= MinSizeToMeshmerize &&
293 scale.Y <= MinSizeToMeshmerize &&
294 scale.Z <= MinSizeToMeshmerize)
295 {
296 repData.isTooSmall = true;
297 return false;
298 }
299
291 if (pbs.SculptEntry) 300 if (pbs.SculptEntry)
292 { 301 {
293 if (meshSculptedPrim) 302 if (meshSculptedPrim)
@@ -299,9 +308,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
299 return false; 308 return false;
300 } 309 }
301 310
302 if (forceSimplePrimMeshing)
303 return true;
304
305 // convex shapes have no holes 311 // convex shapes have no holes
306 ushort profilehollow = pbs.ProfileHollow; 312 ushort profilehollow = pbs.ProfileHollow;
307 if(repData.shapetype == 2) 313 if(repData.shapetype == 2)
@@ -425,17 +431,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
425 Vector3 size = repData.size; 431 Vector3 size = repData.size;
426 432
427 int clod = (int)LevelOfDetail.High; 433 int clod = (int)LevelOfDetail.High;
428 bool convex;
429 byte shapetype = repData.shapetype; 434 byte shapetype = repData.shapetype;
430 if (shapetype == 0) 435 bool convex = shapetype == 2;
431 convex = false;
432 else
433 {
434 convex = true;
435 // sculpts pseudo convex
436 if (pbs.SculptEntry && pbs.SculptType != (byte)SculptType.Mesh)
437 clod = (int)LevelOfDetail.Low;
438 }
439 436
440 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); 437 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
441 438
@@ -563,10 +560,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
563 560
564 private void CalculateBasicPrimVolume(ODEPhysRepData repData) 561 private void CalculateBasicPrimVolume(ODEPhysRepData repData)
565 { 562 {
566 PrimitiveBaseShape _pbs = repData.pbs;
567 Vector3 _size = repData.size; 563 Vector3 _size = repData.size;
568 564
569 float volume = _size.X * _size.Y * _size.Z; // default 565 float volume = _size.X * _size.Y * _size.Z; // default
566 if(repData.isTooSmall)
567 {
568 repData.volume = volume;
569 return;
570 }
571
572 PrimitiveBaseShape _pbs = repData.pbs;
570 float tmp; 573 float tmp;
571 574
572 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; 575 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs
index 76ef88b..aa208e2 100644
--- a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs
@@ -1733,7 +1733,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
1733 return true; 1733 return true;
1734 } 1734 }
1735 1735
1736 private void CreateGeom() 1736 private void CreateGeom(bool OverrideToBox)
1737 { 1737 {
1738 bool hasMesh = false; 1738 bool hasMesh = false;
1739 1739
@@ -1742,7 +1742,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
1742 if ((m_meshState & MeshState.MeshNoColide) != 0) 1742 if ((m_meshState & MeshState.MeshNoColide) != 0)
1743 m_NoColide = true; 1743 m_NoColide = true;
1744 1744
1745 else if(m_mesh != null) 1745 else if(!OverrideToBox && m_mesh != null)
1746 { 1746 {
1747 if (GetMeshGeom()) 1747 if (GetMeshGeom())
1748 hasMesh = true; 1748 hasMesh = true;
@@ -3180,7 +3180,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
3180 3180
3181 primVolume = repData.volume; 3181 primVolume = repData.volume;
3182 3182
3183 CreateGeom(); 3183 CreateGeom(repData.isTooSmall);
3184 3184
3185 if (prim_geom != IntPtr.Zero) 3185 if (prim_geom != IntPtr.Zero)
3186 { 3186 {
@@ -3256,7 +3256,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
3256 3256
3257 primVolume = repData.volume; 3257 primVolume = repData.volume;
3258 3258
3259 CreateGeom(); 3259 CreateGeom(repData.isTooSmall);
3260 3260
3261 if (prim_geom != IntPtr.Zero) 3261 if (prim_geom != IntPtr.Zero)
3262 { 3262 {
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
index 0117800..a2a3f79 100644
--- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
@@ -36,15 +36,13 @@ using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData; 37using OpenMetaverse.StructuredData;
38using System.Drawing; 38using System.Drawing;
39using System.Drawing.Imaging; 39using System.Threading;
40using System.IO.Compression; 40using System.IO.Compression;
41using PrimMesher; 41using PrimMesher;
42using log4net; 42using log4net;
43using Nini.Config; 43using Nini.Config;
44using System.Reflection; 44using System.Reflection;
45using System.IO; 45using System.IO;
46using System.Runtime.Serialization;
47using System.Runtime.Serialization.Formatters.Binary;
48 46
49using Mono.Addins; 47using Mono.Addins;
50 48
@@ -58,22 +56,22 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
58 // Setting baseDir to a path will enable the dumping of raw files 56 // Setting baseDir to a path will enable the dumping of raw files
59 // raw files can be imported by blender so a visual inspection of the results can be done 57 // raw files can be imported by blender so a visual inspection of the results can be done
60 58
59 private static string cacheControlFilename = "cntr";
61 private bool m_Enabled = false; 60 private bool m_Enabled = false;
62 61
63 public static object diskLock = new object(); 62 public static object diskLock = new object();
64 63
65 public bool doMeshFileCache = true; 64 public bool doMeshFileCache = true;
66 65 public bool doCacheExpire = true;
67 public string cachePath = "MeshCache"; 66 public string cachePath = "MeshCache";
68 public TimeSpan CacheExpire; 67 public TimeSpan CacheExpire;
69 public bool doCacheExpire = true;
70 68
71// const string baseDir = "rawFiles"; 69// const string baseDir = "rawFiles";
72 private const string baseDir = null; //"rawFiles"; 70 private const string baseDir = null; //"rawFiles";
73 71
74 private bool useMeshiesPhysicsMesh = false; 72 private bool useMeshiesPhysicsMesh = true;
75 73 private bool doConvexPrims = true;
76 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 74 private bool doConvexSculpts = true;
77 75
78 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>(); 76 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>();
79 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>(); 77 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>();
@@ -103,40 +101,31 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
103 if (mesh_config != null) 101 if (mesh_config != null)
104 { 102 {
105 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); 103 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
106 if (useMeshiesPhysicsMesh) 104 doConvexPrims = mesh_config.GetBoolean("ConvexPrims",doConvexPrims);
107 { 105 doConvexSculpts = mesh_config.GetBoolean("ConvexSculpts",doConvexPrims);
108 doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache); 106 doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache);
109 cachePath = mesh_config.GetString("MeshFileCachePath", cachePath); 107 cachePath = mesh_config.GetString("MeshFileCachePath", cachePath);
110 fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache); 108 fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache);
111 doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire); 109 doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire);
112 }
113 else
114 {
115 doMeshFileCache = false;
116 doCacheExpire = false;
117 }
118 110
119 m_Enabled = true; 111 m_Enabled = true;
120 } 112 }
121 113
122 CacheExpire = TimeSpan.FromHours(fcache); 114 CacheExpire = TimeSpan.FromHours(fcache);
123 115
124 lock (diskLock) 116 if(String.IsNullOrEmpty(cachePath))
117 doMeshFileCache = false;
118
119 if(doMeshFileCache)
125 { 120 {
126 if(doMeshFileCache && cachePath != "") 121 if(!checkCache())
127 { 122 {
128 try 123 doMeshFileCache = false;
129 { 124 doCacheExpire = false;
130 if (!Directory.Exists(cachePath))
131 Directory.CreateDirectory(cachePath);
132 }
133 catch
134 {
135 doMeshFileCache = false;
136 doCacheExpire = false;
137 }
138 } 125 }
139 } 126 }
127 else
128 doCacheExpire = false;
140 } 129 }
141 } 130 }
142 131
@@ -168,87 +157,6 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
168 157
169 #endregion 158 #endregion
170 159
171 /// <summary>
172 /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
173 /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail
174 /// for some reason
175 /// </summary>
176 /// <param name="minX"></param>
177 /// <param name="maxX"></param>
178 /// <param name="minY"></param>
179 /// <param name="maxY"></param>
180 /// <param name="minZ"></param>
181 /// <param name="maxZ"></param>
182 /// <returns></returns>
183 private static Mesh CreateSimpleBoxMesh(float minX, float maxX, float minY, float maxY, float minZ, float maxZ)
184 {
185 Mesh box = new Mesh(true);
186 List<Vertex> vertices = new List<Vertex>();
187 // bottom
188
189 vertices.Add(new Vertex(minX, maxY, minZ));
190 vertices.Add(new Vertex(maxX, maxY, minZ));
191 vertices.Add(new Vertex(maxX, minY, minZ));
192 vertices.Add(new Vertex(minX, minY, minZ));
193
194 box.Add(new Triangle(vertices[0], vertices[1], vertices[2]));
195 box.Add(new Triangle(vertices[0], vertices[2], vertices[3]));
196
197 // top
198
199 vertices.Add(new Vertex(maxX, maxY, maxZ));
200 vertices.Add(new Vertex(minX, maxY, maxZ));
201 vertices.Add(new Vertex(minX, minY, maxZ));
202 vertices.Add(new Vertex(maxX, minY, maxZ));
203
204 box.Add(new Triangle(vertices[4], vertices[5], vertices[6]));
205 box.Add(new Triangle(vertices[4], vertices[6], vertices[7]));
206
207 // sides
208
209 box.Add(new Triangle(vertices[5], vertices[0], vertices[3]));
210 box.Add(new Triangle(vertices[5], vertices[3], vertices[6]));
211
212 box.Add(new Triangle(vertices[1], vertices[0], vertices[5]));
213 box.Add(new Triangle(vertices[1], vertices[5], vertices[4]));
214
215 box.Add(new Triangle(vertices[7], vertices[1], vertices[4]));
216 box.Add(new Triangle(vertices[7], vertices[2], vertices[1]));
217
218 box.Add(new Triangle(vertices[3], vertices[2], vertices[7]));
219 box.Add(new Triangle(vertices[3], vertices[7], vertices[6]));
220
221 return box;
222 }
223
224 /// <summary>
225 /// Creates a simple bounding box mesh for a complex input mesh
226 /// </summary>
227 /// <param name="meshIn"></param>
228 /// <returns></returns>
229 private static Mesh CreateBoundingBoxMesh(Mesh meshIn)
230 {
231 float minX = float.MaxValue;
232 float maxX = float.MinValue;
233 float minY = float.MaxValue;
234 float maxY = float.MinValue;
235 float minZ = float.MaxValue;
236 float maxZ = float.MinValue;
237
238 foreach (Vector3 v in meshIn.getVertexList())
239 {
240 if (v.X < minX) minX = v.X;
241 if (v.Y < minY) minY = v.Y;
242 if (v.Z < minZ) minZ = v.Z;
243
244 if (v.X > maxX) maxX = v.X;
245 if (v.Y > maxY) maxY = v.Y;
246 if (v.Z > maxZ) maxZ = v.Z;
247 }
248
249 return CreateSimpleBoxMesh(minX, maxX, minY, maxY, minZ, maxZ);
250 }
251
252 private void ReportPrimError(string message, string primName, PrimMesh primMesh) 160 private void ReportPrimError(string message, string primName, PrimMesh primMesh)
253 { 161 {
254 m_log.Error(message); 162 m_log.Error(message);
@@ -265,7 +173,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
265 /// <param name="faces"></param> 173 /// <param name="faces"></param>
266 private void AddSubMesh(OSDMap subMeshData, List<Coord> coords, List<Face> faces) 174 private void AddSubMesh(OSDMap subMeshData, List<Coord> coords, List<Face> faces)
267 { 175 {
268 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap)); 176 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap));
269 177
270 // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level 178 // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level
271 // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no 179 // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no
@@ -330,6 +238,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
330 238
331 List<Coord> coords; 239 List<Coord> coords;
332 List<Face> faces; 240 List<Face> faces;
241 bool needsConvexProcessing = convex;
333 242
334 if (primShape.SculptEntry) 243 if (primShape.SculptEntry)
335 { 244 {
@@ -340,23 +249,49 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
340 249
341 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex)) 250 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex))
342 return null; 251 return null;
252 needsConvexProcessing = false;
343 } 253 }
344 else 254 else
345 { 255 {
346 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces)) 256 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces))
347 return null; 257 return null;
258 needsConvexProcessing &= doConvexSculpts;
348 } 259 }
349 } 260 }
350 else 261 else
351 { 262 {
352 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces)) 263 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces))
353 return null; 264 return null;
265 needsConvexProcessing &= doConvexPrims;
354 } 266 }
355 267
356
357 int numCoords = coords.Count; 268 int numCoords = coords.Count;
358 int numFaces = faces.Count; 269 int numFaces = faces.Count;
359 270
271 if(numCoords < 3 || (!needsConvexProcessing && numFaces < 1))
272 {
273 m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName);
274 return null;
275 }
276
277 if(needsConvexProcessing)
278 {
279 List<Coord> convexcoords;
280 List<Face> convexfaces;
281 if(CreateBoundingHull(coords, out convexcoords, out convexfaces) && convexcoords != null && convexfaces != null)
282 {
283 coords.Clear();
284 coords = convexcoords;
285 numCoords = coords.Count;
286
287 faces.Clear();
288 faces = convexfaces;
289 numFaces = faces.Count;
290 }
291 else
292 m_log.ErrorFormat("[ubMESH]: failed to create convex for {0} using normal mesh", primName);
293 }
294
360 Mesh mesh = new Mesh(true); 295 Mesh mesh = new Mesh(true);
361 // Add the corresponding triangles to the mesh 296 // Add the corresponding triangles to the mesh
362 for (int i = 0; i < numFaces; i++) 297 for (int i = 0; i < numFaces; i++)
@@ -371,10 +306,10 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
371 faces.Clear(); 306 faces.Clear();
372 307
373 if(mesh.numberVertices() < 3 || mesh.numberTriangles() < 1) 308 if(mesh.numberVertices() < 3 || mesh.numberTriangles() < 1)
374 { 309 {
375 m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim " + primName + " ignored"); 310 m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName);
376 return null; 311 return null;
377 } 312 }
378 313
379 primShape.SculptData = Utils.EmptyBytes; 314 primShape.SculptData = Utils.EmptyBytes;
380 315
@@ -625,45 +560,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
625 vs.Clear(); 560 vs.Clear();
626 continue; 561 continue;
627 } 562 }
628 /*
629 if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
630 {
631 vs.Clear();
632 continue;
633 }
634 563
635 nverts = hullr.Vertices.Count;
636 nindexs = hullr.Indices.Count;
637
638 if (nindexs % 3 != 0)
639 {
640 vs.Clear();
641 continue;
642 }
643
644 for (i = 0; i < nverts; i++)
645 {
646 c.X = hullr.Vertices[i].x;
647 c.Y = hullr.Vertices[i].y;
648 c.Z = hullr.Vertices[i].z;
649 coords.Add(c);
650 }
651
652 for (i = 0; i < nindexs; i += 3)
653 {
654 t1 = hullr.Indices[i];
655 if (t1 > nverts)
656 break;
657 t2 = hullr.Indices[i + 1];
658 if (t2 > nverts)
659 break;
660 t3 = hullr.Indices[i + 2];
661 if (t3 > nverts)
662 break;
663 f = new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3);
664 faces.Add(f);
665 }
666 */
667 List<int> indices; 564 List<int> indices;
668 if (!HullUtils.ComputeHull(vs, out indices)) 565 if (!HullUtils.ComputeHull(vs, out indices))
669 { 566 {
@@ -769,38 +666,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
769 vs.Clear(); 666 vs.Clear();
770 return true; 667 return true;
771 } 668 }
772/*
773 if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
774 return false;
775
776 nverts = hullr.Vertices.Count;
777 nindexs = hullr.Indices.Count;
778
779 if (nindexs % 3 != 0)
780 return false;
781 669
782 for (i = 0; i < nverts; i++)
783 {
784 c.X = hullr.Vertices[i].x;
785 c.Y = hullr.Vertices[i].y;
786 c.Z = hullr.Vertices[i].z;
787 coords.Add(c);
788 }
789 for (i = 0; i < nindexs; i += 3)
790 {
791 t1 = hullr.Indices[i];
792 if (t1 > nverts)
793 break;
794 t2 = hullr.Indices[i + 1];
795 if (t2 > nverts)
796 break;
797 t3 = hullr.Indices[i + 2];
798 if (t3 > nverts)
799 break;
800 f = new Face(t1, t2, t3);
801 faces.Add(f);
802 }
803*/
804 List<int> indices; 670 List<int> indices;
805 if (!HullUtils.ComputeHull(vs, out indices)) 671 if (!HullUtils.ComputeHull(vs, out indices))
806 return false; 672 return false;
@@ -1413,7 +1279,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1413 } 1279 }
1414 } 1280 }
1415 1281
1416 public void FileNames(AMeshKey key, out string dir,out string fullFileName) 1282 public void FileNames(AMeshKey key, out string dir, out string fullFileName)
1417 { 1283 {
1418 string id = key.ToString(); 1284 string id = key.ToString();
1419 string init = id.Substring(0, 1); 1285 string init = id.Substring(0, 1);
@@ -1530,7 +1396,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1530 if (!doCacheExpire) 1396 if (!doCacheExpire)
1531 return; 1397 return;
1532 1398
1533 string controlfile = System.IO.Path.Combine(cachePath, "cntr"); 1399 string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename);
1534 1400
1535 lock (diskLock) 1401 lock (diskLock)
1536 { 1402 {
@@ -1583,5 +1449,153 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1583 catch { } 1449 catch { }
1584 } 1450 }
1585 } 1451 }
1452
1453 public bool checkCache()
1454 {
1455 string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename);
1456 lock (diskLock)
1457 {
1458 try
1459 {
1460 if (!Directory.Exists(cachePath))
1461 {
1462 Directory.CreateDirectory(cachePath);
1463 Thread.Sleep(100);
1464 FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough);
1465 fs.Close();
1466 return true;
1467 }
1468 }
1469 catch
1470 {
1471 doMeshFileCache = false;
1472 doCacheExpire = false;
1473 return false;
1474 }
1475 finally {}
1476
1477 if (File.Exists(controlfile))
1478 return true;
1479
1480 try
1481 {
1482 Directory.Delete(cachePath, true);
1483 while(Directory.Exists(cachePath))
1484 Thread.Sleep(100);
1485 }
1486 catch(Exception e)
1487 {
1488 m_log.Error("[MESH CACHE]: failed to delete old version of the cache: " + e.Message);
1489 doMeshFileCache = false;
1490 doCacheExpire = false;
1491 return false;
1492 }
1493 finally {}
1494 try
1495 {
1496 Directory.CreateDirectory(cachePath);
1497 while(!Directory.Exists(cachePath))
1498 Thread.Sleep(100);
1499 }
1500 catch(Exception e)
1501 {
1502 m_log.Error("[MESH CACHE]: failed to create new cache folder: " + e.Message);
1503 doMeshFileCache = false;
1504 doCacheExpire = false;
1505 return false;
1506 }
1507 finally {}
1508
1509 try
1510 {
1511 FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough);
1512 fs.Close();
1513 }
1514 catch(Exception e)
1515 {
1516 m_log.Error("[MESH CACHE]: failed to create new control file: " + e.Message);
1517 doMeshFileCache = false;
1518 doCacheExpire = false;
1519 return false;
1520 }
1521 finally {}
1522
1523 return true;
1524 }
1525 }
1526
1527 public bool CreateBoundingHull(List<Coord> inputVertices, out List<Coord> convexcoords, out List<Face> newfaces)
1528 {
1529 convexcoords = null;
1530 newfaces = null;
1531 HullDesc desc = new HullDesc();
1532 HullResult result = new HullResult();
1533
1534 int nInputVerts = inputVertices.Count;
1535 int i;
1536
1537 List<float3> vs = new List<float3>(nInputVerts);
1538 float3 f3;
1539
1540 //useless copy
1541 for(i = 0 ; i < nInputVerts; i++)
1542 {
1543 f3 = new float3(inputVertices[i].X, inputVertices[i].Y, inputVertices[i].Z);
1544 vs.Add(f3);
1545 }
1546
1547 desc.Vertices = vs;
1548 desc.Flags = HullFlag.QF_TRIANGLES;
1549 desc.MaxVertices = 256;
1550
1551 try
1552 {
1553 HullError ret = HullUtils.CreateConvexHull(desc, ref result);
1554 if (ret != HullError.QE_OK)
1555 return false;
1556 int nverts = result.OutputVertices.Count;
1557 int nindx = result.Indices.Count;
1558 if(nverts < 3 || nindx< 3)
1559 return false;
1560 if(nindx % 3 != 0)
1561 return false;
1562
1563 convexcoords = new List<Coord>(nverts);
1564 Coord c;
1565 vs = result.OutputVertices;
1566
1567 for(i = 0 ; i < nverts; i++)
1568 {
1569 c = new Coord(vs[i].x, vs[i].y, vs[i].z);
1570 convexcoords.Add(c);
1571 }
1572
1573 newfaces = new List<Face>(nindx / 3);
1574 List<int> indxs = result.Indices;
1575 int k, l, m;
1576 Face f;
1577 for(i = 0 ; i < nindx;)
1578 {
1579 k = indxs[i++];
1580 l = indxs[i++];
1581 m = indxs[i++];
1582 if(k > nInputVerts)
1583 continue;
1584 if(l > nInputVerts)
1585 continue;
1586 if(m > nInputVerts)
1587 continue;
1588 f = new Face(k,l,m);
1589 newfaces.Add(f);
1590 }
1591 return true;
1592 }
1593 catch
1594 {
1595
1596 return false;
1597 }
1598 return false;
1599 }
1586 } 1600 }
1587} 1601}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index c13e8b2..75b6b0e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7851,7 +7851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7851 UUID key; 7851 UUID key;
7852 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 7852 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7853 7853
7854 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false)) 7854 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false))
7855 { 7855 {
7856 int expires = 0; 7856 int expires = 0;
7857 if (hours != 0) 7857 if (hours != 0)
@@ -13073,7 +13073,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13073 m_host.AddScriptLPS(1); 13073 m_host.AddScriptLPS(1);
13074 UUID key; 13074 UUID key;
13075 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 13075 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
13076 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed, false)) 13076 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManagePasses, false))
13077 { 13077 {
13078 if (UUID.TryParse(avatar, out key)) 13078 if (UUID.TryParse(avatar, out key))
13079 { 13079 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 8780e49..a65f71f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -525,7 +525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
525 } 525 }
526 526
527 [Serializable] 527 [Serializable]
528 public class list: MarshalByRefObject 528 public class list
529 { 529 {
530 private object[] m_data; 530 private object[] m_data;
531 531
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs
index 8e3cf0e..5c6abd2 100644
--- a/OpenSim/Services/HypergridService/GatekeeperService.cs
+++ b/OpenSim/Services/HypergridService/GatekeeperService.cs
@@ -395,9 +395,10 @@ namespace OpenSim.Services.HypergridService
395 { 395 {
396 if(SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo)) 396 if(SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo))
397 { 397 {
398 m_log.InfoFormat( 398 if(account != null)
399 "[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in", 399 m_log.InfoFormat(
400 account.FirstName, account.LastName); 400 "[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in",
401 account.FirstName, account.LastName);
401 reason = "You appear to be already logged in on the destination grid " + 402 reason = "You appear to be already logged in on the destination grid " +
402 "Please wait a a minute or two and retry. " + 403 "Please wait a a minute or two and retry. " +
403 "If this takes longer than a few minutes please contact the grid owner."; 404 "If this takes longer than a few minutes please contact the grid owner.";
diff --git a/OpenSim/Tests/Permissions/DirectTransferTests.cs b/OpenSim/Tests/Permissions/DirectTransferTests.cs
index c68bbdf..0f251db 100644
--- a/OpenSim/Tests/Permissions/DirectTransferTests.cs
+++ b/OpenSim/Tests/Permissions/DirectTransferTests.cs
@@ -44,6 +44,13 @@ namespace OpenSim.Tests.Permissions
44 [SetUp] 44 [SetUp]
45 public void SetUp() 45 public void SetUp()
46 { 46 {
47 // In case we're dealing with some older version of nunit
48 if (Common.TheInstance == null)
49 {
50 Common.TheInstance = new Common();
51 Common.TheInstance.SetUp();
52 }
53
47 Common.TheInstance.DeleteObjectsFolders(); 54 Common.TheInstance.DeleteObjectsFolders();
48 } 55 }
49 56
diff --git a/OpenSim/Tests/Permissions/IndirectTransferTests.cs b/OpenSim/Tests/Permissions/IndirectTransferTests.cs
index 7d8027f..fb96b8b 100644
--- a/OpenSim/Tests/Permissions/IndirectTransferTests.cs
+++ b/OpenSim/Tests/Permissions/IndirectTransferTests.cs
@@ -46,6 +46,12 @@ namespace OpenSim.Tests.Permissions
46 [SetUp] 46 [SetUp]
47 public void SetUp() 47 public void SetUp()
48 { 48 {
49 // In case we're dealing with some older version of nunit
50 if (Common.TheInstance == null)
51 {
52 Common.TheInstance = new Common();
53 Common.TheInstance.SetUp();
54 }
49 Common.TheInstance.DeleteObjectsFolders(); 55 Common.TheInstance.DeleteObjectsFolders();
50 } 56 }
51 57
@@ -74,6 +80,7 @@ namespace OpenSim.Tests.Permissions
74 // Try A2 takes copies of objects that cannot be copied. 80 // Try A2 takes copies of objects that cannot be copied.
75 for (int i = 0; i < 6; i++) 81 for (int i = 0; i < 6; i++)
76 TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]); 82 TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]);
83 // Ad-hoc. Enough time to let the take work.
77 Thread.Sleep(5000); 84 Thread.Sleep(5000);
78 85
79 List<InventoryItemBase> items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID); 86 List<InventoryItemBase> items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID);
@@ -86,6 +93,7 @@ namespace OpenSim.Tests.Permissions
86 // Try A2 takes copies of objects that can be copied. 93 // Try A2 takes copies of objects that can be copied.
87 for (int i = 0; i < 6; i++) 94 for (int i = 0; i < 6; i++)
88 TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]); 95 TakeOneBox(Common.TheScene.GetSceneObjectGroups(), names[i], perms[i]);
96 // Ad-hoc. Enough time to let the take work.
89 Thread.Sleep(5000); 97 Thread.Sleep(5000);
90 98
91 items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID); 99 items = Common.TheScene.InventoryService.GetFolderItems(Common.TheAvatars[1].UUID, objsFolder.ID);
@@ -101,6 +109,7 @@ namespace OpenSim.Tests.Permissions
101 109
102 private void TakeOneBox(List<SceneObjectGroup> objs, string name, PermissionMask mask) 110 private void TakeOneBox(List<SceneObjectGroup> objs, string name, PermissionMask mask)
103 { 111 {
112 // Find the object inworld
104 SceneObjectGroup box = objs.Find(sog => sog.Name == name && sog.OwnerID == Common.TheAvatars[0].UUID); 113 SceneObjectGroup box = objs.Find(sog => sog.Name == name && sog.OwnerID == Common.TheAvatars[0].UUID);
105 Assert.That(box, Is.Not.Null, name); 114 Assert.That(box, Is.Not.Null, name);
106 115