aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs313
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs5
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs120
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs4
-rw-r--r--OpenSim/Region/Communications/Hypergrid/HGUserServices.cs8
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs5
-rw-r--r--OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs19
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs124
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs120
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs78
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs112
-rw-r--r--OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs55
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs5
-rw-r--r--OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs10
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs6
-rw-r--r--OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs3
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs7
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandObject.cs40
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs29
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs10
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IFriendsModule.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/ILandObject.cs1
-rw-r--r--OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs44
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityBase.cs14
-rw-r--r--OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs28
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs126
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs30
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs26
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs88
-rw-r--r--OpenSim/Region/Framework/Scenes/UuidGatherer.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs3
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs5
-rw-r--r--OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs105
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs2
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs2
-rw-r--r--OpenSim/Region/Physics/Meshing/PrimMesher.cs847
-rw-r--r--OpenSim/Region/Physics/Meshing/SculptMesh.cs41
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs26
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs2
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs8
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerClientEventForwarder.cs (renamed from OpenSim/Region/CoreModules/World/Land/RegionCombinerClientEventForwarder.cs)2
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs (renamed from OpenSim/Region/CoreModules/World/Land/RegionCombinerIndividualEventForwarder.cs)2
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs (renamed from OpenSim/Region/CoreModules/World/Land/RegionCombinerLargeLandChannel.cs)3
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs (renamed from OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs)480
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs (renamed from OpenSim/Region/CoreModules/World/Land/RegionCombinerPermissionModule.cs)2
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionConnections.cs (renamed from OpenSim/Region/CoreModules/World/Land/RegionConnections.cs)2
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCourseLocation.cs (renamed from OpenSim/Region/CoreModules/World/Land/RegionCourseLocation.cs)2
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionData.cs (renamed from OpenSim/Region/CoreModules/World/Land/RegionData.cs)2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs134
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs91
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs66
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp1
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs27
67 files changed, 1866 insertions, 1568 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index db0c3b8..7eb829e 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -220,6 +220,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
220 public event FriendActionDelegate OnApproveFriendRequest; 220 public event FriendActionDelegate OnApproveFriendRequest;
221 public event FriendActionDelegate OnDenyFriendRequest; 221 public event FriendActionDelegate OnDenyFriendRequest;
222 public event FriendshipTermination OnTerminateFriendship; 222 public event FriendshipTermination OnTerminateFriendship;
223 public event GrantUserFriendRights OnGrantUserRights;
223 public event MoneyTransferRequest OnMoneyTransferRequest; 224 public event MoneyTransferRequest OnMoneyTransferRequest;
224 public event EconomyDataRequest OnEconomyDataRequest; 225 public event EconomyDataRequest OnEconomyDataRequest;
225 public event MoneyBalanceRequest OnMoneyBalanceRequest; 226 public event MoneyBalanceRequest OnMoneyBalanceRequest;
@@ -1251,7 +1252,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1251 /// <param name="fetchFolders">Do we need to send folder information?</param> 1252 /// <param name="fetchFolders">Do we need to send folder information?</param>
1252 /// <param name="fetchItems">Do we need to send item information?</param> 1253 /// <param name="fetchItems">Do we need to send item information?</param>
1253 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, 1254 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
1254 List<InventoryFolderBase> folders, 1255 List<InventoryFolderBase> folders, int version,
1255 bool fetchFolders, bool fetchItems) 1256 bool fetchFolders, bool fetchItems)
1256 { 1257 {
1257 // An inventory descendents packet consists of a single agent section and an inventory details 1258 // An inventory descendents packet consists of a single agent section and an inventory details
@@ -1264,174 +1265,107 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1264 // 1265 //
1265 // for one example of this kind of thing. In fact, the Linden servers appear to only send about 1266 // for one example of this kind of thing. In fact, the Linden servers appear to only send about
1266 // 6 to 7 items at a time, so let's stick with 6 1267 // 6 to 7 items at a time, so let's stick with 6
1267 int MAX_ITEMS_PER_PACKET = 6; 1268 int MAX_ITEMS_PER_PACKET = 5;
1268 1269 int MAX_FOLDERS_PER_PACKET = 6;
1269 //Ckrinke This variable is not used, so comment out to remove the warning from the compiler (3-21-08)
1270 //Ckrinke uint FULL_MASK_PERMISSIONS = 2147483647;
1271 1270
1271 int totalItems = fetchItems ? items.Count : 0;
1272 int totalFolders = fetchFolders ? folders.Count : 0;
1272 int itemsSent = 0; 1273 int itemsSent = 0;
1273 if (fetchItems) 1274 int foldersSent = 0;
1274 { 1275 int foldersToSend = 0;
1275 InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); 1276 int itemsToSend = 0;
1276 1277
1277 if (items.Count < MAX_ITEMS_PER_PACKET) 1278 InventoryDescendentsPacket currentPacket = null;
1278 {
1279 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count];
1280 }
1281 else
1282 {
1283 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[MAX_ITEMS_PER_PACKET];
1284 }
1285
1286 // Descendents must contain the *total* number of descendents (plus folders, whether we
1287 // fetch them or not), not the number of entries we send in this packet. For consistency,
1288 // I'll use it for folder-requests, too, although I wasn't able to get one with
1289 // FetchFolders = true.
1290 // TODO this should be checked with FetchFolders = true
1291 descend.AgentData.Descendents = items.Count + folders.Count;
1292 1279
1293 int count = 0; 1280 // Handle empty folders
1294 int i = 0; 1281 //
1295 foreach (InventoryItemBase item in items) 1282 if (totalItems == 0 && totalFolders == 0)
1283 currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, items.Count + folders.Count, 0, 0);
1284
1285 // To preserve SL compatibility, we will NOT combine folders and items in one packet
1286 //
1287 while(itemsSent < totalItems || foldersSent < totalFolders)
1288 {
1289 if (currentPacket == null) // Start a new packet
1296 { 1290 {
1297 descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock(); 1291 foldersToSend = totalFolders - foldersSent;
1298 descend.ItemData[i].ItemID = item.ID; 1292 if (foldersToSend > MAX_FOLDERS_PER_PACKET)
1299 descend.ItemData[i].AssetID = item.AssetID; 1293 foldersToSend = MAX_FOLDERS_PER_PACKET;
1300 descend.ItemData[i].CreatorID = item.CreatorIdAsUuid; 1294
1301 descend.ItemData[i].BaseMask = item.BasePermissions; 1295 if (foldersToSend == 0)
1302 descend.ItemData[i].Description = Util.StringToBytes256(item.Description); 1296 {
1303 descend.ItemData[i].EveryoneMask = item.EveryOnePermissions; 1297 itemsToSend = totalItems - itemsSent;
1304 descend.ItemData[i].OwnerMask = item.CurrentPermissions; 1298 if (itemsToSend > MAX_ITEMS_PER_PACKET)
1305 descend.ItemData[i].FolderID = item.Folder; 1299 itemsToSend = MAX_ITEMS_PER_PACKET;
1306 descend.ItemData[i].InvType = (sbyte)item.InvType;
1307 descend.ItemData[i].Name = Util.StringToBytes256(item.Name);
1308 descend.ItemData[i].NextOwnerMask = item.NextPermissions;
1309 descend.ItemData[i].OwnerID = item.Owner;
1310 descend.ItemData[i].Type = (sbyte)item.AssetType;
1311
1312 descend.ItemData[i].GroupID = item.GroupID;
1313 descend.ItemData[i].GroupOwned = item.GroupOwned;
1314 descend.ItemData[i].GroupMask = item.GroupPermissions;
1315 descend.ItemData[i].CreationDate = item.CreationDate;
1316 descend.ItemData[i].SalePrice = item.SalePrice;
1317 descend.ItemData[i].SaleType = item.SaleType;
1318 descend.ItemData[i].Flags = item.Flags;
1319
1320 descend.ItemData[i].CRC =
1321 Helpers.InventoryCRC(descend.ItemData[i].CreationDate, descend.ItemData[i].SaleType,
1322 descend.ItemData[i].InvType, descend.ItemData[i].Type,
1323 descend.ItemData[i].AssetID, descend.ItemData[i].GroupID,
1324 descend.ItemData[i].SalePrice,
1325 descend.ItemData[i].OwnerID, descend.ItemData[i].CreatorID,
1326 descend.ItemData[i].ItemID, descend.ItemData[i].FolderID,
1327 descend.ItemData[i].EveryoneMask,
1328 descend.ItemData[i].Flags, descend.ItemData[i].OwnerMask,
1329 descend.ItemData[i].GroupMask, item.CurrentPermissions);
1330
1331 i++;
1332 count++;
1333 itemsSent++;
1334 if (i == MAX_ITEMS_PER_PACKET)
1335 {
1336 descend.Header.Zerocoded = true;
1337 AddNullFolderBlockToDecendentsPacket(ref descend);
1338 OutPacket(descend, ThrottleOutPacketType.Asset);
1339
1340 if ((items.Count - count) > 0)
1341 {
1342 descend = CreateInventoryDescendentsPacket(ownerID, folderID);
1343 if ((items.Count - count) < MAX_ITEMS_PER_PACKET)
1344 {
1345 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items.Count - count];
1346 }
1347 else
1348 {
1349 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[MAX_ITEMS_PER_PACKET];
1350 }
1351 descend.AgentData.Descendents = items.Count + folders.Count;
1352 i = 0;
1353 }
1354 } 1300 }
1355 }
1356 1301
1357 if (0 < i && i < MAX_ITEMS_PER_PACKET) 1302 currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, items.Count + folders.Count, foldersToSend, itemsToSend);
1358 {
1359 AddNullFolderBlockToDecendentsPacket(ref descend);
1360 OutPacket(descend, ThrottleOutPacketType.Asset);
1361 } 1303 }
1362 }
1363 1304
1364 //send subfolders 1305 if (foldersToSend-- > 0)
1365 if (fetchFolders) 1306 currentPacket.FolderData[foldersSent % MAX_FOLDERS_PER_PACKET] = CreateFolderDataBlock(folders[foldersSent++]);
1366 { 1307 else if(itemsToSend-- > 0)
1367 InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); 1308 currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]);
1368
1369 if (folders.Count < MAX_ITEMS_PER_PACKET)
1370 {
1371 descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[folders.Count];
1372 }
1373 else 1309 else
1374 { 1310 {
1375 descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[MAX_ITEMS_PER_PACKET]; 1311 OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
1312 currentPacket = null;
1376 } 1313 }
1377 1314
1378 // Not sure if this scenario ever actually occurs, but nonetheless we include the items 1315 }
1379 // count even if we're not sending item data for the same reasons as above.
1380 descend.AgentData.Descendents = items.Count + folders.Count;
1381 1316
1382 int i = 0; 1317 if (currentPacket != null)
1383 int count = 0; 1318 OutPacket(currentPacket, ThrottleOutPacketType.Asset, false);
1384 foreach (InventoryFolderBase folder in folders) 1319 }
1385 {
1386 descend.FolderData[i] = new InventoryDescendentsPacket.FolderDataBlock();
1387 descend.FolderData[i].FolderID = folder.ID;
1388 descend.FolderData[i].Name = Util.StringToBytes256(folder.Name);
1389 descend.FolderData[i].ParentID = folder.ParentID;
1390 descend.FolderData[i].Type = (sbyte)folder.Type;
1391 1320
1392 i++; 1321 private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder)
1393 count++; 1322 {
1394 itemsSent++; 1323 InventoryDescendentsPacket.FolderDataBlock newBlock = new InventoryDescendentsPacket.FolderDataBlock();
1395 if (i == MAX_ITEMS_PER_PACKET) 1324 newBlock.FolderID = folder.ID;
1396 { 1325 newBlock.Name = Util.StringToBytes256(folder.Name);
1397 AddNullItemBlockToDescendentsPacket(ref descend); 1326 newBlock.ParentID = folder.ParentID;
1398 OutPacket(descend, ThrottleOutPacketType.Asset); 1327 newBlock.Type = (sbyte)folder.Type;
1399 1328
1400 if ((folders.Count - count) > 0) 1329 return newBlock;
1401 { 1330 }
1402 descend = CreateInventoryDescendentsPacket(ownerID, folderID);
1403 if ((folders.Count - count) < MAX_ITEMS_PER_PACKET)
1404 {
1405 descend.FolderData =
1406 new InventoryDescendentsPacket.FolderDataBlock[folders.Count - count];
1407 }
1408 else
1409 {
1410 descend.FolderData =
1411 new InventoryDescendentsPacket.FolderDataBlock[MAX_ITEMS_PER_PACKET];
1412 }
1413 descend.AgentData.Descendents = items.Count + folders.Count;
1414 i = 0;
1415 }
1416 }
1417 }
1418 1331
1419 if (0 < i && i < MAX_ITEMS_PER_PACKET) 1332 private InventoryDescendentsPacket.ItemDataBlock CreateItemDataBlock(InventoryItemBase item)
1420 { 1333 {
1421 AddNullItemBlockToDescendentsPacket(ref descend); 1334 InventoryDescendentsPacket.ItemDataBlock newBlock = new InventoryDescendentsPacket.ItemDataBlock();
1422 OutPacket(descend, ThrottleOutPacketType.Asset); 1335 newBlock.ItemID = item.ID;
1423 } 1336 newBlock.AssetID = item.AssetID;
1424 } 1337 newBlock.CreatorID = item.CreatorIdAsUuid;
1338 newBlock.BaseMask = item.BasePermissions;
1339 newBlock.Description = Util.StringToBytes256(item.Description);
1340 newBlock.EveryoneMask = item.EveryOnePermissions;
1341 newBlock.OwnerMask = item.CurrentPermissions;
1342 newBlock.FolderID = item.Folder;
1343 newBlock.InvType = (sbyte)item.InvType;
1344 newBlock.Name = Util.StringToBytes256(item.Name);
1345 newBlock.NextOwnerMask = item.NextPermissions;
1346 newBlock.OwnerID = item.Owner;
1347 newBlock.Type = (sbyte)item.AssetType;
1425 1348
1426 if (itemsSent == 0) 1349 newBlock.GroupID = item.GroupID;
1427 { 1350 newBlock.GroupOwned = item.GroupOwned;
1428 // no items found. 1351 newBlock.GroupMask = item.GroupPermissions;
1429 InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); 1352 newBlock.CreationDate = item.CreationDate;
1430 descend.AgentData.Descendents = 0; 1353 newBlock.SalePrice = item.SalePrice;
1431 AddNullItemBlockToDescendentsPacket(ref descend); 1354 newBlock.SaleType = item.SaleType;
1432 AddNullFolderBlockToDecendentsPacket(ref descend); 1355 newBlock.Flags = item.Flags;
1433 OutPacket(descend, ThrottleOutPacketType.Asset); 1356
1434 } 1357 newBlock.CRC =
1358 Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType,
1359 newBlock.InvType, newBlock.Type,
1360 newBlock.AssetID, newBlock.GroupID,
1361 newBlock.SalePrice,
1362 newBlock.OwnerID, newBlock.CreatorID,
1363 newBlock.ItemID, newBlock.FolderID,
1364 newBlock.EveryoneMask,
1365 newBlock.Flags, newBlock.OwnerMask,
1366 newBlock.GroupMask, newBlock.NextOwnerMask);
1367
1368 return newBlock;
1435 } 1369 }
1436 1370
1437 private void AddNullFolderBlockToDecendentsPacket(ref InventoryDescendentsPacket packet) 1371 private void AddNullFolderBlockToDecendentsPacket(ref InventoryDescendentsPacket packet)
@@ -1473,14 +1407,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1473 // No need to add CRC 1407 // No need to add CRC
1474 } 1408 }
1475 1409
1476 private InventoryDescendentsPacket CreateInventoryDescendentsPacket(UUID ownerID, UUID folderID) 1410 private InventoryDescendentsPacket CreateInventoryDescendentsPacket(UUID ownerID, UUID folderID, int version, int descendents, int folders, int items)
1477 { 1411 {
1478 InventoryDescendentsPacket descend = (InventoryDescendentsPacket)PacketPool.Instance.GetPacket(PacketType.InventoryDescendents); 1412 InventoryDescendentsPacket descend = (InventoryDescendentsPacket)PacketPool.Instance.GetPacket(PacketType.InventoryDescendents);
1479 descend.Header.Zerocoded = true; 1413 descend.Header.Zerocoded = true;
1480 descend.AgentData.AgentID = AgentId; 1414 descend.AgentData.AgentID = AgentId;
1481 descend.AgentData.OwnerID = ownerID; 1415 descend.AgentData.OwnerID = ownerID;
1482 descend.AgentData.FolderID = folderID; 1416 descend.AgentData.FolderID = folderID;
1483 descend.AgentData.Version = 1; 1417 descend.AgentData.Version = version;
1418 descend.AgentData.Descendents = descendents;
1419
1420 if (folders > 0)
1421 descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[folders];
1422 else
1423 AddNullFolderBlockToDecendentsPacket(ref descend);
1424
1425 if (items > 0)
1426 descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items];
1427 else
1428 AddNullItemBlockToDescendentsPacket(ref descend);
1484 1429
1485 return descend; 1430 return descend;
1486 } 1431 }
@@ -3251,12 +3196,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3251 if (!IsActive) return; // We don't need to update inactive clients. 3196 if (!IsActive) return; // We don't need to update inactive clients.
3252 3197
3253 CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate); 3198 CoarseLocationUpdatePacket loc = (CoarseLocationUpdatePacket)PacketPool.Instance.GetPacket(PacketType.CoarseLocationUpdate);
3254 // TODO: don't create new blocks if recycling an old packet 3199 loc.Header.Reliable = false;
3255 int total = CoarseLocations.Count; 3200
3256 CoarseLocationUpdatePacket.IndexBlock ib = 3201 // Each packet can only hold around 62 avatar positions and the client clears the mini-map each time
3257 new CoarseLocationUpdatePacket.IndexBlock(); 3202 // a CoarseLocationUpdate packet is received. Oh well.
3203 int total = Math.Min(CoarseLocations.Count, 60);
3204
3205 CoarseLocationUpdatePacket.IndexBlock ib = new CoarseLocationUpdatePacket.IndexBlock();
3206
3258 loc.Location = new CoarseLocationUpdatePacket.LocationBlock[total]; 3207 loc.Location = new CoarseLocationUpdatePacket.LocationBlock[total];
3259 loc.AgentData = new CoarseLocationUpdatePacket.AgentDataBlock[total]; 3208 loc.AgentData = new CoarseLocationUpdatePacket.AgentDataBlock[total];
3209
3260 int selfindex = -1; 3210 int selfindex = -1;
3261 for (int i = 0; i < total; i++) 3211 for (int i = 0; i < total; i++)
3262 { 3212 {
@@ -3266,18 +3216,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3266 lb.X = (byte)CoarseLocations[i].X; 3216 lb.X = (byte)CoarseLocations[i].X;
3267 lb.Y = (byte)CoarseLocations[i].Y; 3217 lb.Y = (byte)CoarseLocations[i].Y;
3268 3218
3269 lb.Z = CoarseLocations[i].Z > 1024 ? (byte)0 : (byte)(CoarseLocations[i].Z * 0.25); 3219 lb.Z = CoarseLocations[i].Z > 1024 ? (byte)0 : (byte)(CoarseLocations[i].Z * 0.25f);
3270 loc.Location[i] = lb; 3220 loc.Location[i] = lb;
3271 loc.AgentData[i] = new CoarseLocationUpdatePacket.AgentDataBlock(); 3221 loc.AgentData[i] = new CoarseLocationUpdatePacket.AgentDataBlock();
3272 loc.AgentData[i].AgentID = users[i]; 3222 loc.AgentData[i].AgentID = users[i];
3273 if (users[i] == AgentId) 3223 if (users[i] == AgentId)
3274 selfindex = i; 3224 selfindex = i;
3275 } 3225 }
3226
3276 ib.You = (short)selfindex; 3227 ib.You = (short)selfindex;
3277 ib.Prey = -1; 3228 ib.Prey = -1;
3278 loc.Index = ib; 3229 loc.Index = ib;
3279 loc.Header.Reliable = false;
3280 loc.Header.Zerocoded = true;
3281 3230
3282 OutPacket(loc, ThrottleOutPacketType.Task); 3231 OutPacket(loc, ThrottleOutPacketType.Task);
3283 } 3232 }
@@ -4088,11 +4037,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4088 4037
4089 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) 4038 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data)
4090 { 4039 {
4091 return CreateImprovedTerseBlock(false, data.LocalID, data.State, Vector4.Zero, data.Position, data.Velocity, 4040 return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity,
4092 data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); 4041 data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry);
4093 } 4042 }
4094 4043
4095 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, byte state, 4044 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint,
4096 Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation, 4045 Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation,
4097 Vector3 angularVelocity, byte[] textureEntry) 4046 Vector3 angularVelocity, byte[] textureEntry)
4098 { 4047 {
@@ -4104,7 +4053,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4104 pos += 4; 4053 pos += 4;
4105 4054
4106 // Avatar/CollisionPlane 4055 // Avatar/CollisionPlane
4107 data[pos++] = state; 4056 data[pos++] = (byte)((attachPoint % 16) * 16 + (attachPoint / 16)); ;
4108 if (avatar) 4057 if (avatar)
4109 { 4058 {
4110 data[pos++] = 1; 4059 data[pos++] = 1;
@@ -4960,9 +4909,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4960 /// <param name="throttlePacketType">Throttling category for the packet</param> 4909 /// <param name="throttlePacketType">Throttling category for the packet</param>
4961 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType) 4910 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType)
4962 { 4911 {
4912 #region BinaryStats
4913 LLUDPServer.LogPacketHeader(false, m_circuitCode, 0, packet.Type, (ushort)packet.Length);
4914 #endregion BinaryStats
4915
4963 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true); 4916 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, true);
4964 } 4917 }
4965 4918
4919 /// <summary>
4920 /// This is the starting point for sending a simulator packet out to the client
4921 /// </summary>
4922 /// <param name="packet">Packet to send</param>
4923 /// <param name="throttlePacketType">Throttling category for the packet</param>
4924 /// <param name="doAutomaticSplitting">True to automatically split oversized
4925 /// packets (the default), or false to disable splitting if the calling code
4926 /// handles splitting manually</param>
4927 protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting)
4928 {
4929 m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting);
4930 }
4931
4966 public bool AddMoney(int debit) 4932 public bool AddMoney(int debit)
4967 { 4933 {
4968 if (m_moneyBalance + debit >= 0) 4934 if (m_moneyBalance + debit >= 0)
@@ -9762,7 +9728,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9762 Utils.BytesToString(avatarInterestUpdate.PropertiesData.SkillsText), 9728 Utils.BytesToString(avatarInterestUpdate.PropertiesData.SkillsText),
9763 Utils.BytesToString(avatarInterestUpdate.PropertiesData.LanguagesText)); 9729 Utils.BytesToString(avatarInterestUpdate.PropertiesData.LanguagesText));
9764 break; 9730 break;
9765 9731
9732 case PacketType.GrantUserRights:
9733 GrantUserRightsPacket GrantUserRights =
9734 (GrantUserRightsPacket)Pack;
9735 #region Packet Session and User Check
9736 if (m_checkPackets)
9737 {
9738 if (GrantUserRights.AgentData.SessionID != SessionId ||
9739 GrantUserRights.AgentData.AgentID != AgentId)
9740 break;
9741 }
9742 #endregion
9743 GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
9744 if (GrantUserRightsHandler != null)
9745 GrantUserRightsHandler(this,
9746 GrantUserRights.AgentData.AgentID,
9747 GrantUserRights.Rights[0].AgentRelated,
9748 GrantUserRights.Rights[0].RelatedRights);
9749 break;
9750
9766 case PacketType.PlacesQuery: 9751 case PacketType.PlacesQuery:
9767 PlacesQueryPacket placesQueryPacket = 9752 PlacesQueryPacket placesQueryPacket =
9768 (PlacesQueryPacket)Pack; 9753 (PlacesQueryPacket)Pack;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
index 697bbe6..adf171e 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLFileTransfer.cs
@@ -197,11 +197,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
197 197
198 private void Initialise(UUID fileID, string fileName) 198 private void Initialise(UUID fileID, string fileName)
199 { 199 {
200 m_asset = new AssetBase(); 200 m_asset = new AssetBase(fileID, fileName, type);
201 m_asset.FullID = fileID;
202 m_asset.Type = type;
203 m_asset.Data = new byte[0]; 201 m_asset.Data = new byte[0];
204 m_asset.Name = fileName;
205 m_asset.Description = "empty"; 202 m_asset.Description = "empty";
206 m_asset.Local = true; 203 m_asset.Local = true;
207 m_asset.Temporary = true; 204 m_asset.Temporary = true;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 93946ae..c773c05 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
30using System.Net; 31using System.Net;
31using System.Net.Sockets; 32using System.Net.Sockets;
32using System.Reflection; 33using System.Reflection;
@@ -204,6 +205,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
204 TextureSendLimit = 20; 205 TextureSendLimit = 20;
205 } 206 }
206 207
208 #region BinaryStats
209 config = configSource.Configs["Statistics.Binary"];
210 m_shouldCollectStats = false;
211 if (config != null)
212 {
213 if (config.Contains("enabled") && config.GetBoolean("enabled"))
214 {
215 if (config.Contains("collect_packet_headers"))
216 m_shouldCollectStats = config.GetBoolean("collect_packet_headers");
217 if (config.Contains("packet_headers_period_seconds"))
218 {
219 binStatsMaxFilesize = TimeSpan.FromSeconds(config.GetInt("region_stats_period_seconds"));
220 }
221 if (config.Contains("stats_dir"))
222 {
223 binStatsDir = config.GetString("stats_dir");
224 }
225 }
226 else
227 {
228 m_shouldCollectStats = false;
229 }
230 }
231 #endregion BinaryStats
232
207 m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps); 233 m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps);
208 m_throttleRates = new ThrottleRates(configSource); 234 m_throttleRates = new ThrottleRates(configSource);
209 } 235 }
@@ -359,9 +385,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
359 } 385 }
360 else 386 else
361 { 387 {
362 m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + 388 bufferSize = dataLength;
363 type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length + ". Dropping packet"); 389 buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize);
364 return; 390
391 // m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
392 // type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length + ". Dropping packet");
393 Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
365 } 394 }
366 } 395 }
367 396
@@ -676,6 +705,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
676 705
677 #endregion Incoming Packet Accounting 706 #endregion Incoming Packet Accounting
678 707
708 #region BinaryStats
709 LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
710 #endregion BinaryStats
711
679 #region Ping Check Handling 712 #region Ping Check Handling
680 713
681 if (packet.Type == PacketType.StartPingCheck) 714 if (packet.Type == PacketType.StartPingCheck)
@@ -697,6 +730,87 @@ namespace OpenSim.Region.ClientStack.LindenUDP
697 packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); 730 packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
698 } 731 }
699 732
733 #region BinaryStats
734
735 public class PacketLogger
736 {
737 public DateTime StartTime;
738 public string Path = null;
739 public System.IO.BinaryWriter Log = null;
740 }
741
742 public static PacketLogger PacketLog;
743
744 protected static bool m_shouldCollectStats = false;
745 // Number of seconds to log for
746 static TimeSpan binStatsMaxFilesize = TimeSpan.FromSeconds(300);
747 static object binStatsLogLock = new object();
748 static string binStatsDir = "";
749
750 public static void LogPacketHeader(bool incoming, uint circuit, byte flags, PacketType packetType, ushort size)
751 {
752 if (!m_shouldCollectStats) return;
753
754 // Binary logging format is TTTTTTTTCCCCFPPPSS, T=Time, C=Circuit, F=Flags, P=PacketType, S=size
755
756 // Put the incoming bit into the least significant bit of the flags byte
757 if (incoming)
758 flags |= 0x01;
759 else
760 flags &= 0xFE;
761
762 // Put the flags byte into the most significant bits of the type integer
763 uint type = (uint)packetType;
764 type |= (uint)flags << 24;
765
766 // m_log.Debug("1 LogPacketHeader(): Outside lock");
767 lock (binStatsLogLock)
768 {
769 DateTime now = DateTime.Now;
770
771 // m_log.Debug("2 LogPacketHeader(): Inside lock. now is " + now.Ticks);
772 try
773 {
774 if (PacketLog == null || (now > PacketLog.StartTime + binStatsMaxFilesize))
775 {
776 if (PacketLog != null && PacketLog.Log != null)
777 {
778 PacketLog.Log.Close();
779 }
780
781 // First log file or time has expired, start writing to a new log file
782 PacketLog = new PacketLogger();
783 PacketLog.StartTime = now;
784 PacketLog.Path = (binStatsDir.Length > 0 ? binStatsDir + System.IO.Path.DirectorySeparatorChar.ToString() : "")
785 + String.Format("packets-{0}.log", now.ToString("yyyyMMddHHmmss"));
786 PacketLog.Log = new BinaryWriter(File.Open(PacketLog.Path, FileMode.Append, FileAccess.Write));
787 }
788
789 // Serialize the data
790 byte[] output = new byte[18];
791 Buffer.BlockCopy(BitConverter.GetBytes(now.Ticks), 0, output, 0, 8);
792 Buffer.BlockCopy(BitConverter.GetBytes(circuit), 0, output, 8, 4);
793 Buffer.BlockCopy(BitConverter.GetBytes(type), 0, output, 12, 4);
794 Buffer.BlockCopy(BitConverter.GetBytes(size), 0, output, 16, 2);
795
796 // Write the serialized data to disk
797 if (PacketLog != null && PacketLog.Log != null)
798 PacketLog.Log.Write(output);
799 }
800 catch (Exception ex)
801 {
802 m_log.Error("Packet statistics gathering failed: " + ex.Message, ex);
803 if (PacketLog.Log != null)
804 {
805 PacketLog.Log.Close();
806 }
807 PacketLog = null;
808 }
809 }
810 }
811
812 #endregion BinaryStats
813
700 private void HandleUseCircuitCode(object o) 814 private void HandleUseCircuitCode(object o)
701 { 815 {
702 object[] array = (object[])o; 816 object[] array = (object[])o;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index 552cc4a..d2779ba 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
@@ -270,8 +270,8 @@ namespace OpenMetaverse
270 { 270 {
271 try 271 try
272 { 272 {
273 UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; 273// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
274 int bytesSent = m_udpSocket.EndSendTo(result); 274 m_udpSocket.EndSendTo(result);
275 } 275 }
276 catch (SocketException) { } 276 catch (SocketException) { }
277 catch (ObjectDisposedException) { } 277 catch (ObjectDisposedException) { }
diff --git a/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs b/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs
index 49a2261..09d8285 100644
--- a/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs
+++ b/OpenSim/Region/Communications/Hypergrid/HGUserServices.cs
@@ -204,6 +204,14 @@ namespace OpenSim.Region.Communications.Hypergrid
204 return base.UpdateUserProfile(userProfile); 204 return base.UpdateUserProfile(userProfile);
205 } 205 }
206 206
207 public override bool AuthenticateUserByPassword(UUID userID, string password)
208 {
209 if (m_localUserServices != null)
210 return m_localUserServices.AuthenticateUserByPassword(userID, password);
211 else
212 return base.AuthenticateUserByPassword(userID, password);
213 }
214
207 #region IUserServices Friend Methods 215 #region IUserServices Friend Methods
208 216
209 // NOTE: We're still not dealing with foreign user friends 217 // NOTE: We're still not dealing with foreign user friends
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index e192b81..f698ea1 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -112,11 +112,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
112 bool storeLocal, bool tempFile) 112 bool storeLocal, bool tempFile)
113 { 113 {
114 ourClient = remoteClient; 114 ourClient = remoteClient;
115 m_asset = new AssetBase(); 115 m_asset = new AssetBase(assetID, "blank", type);
116 m_asset.FullID = assetID;
117 m_asset.Type = type;
118 m_asset.Data = data; 116 m_asset.Data = data;
119 m_asset.Name = "blank";
120 m_asset.Description = "empty"; 117 m_asset.Description = "empty";
121 m_asset.Local = storeLocal; 118 m_asset.Local = storeLocal;
122 m_asset.Temporary = tempFile; 119 m_asset.Temporary = tempFile;
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
index 7456e8c..7ac8bed 100644
--- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
+++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs
@@ -144,8 +144,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
144 /// <param name="j2kData">JPEG2000 data</param> 144 /// <param name="j2kData">JPEG2000 data</param>
145 private void DoJ2KDecode(UUID assetID, byte[] j2kData) 145 private void DoJ2KDecode(UUID assetID, byte[] j2kData)
146 { 146 {
147 int DecodeTime = 0; 147// int DecodeTime = 0;
148 DecodeTime = Environment.TickCount; 148// DecodeTime = Environment.TickCount;
149 OpenJPEG.J2KLayerInfo[] layers; 149 OpenJPEG.J2KLayerInfo[] layers;
150 150
151 if (!TryLoadCacheForAsset(assetID, out layers)) 151 if (!TryLoadCacheForAsset(assetID, out layers))
@@ -238,12 +238,11 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
238 238
239 if (m_cache != null) 239 if (m_cache != null)
240 { 240 {
241 AssetBase layerDecodeAsset = new AssetBase(); 241 string assetID = "j2kCache_" + AssetId.ToString();
242 layerDecodeAsset.ID = "j2kCache_" + AssetId.ToString(); 242
243 AssetBase layerDecodeAsset = new AssetBase(assetID, assetID, (sbyte)AssetType.Notecard);
243 layerDecodeAsset.Local = true; 244 layerDecodeAsset.Local = true;
244 layerDecodeAsset.Name = layerDecodeAsset.ID;
245 layerDecodeAsset.Temporary = true; 245 layerDecodeAsset.Temporary = true;
246 layerDecodeAsset.Type = (sbyte)AssetType.Notecard;
247 246
248 #region Serialize Layer Data 247 #region Serialize Layer Data
249 248
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index c6af806..adcf6bd 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -831,7 +831,7 @@ namespace Flotsam.RegionModules.AssetCache
831 831
832 public string Store(AssetBase asset) 832 public string Store(AssetBase asset)
833 { 833 {
834 if ((asset.FullID == null) || (asset.FullID == UUID.Zero)) 834 if (asset.FullID == UUID.Zero)
835 { 835 {
836 asset.FullID = UUID.Random(); 836 asset.FullID = UUID.Random();
837 } 837 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index fc7d63a..bb4e032 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -395,6 +395,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
395 395
396 // if it leaves, we want to know, too 396 // if it leaves, we want to know, too
397 client.OnLogout += OnLogout; 397 client.OnLogout += OnLogout;
398 client.OnGrantUserRights += GrantUserFriendRights;
399
398 } 400 }
399 401
400 private void ClientClosed(UUID AgentId, Scene scene) 402 private void ClientClosed(UUID AgentId, Scene scene)
@@ -1108,7 +1110,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
1108 // tell everyone that we are offline 1110 // tell everyone that we are offline
1109 SendPresenceState(remoteClient, fl, false); 1111 SendPresenceState(remoteClient, fl, false);
1110 } 1112 }
1111 } 1113 private void GrantUserFriendRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
1114 {
1115 ((Scene)remoteClient.Scene).CommsManager.UpdateUserFriendPerms(requester, target, (uint)rights);
1116 }
1112 1117
1118 public List<FriendListItem> GetUserFriends(UUID agentID)
1119 {
1120 List<FriendListItem> fl;
1121 lock (m_friendLists)
1122 {
1123 fl = (List<FriendListItem>)m_friendLists.Get(agentID.ToString(),
1124 m_initialScene.GetFriendList);
1125 }
1126
1127 return fl;
1128 }
1129 }
1113 #endregion 1130 #endregion
1114} 1131}
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
index f761bf0..aafcfa2 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs
@@ -99,36 +99,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
99 int failedAssetRestores = 0; 99 int failedAssetRestores = 0;
100 int successfulItemRestores = 0; 100 int successfulItemRestores = 0;
101 List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>(); 101 List<InventoryNodeBase> nodesLoaded = new List<InventoryNodeBase>();
102
103 /*
104 if (!m_userInfo.HasReceivedInventory)
105 {
106 // If the region server has access to the user admin service (by which users are created),
107 // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the
108 // server.
109 //
110 // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might
111 // use a remote inventory service, though this is vanishingly rare at the moment.
112 if (null == m_scene.CommsManager.UserAdminService)
113 {
114 m_log.ErrorFormat(
115 "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}",
116 m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID);
117
118 return nodesLoaded;
119 }
120 else
121 {
122 m_userInfo.FetchInventory();
123 for (int i = 0 ; i < 50 ; i++)
124 {
125 if (m_userInfo.HasReceivedInventory == true)
126 break;
127 Thread.Sleep(200);
128 }
129 }
130 }
131 */
132 102
133 //InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath); 103 //InventoryFolderImpl rootDestinationFolder = m_userInfo.RootFolder.FindFolderByPath(m_invPath);
134 InventoryFolderBase rootDestinationFolder 104 InventoryFolderBase rootDestinationFolder
@@ -159,9 +129,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
159 successfulAssetRestores++; 129 successfulAssetRestores++;
160 else 130 else
161 failedAssetRestores++; 131 failedAssetRestores++;
132
133 if ((successfulAssetRestores) % 50 == 0)
134 m_log.DebugFormat(
135 "[INVENTORY ARCHIVER]: Loaded {0} assets...",
136 successfulAssetRestores);
162 } 137 }
163 else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH)) 138 else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH))
164 { 139 {
165 InventoryFolderBase foundFolder 140 InventoryFolderBase foundFolder
166 = ReplicateArchivePathToUserInventory( 141 = ReplicateArchivePathToUserInventory(
167 filePath, TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType, 142 filePath, TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType,
@@ -169,38 +144,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
169 144
170 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) 145 if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType)
171 { 146 {
172 InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data); 147 InventoryItemBase item = LoadItem(data, foundFolder);
173
174 // Don't use the item ID that's in the file
175 item.ID = UUID.Random();
176
177 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.CommsManager);
178 if (UUID.Zero != ospResolvedId)
179 item.CreatorIdAsUuid = ospResolvedId;
180 else
181 item.CreatorIdAsUuid = m_userInfo.UserProfile.ID;
182
183 item.Owner = m_userInfo.UserProfile.ID;
184
185 // Reset folder ID to the one in which we want to load it
186 item.Folder = foundFolder.ID;
187 148
188 //m_userInfo.AddItem(item); 149 if (item != null)
189 m_scene.InventoryService.AddItem(item); 150 {
190 successfulItemRestores++; 151 successfulItemRestores++;
191 152
192 // If we're loading an item directly into the given destination folder then we need to record 153 // If we're loading an item directly into the given destination folder then we need to record
193 // it separately from any loaded root folders 154 // it separately from any loaded root folders
194 if (rootDestinationFolder == foundFolder) 155 if (rootDestinationFolder == foundFolder)
195 nodesLoaded.Add(item); 156 nodesLoaded.Add(item);
157 }
196 } 158 }
197 } 159 }
198 } 160 }
199 161
200 archive.Close(); 162 archive.Close();
201 163
202 m_log.DebugFormat("[INVENTORY ARCHIVER]: Restored {0} assets", successfulAssetRestores); 164 m_log.DebugFormat(
203 m_log.InfoFormat("[INVENTORY ARCHIVER]: Restored {0} items", successfulItemRestores); 165 "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures",
166 successfulAssetRestores, failedAssetRestores);
167 m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores);
204 168
205 return nodesLoaded; 169 return nodesLoaded;
206 } 170 }
@@ -234,8 +198,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
234 198
235 string originalArchivePath = archivePath; 199 string originalArchivePath = archivePath;
236 200
237 m_log.DebugFormat( 201// m_log.DebugFormat(
238 "[INVENTORY ARCHIVER]: Loading to folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID); 202// "[INVENTORY ARCHIVER]: Loading folder {0} {1}", rootDestFolder.Name, rootDestFolder.ID);
239 203
240 InventoryFolderBase destFolder = null; 204 InventoryFolderBase destFolder = null;
241 205
@@ -246,8 +210,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
246 { 210 {
247 if (foldersCreated.ContainsKey(archivePath)) 211 if (foldersCreated.ContainsKey(archivePath))
248 { 212 {
249 m_log.DebugFormat( 213// m_log.DebugFormat(
250 "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath); 214// "[INVENTORY ARCHIVER]: Found previously created folder from archive path {0}", archivePath);
251 destFolder = foldersCreated[archivePath]; 215 destFolder = foldersCreated[archivePath];
252 } 216 }
253 else 217 else
@@ -289,6 +253,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
289 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR); 253 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR);
290 254
291 string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex); 255 string newFolderName = rawDirsToCreate[i].Remove(identicalNameIdentifierIndex);
256
257 newFolderName = InventoryArchiveUtils.UnescapeArchivePath(newFolderName);
292 UUID newFolderId = UUID.Random(); 258 UUID newFolderId = UUID.Random();
293 259
294 // Asset type has to be Unknown here rather than Folder, otherwise the created folder can't be 260 // Asset type has to be Unknown here rather than Folder, otherwise the created folder can't be
@@ -361,6 +327,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
361 } 327 }
362 328
363 /// <summary> 329 /// <summary>
330 /// Load an item from the archive
331 /// </summary>
332 /// <param name="filePath">The archive path for the item</param>
333 /// <param name="data">The raw item data</param>
334 /// <param name="rootDestinationFolder">The root destination folder for loaded items</param>
335 /// <param name="nodesLoaded">All the inventory nodes (items and folders) loaded so far</param>
336 protected InventoryItemBase LoadItem(byte[] data, InventoryFolderBase loadFolder)
337 {
338 InventoryItemBase item = UserInventoryItemSerializer.Deserialize(data);
339
340 // Don't use the item ID that's in the file
341 item.ID = UUID.Random();
342
343 UUID ospResolvedId = OspResolver.ResolveOspa(item.CreatorId, m_scene.CommsManager);
344 if (UUID.Zero != ospResolvedId)
345 item.CreatorIdAsUuid = ospResolvedId;
346 else
347 item.CreatorIdAsUuid = m_userInfo.UserProfile.ID;
348
349 item.Owner = m_userInfo.UserProfile.ID;
350
351 // Reset folder ID to the one in which we want to load it
352 item.Folder = loadFolder.ID;
353
354 //m_userInfo.AddItem(item);
355 m_scene.InventoryService.AddItem(item);
356
357 return item;
358 }
359
360 /// <summary>
364 /// Load an asset 361 /// Load an asset
365 /// </summary> 362 /// </summary>
366 /// <param name="assetFilename"></param> 363 /// <param name="assetFilename"></param>
@@ -389,11 +386,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
389 { 386 {
390 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; 387 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
391 388
392 //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); 389 if (assetType == (sbyte)AssetType.Unknown)
390 m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid);
393 391
394 AssetBase asset = new AssetBase(new UUID(uuid), "RandomName"); 392 //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType);
395 393
396 asset.Type = assetType; 394 AssetBase asset = new AssetBase(new UUID(uuid), "RandomName", assetType);
397 asset.Data = data; 395 asset.Data = data;
398 396
399 m_scene.AssetService.Store(asset); 397 m_scene.AssetService.Store(asset);
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
index a822d10..247cee4 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveUtils.cs
@@ -27,6 +27,9 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
30using OpenMetaverse; 33using OpenMetaverse;
31using OpenSim.Framework; 34using OpenSim.Framework;
32using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
@@ -38,7 +41,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
38 /// </summary> 41 /// </summary>
39 public static class InventoryArchiveUtils 42 public static class InventoryArchiveUtils
40 { 43 {
41 public static readonly string PATH_DELIMITER = "/"; 44// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 // Character used for escaping the path delimter ("\/") and itself ("\\") in human escaped strings
47 public static readonly char ESCAPE_CHARACTER = '\\';
48
49 // The character used to separate inventory path components (different folders and items)
50 public static readonly char PATH_DELIMITER = '/';
42 51
43 /// <summary> 52 /// <summary>
44 /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder 53 /// Find a folder given a PATH_DELIMITER delimited path starting from a user's root folder
@@ -103,10 +112,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
103 112
104 path = path.Trim(); 113 path = path.Trim();
105 114
106 if (path == PATH_DELIMITER) 115 if (path == PATH_DELIMITER.ToString())
107 return startFolder; 116 return startFolder;
108 117
109 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 118 string[] components = SplitEscapedPath(path);
119 components[0] = UnescapePath(components[0]);
120
121 //string[] components = path.Split(new string[] { PATH_DELIMITER.ToString() }, 2, StringSplitOptions.None);
122
110 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 123 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
111 124
112 foreach (InventoryFolderBase folder in contents.Folders) 125 foreach (InventoryFolderBase folder in contents.Folders)
@@ -181,10 +194,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
181 public static InventoryItemBase FindItemByPath( 194 public static InventoryItemBase FindItemByPath(
182 IInventoryService inventoryService, InventoryFolderBase startFolder, string path) 195 IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
183 { 196 {
184 string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); 197 string[] components = SplitEscapedPath(path);
198 components[0] = UnescapePath(components[0]);
199
200 //string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None);
185 201
186 if (components.Length == 1) 202 if (components.Length == 1)
187 { 203 {
204// m_log.DebugFormat("FOUND SINGLE COMPONENT [{0}]", components[0]);
205
188 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID); 206 List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
189 foreach (InventoryItemBase item in items) 207 foreach (InventoryItemBase item in items)
190 { 208 {
@@ -194,6 +212,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
194 } 212 }
195 else 213 else
196 { 214 {
215// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
216
197 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID); 217 InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
198 218
199 foreach (InventoryFolderBase folder in contents.Folders) 219 foreach (InventoryFolderBase folder in contents.Folders)
@@ -206,5 +226,97 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
206 // We didn't find an item or intermediate folder with the given name 226 // We didn't find an item or intermediate folder with the given name
207 return null; 227 return null;
208 } 228 }
229
230 /// <summary>
231 /// Split a human escaped path into two components if it contains an unescaped path delimiter, or one component
232 /// if no delimiter is present
233 /// </summary>
234 /// <param name="path"></param>
235 /// <returns>
236 /// The split path. We leave the components in their originally unescaped state (though we remove the delimiter
237 /// which originally split them if applicable).
238 /// </returns>
239 public static string[] SplitEscapedPath(string path)
240 {
241// m_log.DebugFormat("SPLITTING PATH {0}", path);
242
243 bool singleEscapeChar = false;
244
245 for (int i = 0; i < path.Length; i++)
246 {
247 if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar)
248 {
249 singleEscapeChar = true;
250 }
251 else
252 {
253 if (PATH_DELIMITER == path[i] && !singleEscapeChar)
254 return new string[2] { path.Remove(i), path.Substring(i + 1) };
255 else
256 singleEscapeChar = false;
257 }
258 }
259
260 // We didn't find a delimiter
261 return new string[1] { path };
262 }
263
264 /// <summary>
265 /// Unescapes a human escaped path. This means that "\\" goes to "\", and "\/" goes to "/"
266 /// </summary>
267 /// <param name="path"></param>
268 /// <returns></returns>
269 public static string UnescapePath(string path)
270 {
271// m_log.DebugFormat("ESCAPING PATH {0}", path);
272
273 StringBuilder sb = new StringBuilder();
274
275 bool singleEscapeChar = false;
276 for (int i = 0; i < path.Length; i++)
277 {
278 if (path[i] == ESCAPE_CHARACTER && !singleEscapeChar)
279 singleEscapeChar = true;
280 else
281 singleEscapeChar = false;
282
283 if (singleEscapeChar)
284 {
285 if (PATH_DELIMITER == path[i])
286 sb.Append(PATH_DELIMITER);
287 }
288 else
289 {
290 sb.Append(path[i]);
291 }
292 }
293
294// m_log.DebugFormat("ESCAPED PATH TO {0}", sb);
295
296 return sb.ToString();
297 }
298
299 /// <summary>
300 /// Escape an archive path.
301 /// </summary>
302 /// This has to be done differently from human paths because we can't leave in any "/" characters (due to
303 /// problems if the archive is built from or extracted to a filesystem
304 /// <param name="path"></param>
305 /// <returns></returns>
306 public static string EscapeArchivePath(string path)
307 {
308 // Only encode ampersands (for escaping anything) and / (since this is used as general dir separator).
309 return path.Replace("&", "&amp;").Replace("/", "&#47;");
310 }
311
312 /// <summary>
313 /// Unescape an archive path.
314 /// </summary>
315 /// <param name="path"></param>
316 /// <returns></returns>
317 public static string UnescapeArchivePath(string path)
318 {
319 return path.Replace("&#47;", "/").Replace("&amp;", "&");
320 }
209 } 321 }
210} \ No newline at end of file 322} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
index 499c552..bbb49f6 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveWriteRequest.cs
@@ -217,37 +217,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
217 InventoryItemBase inventoryItem = null; 217 InventoryItemBase inventoryItem = null;
218 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.UserProfile.ID); 218 InventoryFolderBase rootFolder = m_scene.InventoryService.GetRootFolder(m_userInfo.UserProfile.ID);
219 219
220 // XXX: Very temporarily, drop and refetch inventory to make sure we have any newly created items in cache
221 // This will disappear very soon once we stop using the old cached inventory.
222 /*
223 m_userInfo.DropInventory();
224 m_userInfo.FetchInventory();
225 */
226
227 /*
228 if (!m_userInfo.HasReceivedInventory)
229 {
230 // If the region server has access to the user admin service (by which users are created),
231 // then we'll assume that it's okay to fiddle with the user's inventory even if they are not on the
232 // server.
233 //
234 // FIXME: FetchInventory should probably be assumed to by async anyway, since even standalones might
235 // use a remote inventory service, though this is vanishingly rare at the moment.
236 if (null == m_scene.CommsManager.UserAdminService)
237 {
238 m_log.ErrorFormat(
239 "[INVENTORY ARCHIVER]: Have not yet received inventory info for user {0} {1}",
240 m_userInfo.UserProfile.Name, m_userInfo.UserProfile.ID);
241
242 return;
243 }
244 else
245 {
246 m_userInfo.FetchInventory();
247 }
248 }
249 */
250
251 bool foundStar = false; 220 bool foundStar = false;
252 221
253 // Eliminate double slashes and any leading / on the path. 222 // Eliminate double slashes and any leading / on the path.
@@ -294,34 +263,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
294 263
295 m_archiveWriter = new TarArchiveWriter(m_saveStream); 264 m_archiveWriter = new TarArchiveWriter(m_saveStream);
296 265
297 if (null == inventoryFolder) 266 if (inventoryFolder != null)
298 {
299 if (null == inventoryItem)
300 {
301 // We couldn't find the path indicated
302 m_saveStream.Close();
303 m_module.TriggerInventoryArchiveSaved(
304 m_id, false, m_userInfo, m_invPath, m_saveStream,
305 new Exception(string.Format("Could not find inventory entry at path {0}", m_invPath)));
306 return;
307 }
308 else
309 {
310 m_log.DebugFormat(
311 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
312 inventoryItem.Name, inventoryItem.ID, m_invPath);
313
314 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH);
315 }
316 }
317 else
318 { 267 {
319 m_log.DebugFormat( 268 m_log.DebugFormat(
320 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}", 269 "[INVENTORY ARCHIVER]: Found folder {0} {1} at {2}",
321 inventoryFolder.Name, inventoryFolder.ID, m_invPath); 270 inventoryFolder.Name, inventoryFolder.ID, m_invPath);
322 271
323 //recurse through all dirs getting dirs and files 272 //recurse through all dirs getting dirs and files
324 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar); 273 SaveInvFolder(inventoryFolder, ArchiveConstants.INVENTORY_PATH, !foundStar);
274 }
275 else if (inventoryItem != null)
276 {
277 m_log.DebugFormat(
278 "[INVENTORY ARCHIVER]: Found item {0} {1} at {2}",
279 inventoryItem.Name, inventoryItem.ID, m_invPath);
280
281 SaveInvItem(inventoryItem, ArchiveConstants.INVENTORY_PATH);
282 }
283 else
284 {
285 // We couldn't find the path indicated
286 m_saveStream.Close();
287 string errorMessage = string.Format("Aborted save. Could not find inventory path {0}", m_invPath);
288 m_log.ErrorFormat("[INVENTORY ARCHIVER]: {0}", errorMessage);
289 m_module.TriggerInventoryArchiveSaved(
290 m_id, false, m_userInfo, m_invPath, m_saveStream,
291 new Exception(errorMessage));
292 return;
325 } 293 }
326 294
327 // Don't put all this profile information into the archive right now. 295 // Don't put all this profile information into the archive right now.
@@ -396,7 +364,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
396 { 364 {
397 return string.Format( 365 return string.Format(
398 "{0}{1}{2}/", 366 "{0}{1}{2}/",
399 name, 367 InventoryArchiveUtils.EscapeArchivePath(name),
400 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, 368 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
401 id); 369 id);
402 } 370 }
@@ -411,7 +379,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
411 { 379 {
412 return string.Format( 380 return string.Format(
413 "{0}{1}{2}.xml", 381 "{0}{1}{2}.xml",
414 name, 382 InventoryArchiveUtils.EscapeArchivePath(name),
415 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR, 383 ArchiveConstants.INVENTORY_NODE_NAME_COMPONENT_SEPARATOR,
416 id); 384 id);
417 } 385 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
index b0fdcd6..f8a010c 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs
@@ -29,7 +29,6 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO; 30using System.IO;
31using System.Reflection; 31using System.Reflection;
32using System.Text;
33using System.Threading; 32using System.Threading;
34using NUnit.Framework; 33using NUnit.Framework;
35using NUnit.Framework.SyntaxHelpers; 34using NUnit.Framework.SyntaxHelpers;
@@ -122,9 +121,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
122 } 121 }
123 122
124 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); 123 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
125 AssetBase asset1 = new AssetBase(); 124 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
126 asset1.FullID = asset1Id;
127 asset1.Data = Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(object1));
128 scene.AssetService.Store(asset1); 125 scene.AssetService.Store(asset1);
129 126
130 // Create item 127 // Create item
@@ -136,7 +133,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
136 InventoryFolderBase objsFolder 133 InventoryFolderBase objsFolder
137 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects"); 134 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects");
138 item1.Folder = objsFolder.ID; 135 item1.Folder = objsFolder.ID;
139 scene.AddInventoryItem(userId, item1); 136 scene.AddInventoryItem(userId, item1);
140 137
141 MemoryStream archiveWriteStream = new MemoryStream(); 138 MemoryStream archiveWriteStream = new MemoryStream();
142 archiverModule.OnInventoryArchiveSaved += SaveCompleted; 139 archiverModule.OnInventoryArchiveSaved += SaveCompleted;
@@ -218,14 +215,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
218 string userItemCreatorLastName = "Lucan"; 215 string userItemCreatorLastName = "Lucan";
219 UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000000666"); 216 UUID userItemCreatorUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
220 217
221 string itemName = "b.lsl"; 218 string item1Name = "b.lsl";
222 string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(itemName, UUID.Random()); 219 string archiveItemName = InventoryArchiveWriteRequest.CreateArchiveItemName(item1Name, UUID.Random());
223 220
224 MemoryStream archiveWriteStream = new MemoryStream(); 221 MemoryStream archiveWriteStream = new MemoryStream();
225 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); 222 TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream);
226 223
227 InventoryItemBase item1 = new InventoryItemBase(); 224 InventoryItemBase item1 = new InventoryItemBase();
228 item1.Name = itemName; 225 item1.Name = item1Name;
229 item1.AssetID = UUID.Random(); 226 item1.AssetID = UUID.Random();
230 item1.GroupID = UUID.Random(); 227 item1.GroupID = UUID.Random();
231 item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName); 228 item1.CreatorId = OspResolver.MakeOspa(userItemCreatorFirstName, userItemCreatorLastName);
@@ -259,7 +256,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
259 = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName); 256 = scene.CommsManager.UserProfileCacheService.GetUserDetails(userFirstName, userLastName);
260 257
261 InventoryItemBase foundItem1 258 InventoryItemBase foundItem1
262 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, itemName); 259 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, item1Name);
263 260
264 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); 261 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
265 Assert.That( 262 Assert.That(
@@ -277,7 +274,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
277 archiverModule.DearchiveInventory(userFirstName, userLastName, "xA", "meowfood", archiveReadStream); 274 archiverModule.DearchiveInventory(userFirstName, userLastName, "xA", "meowfood", archiveReadStream);
278 275
279 InventoryItemBase foundItem2 276 InventoryItemBase foundItem2
280 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xA/" + itemName); 277 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xA/" + item1Name);
281 Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); 278 Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2");
282 279
283 // Now try loading to a more deeply nested folder 280 // Now try loading to a more deeply nested folder
@@ -286,10 +283,99 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
286 archiverModule.DearchiveInventory(userFirstName, userLastName, "xB/xC", "meowfood", archiveReadStream); 283 archiverModule.DearchiveInventory(userFirstName, userLastName, "xB/xC", "meowfood", archiveReadStream);
287 284
288 InventoryItemBase foundItem3 285 InventoryItemBase foundItem3
289 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xB/xC/" + itemName); 286 = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, userInfo.UserProfile.ID, "xB/xC/" + item1Name);
290 Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3"); 287 Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3");
291 } 288 }
292 289
290 [Test]
291 public void TestIarV0_1WithEscapedChars()
292 {
293 TestHelper.InMethod();
294// log4net.Config.XmlConfigurator.Configure();
295
296 string itemName = "You & you are a mean/man/";
297 string humanEscapedItemName = @"You & you are a mean\/man\/";
298 string userPassword = "meowfood";
299
300 InventoryArchiverModule archiverModule = new InventoryArchiverModule(true);
301
302 Scene scene = SceneSetupHelpers.SetupScene("Inventory");
303 SceneSetupHelpers.SetupSceneModules(scene, archiverModule);
304 CommunicationsManager cm = scene.CommsManager;
305
306 // Create user
307 string userFirstName = "Jock";
308 string userLastName = "Stirrup";
309 UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020");
310
311 lock (this)
312 {
313 UserProfileTestUtils.CreateUserWithInventory(
314 cm, userFirstName, userLastName, userPassword, userId, InventoryReceived);
315 Monitor.Wait(this, 60000);
316 }
317
318 // Create asset
319 SceneObjectGroup object1;
320 SceneObjectPart part1;
321 {
322 string partName = "part name";
323 UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000040");
324 PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere();
325 Vector3 groupPosition = new Vector3(10, 20, 30);
326 Quaternion rotationOffset = new Quaternion(20, 30, 40, 50);
327 Vector3 offsetPosition = new Vector3(5, 10, 15);
328
329 part1
330 = new SceneObjectPart(
331 ownerId, shape, groupPosition, rotationOffset, offsetPosition);
332 part1.Name = partName;
333
334 object1 = new SceneObjectGroup(part1);
335 scene.AddNewSceneObject(object1, false);
336 }
337
338 UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060");
339 AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1);
340 scene.AssetService.Store(asset1);
341
342 // Create item
343 UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080");
344 InventoryItemBase item1 = new InventoryItemBase();
345 item1.Name = itemName;
346 item1.AssetID = asset1.FullID;
347 item1.ID = item1Id;
348 InventoryFolderBase objsFolder
349 = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects");
350 item1.Folder = objsFolder.ID;
351 scene.AddInventoryItem(userId, item1);
352
353 MemoryStream archiveWriteStream = new MemoryStream();
354 archiverModule.OnInventoryArchiveSaved += SaveCompleted;
355
356 mre.Reset();
357 archiverModule.ArchiveInventory(
358 Guid.NewGuid(), userFirstName, userLastName, "Objects", userPassword, archiveWriteStream);
359 mre.WaitOne(60000, false);
360
361 // LOAD ITEM
362 MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
363
364 archiverModule.DearchiveInventory(userFirstName, userLastName, "Scripts", userPassword, archiveReadStream);
365
366 InventoryItemBase foundItem1
367 = InventoryArchiveUtils.FindItemByPath(
368 scene.InventoryService, userId, "Scripts/Objects/" + humanEscapedItemName);
369
370 Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1");
371// Assert.That(
372// foundItem1.CreatorId, Is.EqualTo(userUuid),
373// "Loaded item non-uuid creator doesn't match that of the loading user");
374 Assert.That(
375 foundItem1.Name, Is.EqualTo(itemName),
376 "Loaded item name doesn't match saved name");
377 }
378
293 /// <summary> 379 /// <summary>
294 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where 380 /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where
295 /// embedded creators do not exist in the system 381 /// embedded creators do not exist in the system
@@ -302,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
302 { 388 {
303 TestHelper.InMethod(); 389 TestHelper.InMethod();
304 390
305 log4net.Config.XmlConfigurator.Configure(); 391 //log4net.Config.XmlConfigurator.Configure();
306 392
307 string userFirstName = "Charlie"; 393 string userFirstName = "Charlie";
308 string userLastName = "Chan"; 394 string userLastName = "Chan";
@@ -370,7 +456,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
370 { 456 {
371 TestHelper.InMethod(); 457 TestHelper.InMethod();
372 458
373 log4net.Config.XmlConfigurator.Configure(); 459 //log4net.Config.XmlConfigurator.Configure();
374 460
375 string userFirstName = "Dennis"; 461 string userFirstName = "Dennis";
376 string userLastName = "Menace"; 462 string userLastName = "Menace";
diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
index 769af8d..11aca99 100644
--- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs
@@ -1,7 +1,10 @@
1using System.Collections.Generic; 1using System.Collections;
2using System.Collections.Generic;
2using System.Reflection; 3using System.Reflection;
3using log4net; 4using log4net;
4using Nini.Config; 5using Nini.Config;
6using OpenMetaverse;
7using OpenSim.Framework;
5using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts; 8using OpenSim.Region.CoreModules.Framework.Monitoring.Alerts;
6using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors; 9using OpenSim.Region.CoreModules.Framework.Monitoring.Monitors;
7using OpenSim.Region.Framework.Interfaces; 10using OpenSim.Region.Framework.Interfaces;
@@ -43,6 +46,56 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring
43 "monitor report", 46 "monitor report",
44 "Returns a variety of statistics about the current region and/or simulator", 47 "Returns a variety of statistics about the current region and/or simulator",
45 DebugMonitors); 48 DebugMonitors);
49
50 MainServer.Instance.AddHTTPHandler("/monitorstats/" + m_scene.RegionInfo.RegionID + "/", StatsPage);
51 }
52
53 public Hashtable StatsPage(Hashtable request)
54 {
55 // If request was for a specific monitor
56 // eg url/?monitor=Monitor.Name
57 if (request.ContainsKey("monitor"))
58 {
59 string monID = (string) request["monitor"];
60
61 foreach (IMonitor monitor in m_monitors)
62 {
63 if (monitor.ToString() == monID)
64 {
65 Hashtable ereply3 = new Hashtable();
66
67 ereply3["int_response_code"] = 404; // 200 OK
68 ereply3["str_response_string"] = monitor.GetValue().ToString();
69 ereply3["content_type"] = "text/plain";
70
71 return ereply3;
72 }
73 }
74
75 // No monitor with that name
76 Hashtable ereply2 = new Hashtable();
77
78 ereply2["int_response_code"] = 404; // 200 OK
79 ereply2["str_response_string"] = "No such monitor";
80 ereply2["content_type"] = "text/plain";
81
82 return ereply2;
83 }
84
85 string xml = "<data>";
86 foreach (IMonitor monitor in m_monitors)
87 {
88 xml += "<" + monitor.ToString() + ">" + monitor.GetValue() + "</" + monitor.ToString() + ">";
89 }
90 xml += "</data>";
91
92 Hashtable ereply = new Hashtable();
93
94 ereply["int_response_code"] = 200; // 200 OK
95 ereply["str_response_string"] = xml;
96 ereply["content_type"] = "text/xml";
97
98 return ereply;
46 } 99 }
47 100
48 public void PostInitialise() 101 public void PostInitialise()
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index 8f82718..9757072 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -13,7 +13,6 @@
13 <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" /> 13 <RegionModule id="ArchiverModule" type="OpenSim.Region.CoreModules.World.Archiver.ArchiverModule" />
14 <RegionModule id="CapabilitiesModule" type="OpenSim.Region.CoreModules.Agent.Capabilities.CapabilitiesModule" /> 14 <RegionModule id="CapabilitiesModule" type="OpenSim.Region.CoreModules.Agent.Capabilities.CapabilitiesModule" />
15 <RegionModule id="TerrainModule" type="OpenSim.Region.CoreModules.World.Terrain.TerrainModule" /> 15 <RegionModule id="TerrainModule" type="OpenSim.Region.CoreModules.World.Terrain.TerrainModule" />
16 <RegionModule id="RegionCombinerModule" type="OpenSim.Region.CoreModules.World.Land.RegionCombinerModule" />
17 <RegionModule id="WorldMapModule" type="OpenSim.Region.CoreModules.World.WorldMap.WorldMapModule" /> 16 <RegionModule id="WorldMapModule" type="OpenSim.Region.CoreModules.World.WorldMap.WorldMapModule" />
18 <RegionModule id="HGWorldMapModule" type="OpenSim.Region.CoreModules.Hypergrid.HGWorldMapModule" /> 17 <RegionModule id="HGWorldMapModule" type="OpenSim.Region.CoreModules.Hypergrid.HGWorldMapModule" />
19 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" /> 18 <RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 9a6c49a..43761fc 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -311,11 +311,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
311 } 311 }
312 312
313 // Create a new asset for user 313 // Create a new asset for user
314 AssetBase asset = new AssetBase(); 314 AssetBase asset = new AssetBase(UUID.Random(), "DynamicImage" + Util.RandomClass.Next(1, 10000), (sbyte)AssetType.Texture);
315 asset.FullID = UUID.Random();
316 asset.Data = assetData; 315 asset.Data = assetData;
317 asset.Name = "DynamicImage" + Util.RandomClass.Next(1, 10000);
318 asset.Type = 0;
319 asset.Description = String.Format("URL image : {0}", Url); 316 asset.Description = String.Format("URL image : {0}", Url);
320 asset.Local = false; 317 asset.Local = false;
321 asset.Temporary = ((Disp & DISP_TEMP) != 0); 318 asset.Temporary = ((Disp & DISP_TEMP) != 0);
diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
index 97899a7..27b64bf 100644
--- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs
@@ -689,7 +689,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC
689 } 689 }
690 if (respParms.Contains("IntValue")) 690 if (respParms.Contains("IntValue"))
691 { 691 {
692 Idata = Convert.ToInt32((string) respParms["IntValue"]); 692 Idata = Convert.ToInt32(respParms["IntValue"]);
693 } 693 }
694 if (respParms.Contains("faultString")) 694 if (respParms.Contains("faultString"))
695 { 695 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs
index 92db15b..b12d778 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs
@@ -118,7 +118,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid
118 118
119 m_log.Info("[HypergridService]: Starting..."); 119 m_log.Info("[HypergridService]: Starting...");
120 120
121 Object[] args = new Object[] { m_Config, MainServer.Instance }; 121// Object[] args = new Object[] { m_Config, MainServer.Instance };
122 122
123 m_HypergridHandler = new HypergridServiceInConnector(m_Config, MainServer.Instance, scene.RequestModuleInterface<IHyperlinkService>()); 123 m_HypergridHandler = new HypergridServiceInConnector(m_Config, MainServer.Instance, scene.RequestModuleInterface<IHyperlinkService>());
124 //ServerUtils.LoadPlugin<HypergridServiceInConnector>("OpenSim.Server.Handlers.dll:HypergridServiceInConnector", args); 124 //ServerUtils.LoadPlugin<HypergridServiceInConnector>("OpenSim.Server.Handlers.dll:HypergridServiceInConnector", args);
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
index 40ac647..f2d8579 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Grid/HGGridConnector.cs
@@ -336,7 +336,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
336 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax) 336 public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
337 { 337 {
338 int snapXmin = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize; 338 int snapXmin = (int)(xmin / Constants.RegionSize) * (int)Constants.RegionSize;
339 int snapXmax = (int)(xmax / Constants.RegionSize) * (int)Constants.RegionSize; 339// int snapXmax = (int)(xmax / Constants.RegionSize) * (int)Constants.RegionSize;
340 int snapYmin = (int)(ymin / Constants.RegionSize) * (int)Constants.RegionSize; 340 int snapYmin = (int)(ymin / Constants.RegionSize) * (int)Constants.RegionSize;
341 int snapYmax = (int)(ymax / Constants.RegionSize) * (int)Constants.RegionSize; 341 int snapYmax = (int)(ymax / Constants.RegionSize) * (int)Constants.RegionSize;
342 342
@@ -604,13 +604,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
604 { 604 {
605 CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(agentData.AgentID); 605 CachedUserInfo uinfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(agentData.AgentID);
606 606
607 if (uinfo == null)
608 return false;
609
607 if ((IsLocalUser(uinfo) && (GetHyperlinkRegion(regInfo.RegionHandle) != null)) || 610 if ((IsLocalUser(uinfo) && (GetHyperlinkRegion(regInfo.RegionHandle) != null)) ||
608 (!IsLocalUser(uinfo) && !IsGoingHome(uinfo, regInfo))) 611 (!IsLocalUser(uinfo) && !IsGoingHome(uinfo, regInfo)))
609 { 612 {
610 m_log.Info("[HGrid]: Local user is going to foreign region or foreign user is going elsewhere"); 613 m_log.Info("[HGrid]: Local user is going to foreign region or foreign user is going elsewhere");
611 614
612 // Set the position of the region on the remote grid 615 // Set the position of the region on the remote grid
613 ulong realHandle = FindRegionHandle(regInfo.RegionHandle); 616// ulong realHandle = FindRegionHandle(regInfo.RegionHandle);
614 uint x = 0, y = 0; 617 uint x = 0, y = 0;
615 Utils.LongToUInts(regInfo.RegionHandle, out x, out y); 618 Utils.LongToUInts(regInfo.RegionHandle, out x, out y);
616 GridRegion clonedRegion = new GridRegion(regInfo); 619 GridRegion clonedRegion = new GridRegion(regInfo);
@@ -737,6 +740,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid
737 // Is the user going back to the home region or the home grid? 740 // Is the user going back to the home region or the home grid?
738 protected bool IsGoingHome(CachedUserInfo uinfo, GridRegion rinfo) 741 protected bool IsGoingHome(CachedUserInfo uinfo, GridRegion rinfo)
739 { 742 {
743 if (uinfo == null)
744 return false;
745
740 if (uinfo.UserProfile == null) 746 if (uinfo.UserProfile == null)
741 return false; 747 return false;
742 748
diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
index c261943..70a225e 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs
@@ -332,10 +332,12 @@ namespace OpenSim.Region.CoreModules.World.Archiver
332 { 332 {
333 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; 333 sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
334 334
335 if (assetType == (sbyte)AssetType.Unknown)
336 m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid);
337
335 //m_log.DebugFormat("[ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); 338 //m_log.DebugFormat("[ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType);
336 339
337 AssetBase asset = new AssetBase(new UUID(uuid), String.Empty); 340 AssetBase asset = new AssetBase(new UUID(uuid), String.Empty, assetType);
338 asset.Type = assetType;
339 asset.Data = data; 341 asset.Data = data;
340 342
341 // We're relying on the asset service to do the sensible thing and not store the asset if it already 343 // We're relying on the asset service to do the sensible thing and not store the asset if it already
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs
index 5208e7a..2d2c570 100644
--- a/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs
+++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsDearchiver.cs
@@ -158,9 +158,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
158 158
159 m_log.DebugFormat("[ARCHIVER]: Importing asset {0}", filename); 159 m_log.DebugFormat("[ARCHIVER]: Importing asset {0}", filename);
160 160
161 AssetBase asset = new AssetBase(new UUID(filename), metadata.Name); 161 AssetBase asset = new AssetBase(new UUID(filename), metadata.Name, metadata.AssetType);
162 asset.Description = metadata.Description; 162 asset.Description = metadata.Description;
163 asset.Type = metadata.AssetType;
164 asset.Data = data; 163 asset.Data = data;
165 164
166 m_cache.Store(asset); 165 m_cache.Store(asset);
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs
index ddac515..2ff635b 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs
@@ -52,16 +52,11 @@ namespace OpenSim.Region.CoreModules.World.Estate
52 52
53 public EstateTerrainXferHandler(IClientAPI pRemoteClient, string pClientFilename) 53 public EstateTerrainXferHandler(IClientAPI pRemoteClient, string pClientFilename)
54 { 54 {
55 55 m_asset = new AssetBase(UUID.Zero, pClientFilename, type);
56 m_asset = new AssetBase();
57 m_asset.FullID = UUID.Zero;
58 m_asset.Type = type;
59 m_asset.Data = new byte[0]; 56 m_asset.Data = new byte[0];
60 m_asset.Name = pClientFilename;
61 m_asset.Description = "empty"; 57 m_asset.Description = "empty";
62 m_asset.Local = true; 58 m_asset.Local = true;
63 m_asset.Temporary = true; 59 m_asset.Temporary = true;
64
65 } 60 }
66 61
67 public ulong XferID 62 public ulong XferID
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 93a949a..968f46a 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -1059,9 +1059,11 @@ namespace OpenSim.Region.CoreModules.World.Land
1059 if (m_scene.Permissions.IsGod(remote_client.AgentId)) 1059 if (m_scene.Permissions.IsGod(remote_client.AgentId))
1060 { 1060 {
1061 land.LandData.OwnerID = ownerID; 1061 land.LandData.OwnerID = ownerID;
1062 land.LandData.GroupID = UUID.Zero;
1063 land.LandData.IsGroupOwned = false;
1062 1064
1063 m_scene.ForEachClient(SendParcelOverlay); 1065 m_scene.ForEachClient(SendParcelOverlay);
1064 land.SendLandUpdateToClient(remote_client); 1066 land.SendLandUpdateToClient(true, remote_client);
1065 } 1067 }
1066 } 1068 }
1067 } 1069 }
@@ -1082,8 +1084,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1082 land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 1084 land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
1083 else 1085 else
1084 land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; 1086 land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
1087 land.LandData.GroupID = UUID.Zero;
1088 land.LandData.IsGroupOwned = false;
1085 m_scene.ForEachClient(SendParcelOverlay); 1089 m_scene.ForEachClient(SendParcelOverlay);
1086 land.SendLandUpdateToClient(remote_client); 1090 land.SendLandUpdateToClient(true, remote_client);
1087 } 1091 }
1088 } 1092 }
1089 } 1093 }
@@ -1105,9 +1109,10 @@ namespace OpenSim.Region.CoreModules.World.Land
1105 else 1109 else
1106 land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; 1110 land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
1107 land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); 1111 land.LandData.ClaimDate = Util.UnixTimeSinceEpoch();
1112 land.LandData.GroupID = UUID.Zero;
1108 land.LandData.IsGroupOwned = false; 1113 land.LandData.IsGroupOwned = false;
1109 m_scene.ForEachClient(SendParcelOverlay); 1114 m_scene.ForEachClient(SendParcelOverlay);
1110 land.SendLandUpdateToClient(remote_client); 1115 land.SendLandUpdateToClient(true, remote_client);
1111 } 1116 }
1112 } 1117 }
1113 } 1118 }
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
index bfe85f1..0bd225e 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.World.Land
49 #pragma warning restore 0429 49 #pragma warning restore 0429
50 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; 50 private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax];
51 51
52 private int m_lastSeqId = 0;
53
52 protected LandData m_landData = new LandData(); 54 protected LandData m_landData = new LandData();
53 protected Scene m_scene; 55 protected Scene m_scene;
54 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>(); 56 protected List<SceneObjectGroup> primsOverMe = new List<SceneObjectGroup>();
@@ -81,6 +83,10 @@ namespace OpenSim.Region.CoreModules.World.Land
81 { 83 {
82 m_scene = scene; 84 m_scene = scene;
83 LandData.OwnerID = owner_id; 85 LandData.OwnerID = owner_id;
86 if (is_group_owned)
87 LandData.GroupID = owner_id;
88 else
89 LandData.GroupID = UUID.Zero;
84 LandData.IsGroupOwned = is_group_owned; 90 LandData.IsGroupOwned = is_group_owned;
85 } 91 }
86 92
@@ -172,7 +178,19 @@ namespace OpenSim.Region.CoreModules.World.Land
172// regionFlags |= (uint)RegionFlags.AllowLandmark; 178// regionFlags |= (uint)RegionFlags.AllowLandmark;
173// if (landData.OwnerID == remote_client.AgentId) 179// if (landData.OwnerID == remote_client.AgentId)
174// regionFlags |= (uint)RegionFlags.AllowSetHome; 180// regionFlags |= (uint)RegionFlags.AllowSetHome;
175 remote_client.SendLandProperties(sequence_id, 181
182 int seq_id;
183 if (snap_selection && (sequence_id == 0))
184 {
185 seq_id = m_lastSeqId;
186 }
187 else
188 {
189 seq_id = sequence_id;
190 m_lastSeqId = seq_id;
191 }
192
193 remote_client.SendLandProperties(seq_id,
176 snap_selection, request_result, LandData, 194 snap_selection, request_result, LandData,
177 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, 195 (float)m_scene.RegionInfo.RegionSettings.ObjectBonus,
178 GetParcelMaxPrimCount(this), 196 GetParcelMaxPrimCount(this),
@@ -184,6 +202,7 @@ namespace OpenSim.Region.CoreModules.World.Land
184 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) 202 if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this))
185 { 203 {
186 //Needs later group support 204 //Needs later group support
205 bool snap_selection = false;
187 LandData newData = LandData.Copy(); 206 LandData newData = LandData.Copy();
188 207
189 if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) 208 if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice)
@@ -192,6 +211,7 @@ namespace OpenSim.Region.CoreModules.World.Land
192 { 211 {
193 newData.AuthBuyerID = args.AuthBuyerID; 212 newData.AuthBuyerID = args.AuthBuyerID;
194 newData.SalePrice = args.SalePrice; 213 newData.SalePrice = args.SalePrice;
214 snap_selection = true;
195 } 215 }
196 } 216 }
197 newData.Category = args.Category; 217 newData.Category = args.Category;
@@ -212,7 +232,7 @@ namespace OpenSim.Region.CoreModules.World.Land
212 232
213 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 233 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
214 234
215 SendLandUpdateToAvatarsOverMe(); 235 SendLandUpdateToAvatarsOverMe(snap_selection);
216 } 236 }
217 } 237 }
218 238
@@ -230,7 +250,7 @@ namespace OpenSim.Region.CoreModules.World.Land
230 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects); 250 newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects);
231 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 251 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
232 252
233 SendLandUpdateToAvatarsOverMe(); 253 SendLandUpdateToAvatarsOverMe(true);
234 } 254 }
235 255
236 public void DeedToGroup(UUID groupID) 256 public void DeedToGroup(UUID groupID)
@@ -242,7 +262,7 @@ namespace OpenSim.Region.CoreModules.World.Land
242 262
243 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); 263 m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData);
244 264
245 SendLandUpdateToAvatarsOverMe(); 265 SendLandUpdateToAvatarsOverMe(true);
246 } 266 }
247 267
248 public bool IsEitherBannedOrRestricted(UUID avatar) 268 public bool IsEitherBannedOrRestricted(UUID avatar)
@@ -297,8 +317,18 @@ namespace OpenSim.Region.CoreModules.World.Land
297 SendLandProperties(0, false, 0, remote_client); 317 SendLandProperties(0, false, 0, remote_client);
298 } 318 }
299 319
320 public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client)
321 {
322 SendLandProperties(0, snap_selection, 0, remote_client);
323 }
324
300 public void SendLandUpdateToAvatarsOverMe() 325 public void SendLandUpdateToAvatarsOverMe()
301 { 326 {
327 SendLandUpdateToAvatarsOverMe(false);
328 }
329
330 public void SendLandUpdateToAvatarsOverMe(bool snap_selection)
331 {
302 List<ScenePresence> avatars = m_scene.GetAvatars(); 332 List<ScenePresence> avatars = m_scene.GetAvatars();
303 ILandObject over = null; 333 ILandObject over = null;
304 for (int i = 0; i < avatars.Count; i++) 334 for (int i = 0; i < avatars.Count; i++)
@@ -325,7 +355,7 @@ namespace OpenSim.Region.CoreModules.World.Land
325 else 355 else
326 avatars[i].Invulnerable = true; 356 avatars[i].Invulnerable = true;
327 357
328 SendLandUpdateToClient(avatars[i].ControllingClient); 358 SendLandUpdateToClient(snap_selection, avatars[i].ControllingClient);
329 } 359 }
330 } 360 }
331 } 361 }
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index fe9de1b..c790624 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -144,6 +144,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
144 private Dictionary<string, bool> GrantVB = new Dictionary<string, bool>(); 144 private Dictionary<string, bool> GrantVB = new Dictionary<string, bool>();
145 private Dictionary<string, bool> GrantJS = new Dictionary<string, bool>(); 145 private Dictionary<string, bool> GrantJS = new Dictionary<string, bool>();
146 private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>(); 146 private Dictionary<string, bool> GrantYP = new Dictionary<string, bool>();
147 private IFriendsModule m_friendsModule = null;
148
147 #endregion 149 #endregion
148 150
149 #region IRegionModule Members 151 #region IRegionModule Members
@@ -363,6 +365,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions
363 365
364 public void PostInitialise() 366 public void PostInitialise()
365 { 367 {
368 m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
369
370 if (m_friendsModule == null)
371 m_log.Error("[PERMISSIONS]: Friends module not found, friend permissions will not work");
372 else
373 m_log.Info("[PERMISSIONS]: Friends module found, friend permissions enabled");
366 } 374 }
367 375
368 public void Close() 376 public void Close()
@@ -476,6 +484,24 @@ namespace OpenSim.Region.CoreModules.World.Permissions
476 484
477 return false; 485 return false;
478 } 486 }
487 protected bool IsFriendWithPerms(UUID user,UUID objectOwner)
488 {
489
490 if (user == UUID.Zero)
491 return false;
492
493 if (m_friendsModule == null)
494 return false;
495
496 List<FriendListItem> profile = m_friendsModule.GetUserFriends(user);
497
498 foreach (FriendListItem item in profile)
499 {
500 if(item.Friend == objectOwner && (item.FriendPerms & (uint)FriendRights.CanModifyObjects) != 0)
501 return true;
502 }
503 return false;
504 }
479 505
480 protected bool IsEstateManager(UUID user) 506 protected bool IsEstateManager(UUID user)
481 { 507 {
@@ -565,6 +591,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions
565 // Object owners should be able to edit their own content 591 // Object owners should be able to edit their own content
566 if (user == objectOwner) 592 if (user == objectOwner)
567 return objectOwnerMask; 593 return objectOwnerMask;
594
595 if (IsFriendWithPerms(user, objectOwner))
596 return objectOwnerMask;
568 597
569 // Estate users should be able to edit anything in the sim 598 // Estate users should be able to edit anything in the sim
570 if (IsEstateManager(user) && m_RegionOwnerIsGod && !IsAdministrator(objectOwner)) 599 if (IsEstateManager(user) && m_RegionOwnerIsGod && !IsAdministrator(objectOwner))
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index f4b54aa..44a651f 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -1077,14 +1077,12 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1077 1077
1078 m_scene.RegionInfo.RegionSettings.TerrainImageID = TerrainImageUUID; 1078 m_scene.RegionInfo.RegionSettings.TerrainImageID = TerrainImageUUID;
1079 1079
1080 AssetBase asset = new AssetBase(); 1080 AssetBase asset = new AssetBase(
1081 asset.FullID = m_scene.RegionInfo.RegionSettings.TerrainImageID; 1081 m_scene.RegionInfo.RegionSettings.TerrainImageID,
1082 "terrainImage_" + m_scene.RegionInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString(),
1083 (sbyte)AssetType.Texture);
1082 asset.Data = data; 1084 asset.Data = data;
1083 asset.Name
1084 = "terrainImage_" + m_scene.RegionInfo.RegionID.ToString() + "_" + lastMapRefresh.ToString();
1085 asset.Description = m_scene.RegionInfo.RegionName; 1085 asset.Description = m_scene.RegionInfo.RegionName;
1086
1087 asset.Type = 0;
1088 asset.Temporary = temporary; 1086 asset.Temporary = temporary;
1089 m_scene.AssetService.Store(asset); 1087 m_scene.AssetService.Store(asset);
1090 } 1088 }
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 5a5fcfe..9754da3 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -179,6 +179,7 @@ namespace OpenSim.Region.Examples.SimpleModule
179 public event FriendActionDelegate OnApproveFriendRequest; 179 public event FriendActionDelegate OnApproveFriendRequest;
180 public event FriendActionDelegate OnDenyFriendRequest; 180 public event FriendActionDelegate OnDenyFriendRequest;
181 public event FriendshipTermination OnTerminateFriendship; 181 public event FriendshipTermination OnTerminateFriendship;
182 public event GrantUserFriendRights OnGrantUserRights;
182 183
183 public event EconomyDataRequest OnEconomyDataRequest; 184 public event EconomyDataRequest OnEconomyDataRequest;
184 public event MoneyBalanceRequest OnMoneyBalanceRequest; 185 public event MoneyBalanceRequest OnMoneyBalanceRequest;
@@ -538,6 +539,7 @@ namespace OpenSim.Region.Examples.SimpleModule
538 public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID, 539 public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID,
539 List<InventoryItemBase> items, 540 List<InventoryItemBase> items,
540 List<InventoryFolderBase> folders, 541 List<InventoryFolderBase> folders,
542 int version,
541 bool fetchFolders, 543 bool fetchFolders,
542 bool fetchItems) 544 bool fetchItems)
543 { 545 {
diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
index 7a8aba2..8386030 100644
--- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
@@ -27,6 +27,7 @@
27 27
28using OpenMetaverse; 28using OpenMetaverse;
29using OpenSim.Framework; 29using OpenSim.Framework;
30using System.Collections.Generic;
30 31
31namespace OpenSim.Region.Framework.Interfaces 32namespace OpenSim.Region.Framework.Interfaces
32{ 33{
@@ -45,5 +46,6 @@ namespace OpenSim.Region.Framework.Interfaces
45 /// </param> 46 /// </param>
46 /// <param name="offerMessage"></param> 47 /// <param name="offerMessage"></param>
47 void OfferFriendship(UUID fromUserId, IClientAPI toUserClient, string offerMessage); 48 void OfferFriendship(UUID fromUserId, IClientAPI toUserClient, string offerMessage);
49 List<FriendListItem> GetUserFriends(UUID agentID);
48 } 50 }
49} 51}
diff --git a/OpenSim/Region/Framework/Interfaces/ILandObject.cs b/OpenSim/Region/Framework/Interfaces/ILandObject.cs
index c2b1292..084184f 100644
--- a/OpenSim/Region/Framework/Interfaces/ILandObject.cs
+++ b/OpenSim/Region/Framework/Interfaces/ILandObject.cs
@@ -54,6 +54,7 @@ namespace OpenSim.Region.Framework.Interfaces
54 bool IsBannedFromLand(UUID avatar); 54 bool IsBannedFromLand(UUID avatar);
55 bool IsRestrictedFromLand(UUID avatar); 55 bool IsRestrictedFromLand(UUID avatar);
56 void SendLandUpdateToClient(IClientAPI remote_client); 56 void SendLandUpdateToClient(IClientAPI remote_client);
57 void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client);
57 List<UUID> CreateAccessListArrayByFlag(AccessList flag); 58 List<UUID> CreateAccessListArrayByFlag(AccessList flag);
58 void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, IClientAPI remote_client); 59 void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, IClientAPI remote_client);
59 void UpdateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client); 60 void UpdateAccessList(uint flags, List<ParcelManager.ParcelAccessEntry> entries, IClientAPI remote_client);
diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
new file mode 100644
index 0000000..5cdf191
--- /dev/null
+++ b/OpenSim/Region/Framework/Interfaces/IScriptModuleComms.cs
@@ -0,0 +1,44 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenMetaverse;
30
31namespace OpenSim.Region.Framework.Interfaces
32{
33 public delegate void ScriptCommand(UUID script, string id, string module, string command, string k);
34
35 public interface IScriptModuleComms
36 {
37 event ScriptCommand OnScriptCommand;
38
39 void DispatchReply(UUID script, int code, string text, string k);
40
41 // For use ONLY by the script API
42 void RaiseEvent(UUID script, string id, string module, string command, string k);
43 }
44}
diff --git a/OpenSim/Region/Framework/Scenes/EntityBase.cs b/OpenSim/Region/Framework/Scenes/EntityBase.cs
index c2ec6a5..1c76c54 100644
--- a/OpenSim/Region/Framework/Scenes/EntityBase.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityBase.cs
@@ -94,14 +94,6 @@ namespace OpenSim.Region.Framework.Scenes
94 set { m_velocity = value; } 94 set { m_velocity = value; }
95 } 95 }
96 96
97 protected Quaternion m_rotation = new Quaternion(0f, 0f, 1f, 0f);
98
99 public virtual Quaternion Rotation
100 {
101 get { return m_rotation; }
102 set { m_rotation = value; }
103 }
104
105 protected uint m_localId; 97 protected uint m_localId;
106 98
107 public virtual uint LocalId 99 public virtual uint LocalId
@@ -115,13 +107,7 @@ namespace OpenSim.Region.Framework.Scenes
115 /// </summary> 107 /// </summary>
116 public EntityBase() 108 public EntityBase()
117 { 109 {
118 m_uuid = UUID.Zero;
119
120 m_pos = Vector3.Zero;
121 m_velocity = Vector3.Zero;
122 Rotation = Quaternion.Identity;
123 m_name = "(basic entity)"; 110 m_name = "(basic entity)";
124 m_rotationalvelocity = Vector3.Zero;
125 } 111 }
126 112
127 /// <summary> 113 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
index 244ac3b..ec50598 100644
--- a/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
+++ b/OpenSim/Region/Framework/Scenes/Hypergrid/HGAssetMapper.cs
@@ -77,13 +77,13 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid
77 77
78 #region Internal functions 78 #region Internal functions
79 79
80 private string UserAssetURL(UUID userID) 80// private string UserAssetURL(UUID userID)
81 { 81// {
82 CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID); 82// CachedUserInfo uinfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(userID);
83 if (uinfo != null) 83// if (uinfo != null)
84 return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI; 84// return (uinfo.UserProfile.UserAssetURI == "") ? null : uinfo.UserProfile.UserAssetURI;
85 return null; 85// return null;
86 } 86// }
87 87
88// private string UserInventoryURL(UUID userID) 88// private string UserInventoryURL(UUID userID)
89// { 89// {
@@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes.Hypergrid
118 // HGAssetService dispatches it to the remote grid. 118 // HGAssetService dispatches it to the remote grid.
119 // It's not pretty, but the best that can be done while 119 // It's not pretty, but the best that can be done while
120 // not having a global naming infrastructure 120 // not having a global naming infrastructure
121 AssetBase asset1 = new AssetBase(); 121 AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type);
122 Copy(asset, asset1); 122 Copy(asset, asset1);
123 try 123 try
124 { 124 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 4d76b4ef..66fb918 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.Framework.Scenes
93 93
94 public void AddInventoryItem(UUID AgentID, InventoryItemBase item) 94 public void AddInventoryItem(UUID AgentID, InventoryItemBase item)
95 { 95 {
96
97 if (InventoryService.AddItem(item)) 96 if (InventoryService.AddItem(item))
98 { 97 {
99 int userlevel = 0; 98 int userlevel = 0;
@@ -627,11 +626,8 @@ namespace OpenSim.Region.Framework.Scenes
627 /// <returns></returns> 626 /// <returns></returns>
628 private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data) 627 private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data)
629 { 628 {
630 AssetBase asset = new AssetBase(); 629 AssetBase asset = new AssetBase(UUID.Random(), name, assetType);
631 asset.Name = name;
632 asset.Description = description; 630 asset.Description = description;
633 asset.Type = assetType;
634 asset.FullID = UUID.Random();
635 asset.Data = (data == null) ? new byte[1] : data; 631 asset.Data = (data == null) ? new byte[1] : data;
636 632
637 return asset; 633 return asset;
@@ -807,20 +803,6 @@ namespace OpenSim.Region.Framework.Scenes
807 InventoryService.DeleteFolders(remoteClient.AgentId, folderIDs); 803 InventoryService.DeleteFolders(remoteClient.AgentId, folderIDs);
808 } 804 }
809 805
810 private SceneObjectGroup GetGroupByPrim(uint localID)
811 {
812 List<EntityBase> EntityList = GetEntities();
813
814 foreach (EntityBase ent in EntityList)
815 {
816 if (ent is SceneObjectGroup)
817 {
818 if (((SceneObjectGroup) ent).HasChildPrim(localID))
819 return (SceneObjectGroup) ent;
820 }
821 }
822 return null;
823 }
824 806
825 /// <summary> 807 /// <summary>
826 /// Send the details of a prim's inventory to the client. 808 /// Send the details of a prim's inventory to the client.
@@ -1175,7 +1157,13 @@ namespace OpenSim.Region.Framework.Scenes
1175 { 1157 {
1176 m_log.DebugFormat("[AGENT INVENTORY]: Send Inventory Folder {0} Update to {1} {2}", folder.Name, client.FirstName, client.LastName); 1158 m_log.DebugFormat("[AGENT INVENTORY]: Send Inventory Folder {0} Update to {1} {2}", folder.Name, client.FirstName, client.LastName);
1177 InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID); 1159 InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID);
1178 client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, fetchFolders, fetchItems); 1160 InventoryFolderBase containingFolder = new InventoryFolderBase();
1161 containingFolder.ID = folder.ID;
1162 containingFolder.Owner = client.AgentId;
1163 containingFolder = InventoryService.GetFolder(containingFolder);
1164 int version = containingFolder.Version;
1165
1166 client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, version, fetchFolders, fetchItems);
1179 } 1167 }
1180 1168
1181 /// <summary> 1169 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
index 1a91f0c..47fbeb4 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs
@@ -462,7 +462,7 @@ namespace OpenSim.Region.Framework.Scenes
462 { 462 {
463 remoteClient.SendInventoryFolderDetails( 463 remoteClient.SendInventoryFolderDetails(
464 fold.Owner, folderID, fold.RequestListOfItems(), 464 fold.Owner, folderID, fold.RequestListOfItems(),
465 fold.RequestListOfFolders(), fetchFolders, fetchItems); 465 fold.RequestListOfFolders(), fold.Version, fetchFolders, fetchItems);
466 return; 466 return;
467 } 467 }
468 468
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a6ee40a..aeca7df 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -36,6 +36,7 @@ using System.Timers;
36using System.Xml; 36using System.Xml;
37using Nini.Config; 37using Nini.Config;
38using OpenMetaverse; 38using OpenMetaverse;
39using OpenMetaverse.Packets;
39using OpenMetaverse.Imaging; 40using OpenMetaverse.Imaging;
40using OpenSim.Framework; 41using OpenSim.Framework;
41using OpenSim.Services.Interfaces; 42using OpenSim.Services.Interfaces;
@@ -87,8 +88,18 @@ namespace OpenSim.Region.Framework.Scenes
87 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 88 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
88 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 89 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
89 90
90 public volatile bool BordersLocked = false; 91 private volatile int m_bordersLocked = 0;
91 92 public bool BordersLocked
93 {
94 get { return m_bordersLocked == 1; }
95 set
96 {
97 if (value == true)
98 m_bordersLocked = 1;
99 else
100 m_bordersLocked = 0;
101 }
102 }
92 public List<Border> NorthBorders = new List<Border>(); 103 public List<Border> NorthBorders = new List<Border>();
93 public List<Border> EastBorders = new List<Border>(); 104 public List<Border> EastBorders = new List<Border>();
94 public List<Border> SouthBorders = new List<Border>(); 105 public List<Border> SouthBorders = new List<Border>();
@@ -397,6 +408,73 @@ namespace OpenSim.Region.Framework.Scenes
397 408
398 #endregion 409 #endregion
399 410
411 #region BinaryStats
412
413 public class StatLogger
414 {
415 public DateTime StartTime;
416 public string Path;
417 public System.IO.BinaryWriter Log;
418 }
419 static StatLogger m_statLog = null;
420 static TimeSpan m_statLogPeriod = TimeSpan.FromSeconds(300);
421 static string m_statsDir = String.Empty;
422 static Object m_statLockObject = new Object();
423 private void LogSimStats(SimStats stats)
424 {
425 SimStatsPacket pack = new SimStatsPacket();
426 pack.Region = new SimStatsPacket.RegionBlock();
427 pack.Region.RegionX = stats.RegionX;
428 pack.Region.RegionY = stats.RegionY;
429 pack.Region.RegionFlags = stats.RegionFlags;
430 pack.Region.ObjectCapacity = stats.ObjectCapacity;
431 //pack.Region = //stats.RegionBlock;
432 pack.Stat = stats.StatsBlock;
433 pack.Header.Reliable = false;
434
435 // note that we are inside the reporter lock when called
436 DateTime now = DateTime.Now;
437
438 // hide some time information into the packet
439 pack.Header.Sequence = (uint)now.Ticks;
440
441 lock (m_statLockObject) // m_statLog is shared so make sure there is only executer here
442 {
443 try
444 {
445 if (m_statLog == null || now > m_statLog.StartTime + m_statLogPeriod)
446 {
447 // First log file or time has expired, start writing to a new log file
448 if (m_statLog != null && m_statLog.Log != null)
449 {
450 m_statLog.Log.Close();
451 }
452 m_statLog = new StatLogger();
453 m_statLog.StartTime = now;
454 m_statLog.Path = (m_statsDir.Length > 0 ? m_statsDir + System.IO.Path.DirectorySeparatorChar.ToString() : "")
455 + String.Format("stats-{0}.log", now.ToString("yyyyMMddHHmmss"));
456 m_statLog.Log = new BinaryWriter(File.Open(m_statLog.Path, FileMode.Append, FileAccess.Write));
457 }
458
459 // Write the serialized data to disk
460 if (m_statLog != null && m_statLog.Log != null)
461 m_statLog.Log.Write(pack.ToBytes());
462 }
463 catch (Exception ex)
464 {
465 m_log.Error("statistics gathering failed: " + ex.Message, ex);
466 if (m_statLog != null && m_statLog.Log != null)
467 {
468 m_statLog.Log.Close();
469 }
470 m_statLog = null;
471 }
472 }
473 return;
474 }
475
476 #endregion
477
400 #region Constructors 478 #region Constructors
401 479
402 public Scene(RegionInfo regInfo, AgentCircuitManager authen, 480 public Scene(RegionInfo regInfo, AgentCircuitManager authen,
@@ -582,6 +660,38 @@ namespace OpenSim.Region.Framework.Scenes
582 } 660 }
583 661
584 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); 662 m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme");
663
664 #region BinaryStats
665
666 try
667 {
668 IConfig statConfig = m_config.Configs["Statistics.Binary"];
669 if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled"))
670 {
671 if (statConfig.Contains("collect_region_stats"))
672 {
673 if (statConfig.GetBoolean("collect_region_stats"))
674 {
675 // if enabled, add us to the event. If not enabled, I won't get called
676 StatsReporter.OnSendStatsResult += LogSimStats;
677 }
678 }
679 if (statConfig.Contains("region_stats_period_seconds"))
680 {
681 m_statLogPeriod = TimeSpan.FromSeconds(statConfig.GetInt("region_stats_period_seconds"));
682 }
683 if (statConfig.Contains("stats_dir"))
684 {
685 m_statsDir = statConfig.GetString("stats_dir");
686 }
687 }
688 }
689 catch
690 {
691 // if it doesn't work, we don't collect anything
692 }
693
694 #endregion BinaryStats
585 } 695 }
586 catch 696 catch
587 { 697 {
@@ -1043,7 +1153,7 @@ namespace OpenSim.Region.Framework.Scenes
1043 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; 1153 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
1044 physicsFPS = 0f; 1154 physicsFPS = 0f;
1045 1155
1046 maintc = maintc = otherMS = Environment.TickCount; 1156 maintc = otherMS = Environment.TickCount;
1047 int tmpFrameMS = maintc; 1157 int tmpFrameMS = maintc;
1048 1158
1049 // Increment the frame counter 1159 // Increment the frame counter
@@ -4273,6 +4383,16 @@ namespace OpenSim.Region.Framework.Scenes
4273 return m_sceneGraph.GetSceneObjectPart(fullID); 4383 return m_sceneGraph.GetSceneObjectPart(fullID);
4274 } 4384 }
4275 4385
4386 /// <summary>
4387 /// Get a scene object group that contains the prim with the given local id
4388 /// </summary>
4389 /// <param name="localID"></param>
4390 /// <returns>null if no scene object group containing that prim is found</returns>
4391 public SceneObjectGroup GetGroupByPrim(uint localID)
4392 {
4393 return m_sceneGraph.GetGroupByPrim(localID);
4394 }
4395
4276 public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) 4396 public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar)
4277 { 4397 {
4278 return m_sceneGraph.TryGetAvatar(avatarId, out avatar); 4398 return m_sceneGraph.TryGetAvatar(avatarId, out avatar);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 0b752c9..bcc9b37 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -204,6 +204,14 @@ namespace OpenSim.Region.Framework.Scenes
204 get { return m_parts.Count; } 204 get { return m_parts.Count; }
205 } 205 }
206 206
207 protected Quaternion m_rotation = Quaternion.Identity;
208
209 public virtual Quaternion Rotation
210 {
211 get { return m_rotation; }
212 set { m_rotation = value; }
213 }
214
207 public Quaternion GroupRotation 215 public Quaternion GroupRotation
208 { 216 {
209 get { return m_rootPart.RotationOffset; } 217 get { return m_rootPart.RotationOffset; }
@@ -1959,12 +1967,12 @@ namespace OpenSim.Region.Framework.Scenes
1959 /// Note: this may not be cused by opensim (it probably should) but it's used by 1967 /// Note: this may not be cused by opensim (it probably should) but it's used by
1960 /// external modules. 1968 /// external modules.
1961 /// </summary> 1969 /// </summary>
1962 public void SendGroupRootUpdate() 1970 public void SendGroupRootTerseUpdate()
1963 { 1971 {
1964 if (IsDeleted) 1972 if (IsDeleted)
1965 return; 1973 return;
1966 1974
1967 RootPart.SendFullUpdateToAllClients(); 1975 RootPart.SendTerseUpdateToAllClients();
1968 } 1976 }
1969 1977
1970 public void QueueForUpdateCheck() 1978 public void QueueForUpdateCheck()
@@ -2946,12 +2954,13 @@ namespace OpenSim.Region.Framework.Scenes
2946 /// <param name="rot"></param> 2954 /// <param name="rot"></param>
2947 public void UpdateGroupRotationR(Quaternion rot) 2955 public void UpdateGroupRotationR(Quaternion rot)
2948 { 2956 {
2949
2950 m_rootPart.UpdateRotation(rot); 2957 m_rootPart.UpdateRotation(rot);
2951 if (m_rootPart.PhysActor != null) 2958
2959 PhysicsActor actor = m_rootPart.PhysActor;
2960 if (actor != null)
2952 { 2961 {
2953 m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; 2962 actor.Orientation = m_rootPart.RotationOffset;
2954 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 2963 m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
2955 } 2964 }
2956 2965
2957 HasGroupChanged = true; 2966 HasGroupChanged = true;
@@ -2966,11 +2975,14 @@ namespace OpenSim.Region.Framework.Scenes
2966 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) 2975 public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot)
2967 { 2976 {
2968 m_rootPart.UpdateRotation(rot); 2977 m_rootPart.UpdateRotation(rot);
2969 if (m_rootPart.PhysActor != null) 2978
2979 PhysicsActor actor = m_rootPart.PhysActor;
2980 if (actor != null)
2970 { 2981 {
2971 m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; 2982 actor.Orientation = m_rootPart.RotationOffset;
2972 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 2983 m_scene.PhysicsScene.AddPhysicsActorTaint(actor);
2973 } 2984 }
2985
2974 AbsolutePosition = pos; 2986 AbsolutePosition = pos;
2975 2987
2976 HasGroupChanged = true; 2988 HasGroupChanged = true;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 2bc7f66..73d0984 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -243,7 +243,7 @@ namespace OpenSim.Region.Framework.Scenes
243 protected SceneObjectGroup m_parentGroup; 243 protected SceneObjectGroup m_parentGroup;
244 protected byte[] m_particleSystem = Utils.EmptyBytes; 244 protected byte[] m_particleSystem = Utils.EmptyBytes;
245 protected ulong m_regionHandle; 245 protected ulong m_regionHandle;
246 protected Quaternion m_rotationOffset; 246 protected Quaternion m_rotationOffset = Quaternion.Identity;
247 protected PrimitiveBaseShape m_shape; 247 protected PrimitiveBaseShape m_shape;
248 protected UUID m_uuid; 248 protected UUID m_uuid;
249 protected Vector3 m_velocity; 249 protected Vector3 m_velocity;
@@ -3758,14 +3758,12 @@ namespace OpenSim.Region.Framework.Scenes
3758 3758
3759 Vector3 lPos = OffsetPosition; 3759 Vector3 lPos = OffsetPosition;
3760 3760
3761 byte state = Shape.State;
3762 if (IsAttachment) 3761 if (IsAttachment)
3763 { 3762 {
3764 if (ParentGroup.RootPart != this) 3763 if (ParentGroup.RootPart != this)
3765 return; 3764 return;
3766 3765
3767 lPos = ParentGroup.RootPart.AttachedPos; 3766 lPos = ParentGroup.RootPart.AttachedPos;
3768 state = (byte)AttachmentPoint;
3769 } 3767 }
3770 else 3768 else
3771 { 3769 {
@@ -3778,7 +3776,7 @@ namespace OpenSim.Region.Framework.Scenes
3778 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, 3776 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle,
3779 m_parentGroup.GetTimeDilation(), LocalId, lPos, 3777 m_parentGroup.GetTimeDilation(), LocalId, lPos,
3780 RotationOffset, Velocity, Acceleration, 3778 RotationOffset, Velocity, Acceleration,
3781 AngularVelocity, state, FromItemID, 3779 AngularVelocity, FromItemID,
3782 OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); 3780 OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient)));
3783 } 3781 }
3784 3782
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 6c0d9f2..08c144a 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes
76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 76 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
77 77
78 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; 78 private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 };
79 private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); 79// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes();
80 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); 80 private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags));
81 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); 81 private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f);
82 /// <summary> 82 /// <summary>
@@ -181,7 +181,7 @@ namespace OpenSim.Region.Framework.Scenes
181 private byte m_state; 181 private byte m_state;
182 182
183 //Reuse the Vector3 instead of creating a new one on the UpdateMovement method 183 //Reuse the Vector3 instead of creating a new one on the UpdateMovement method
184 private Vector3 movementvector; 184// private Vector3 movementvector;
185 185
186 private bool m_autopilotMoving; 186 private bool m_autopilotMoving;
187 private Vector3 m_autoPilotTarget; 187 private Vector3 m_autoPilotTarget;
@@ -481,6 +481,12 @@ namespace OpenSim.Region.Framework.Scenes
481 } 481 }
482 } 482 }
483 483
484 public Quaternion Rotation
485 {
486 get { return m_bodyRot; }
487 set { m_bodyRot = value; }
488 }
489
484 /// <summary> 490 /// <summary>
485 /// If this is true, agent doesn't have a representation in this scene. 491 /// If this is true, agent doesn't have a representation in this scene.
486 /// this is an agent 'looking into' this scene from a nearby scene(region) 492 /// this is an agent 'looking into' this scene from a nearby scene(region)
@@ -1912,14 +1918,10 @@ namespace OpenSim.Region.Framework.Scenes
1912 } 1918 }
1913 1919
1914 1920
1915 AssetBase Animasset = new AssetBase(); 1921 AssetBase Animasset = new AssetBase(UUID.Random(), "Random Animation", (sbyte)AssetType.Animation);
1916 Animasset.Data = anim.ToBytes(); 1922 Animasset.Data = anim.ToBytes();
1917 Animasset.Temporary = true; 1923 Animasset.Temporary = true;
1918 Animasset.Local = true; 1924 Animasset.Local = true;
1919 Animasset.FullID = UUID.Random();
1920 Animasset.ID = Animasset.FullID.ToString();
1921 Animasset.Name = "Random Animation";
1922 Animasset.Type = (sbyte)AssetType.Animation;
1923 Animasset.Description = "dance"; 1925 Animasset.Description = "dance";
1924 //BinBVHAnimation bbvhanim = new BinBVHAnimation(Animasset.Data); 1926 //BinBVHAnimation bbvhanim = new BinBVHAnimation(Animasset.Data);
1925 1927
@@ -2068,7 +2070,7 @@ namespace OpenSim.Region.Framework.Scenes
2068 if (heldDown) { move.Z -= 1; } 2070 if (heldDown) { move.Z -= 1; }
2069 2071
2070 // Is the avatar trying to move? 2072 // Is the avatar trying to move?
2071 bool moving = (move != Vector3.Zero); 2073// bool moving = (move != Vector3.Zero);
2072 bool jumping = m_animTickJump != 0; 2074 bool jumping = m_animTickJump != 0;
2073 2075
2074 #endregion Inputs 2076 #endregion Inputs
@@ -2256,7 +2258,7 @@ namespace OpenSim.Region.Framework.Scenes
2256 2258
2257 m_perfMonMS = Environment.TickCount; 2259 m_perfMonMS = Environment.TickCount;
2258 2260
2259 m_rotation = rotation; 2261 Rotation = rotation;
2260 Vector3 direc = vec * rotation; 2262 Vector3 direc = vec * rotation;
2261 direc.Normalize(); 2263 direc.Normalize();
2262 2264
@@ -2320,7 +2322,7 @@ namespace OpenSim.Region.Framework.Scenes
2320 2322
2321 if (m_isChildAgent == false) 2323 if (m_isChildAgent == false)
2322 { 2324 {
2323 PhysicsActor actor = m_physicsActor; 2325// PhysicsActor actor = m_physicsActor;
2324 2326
2325 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to 2327 // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
2326 // grab the latest PhysicsActor velocity, whereas m_velocity is often 2328 // grab the latest PhysicsActor velocity, whereas m_velocity is often
@@ -3256,7 +3258,7 @@ namespace OpenSim.Region.Framework.Scenes
3256 Vector3 force = m_forceToApply.Value; 3258 Vector3 force = m_forceToApply.Value;
3257 3259
3258 m_updateflag = true; 3260 m_updateflag = true;
3259 movementvector = force; 3261// movementvector = force;
3260 Velocity = force; 3262 Velocity = force;
3261 3263
3262 m_forceToApply = null; 3264 m_forceToApply = null;
@@ -3905,7 +3907,7 @@ namespace OpenSim.Region.Framework.Scenes
3905 } 3907 }
3906 else 3908 else
3907 { 3909 {
3908 group = Scene.SceneGraph.GetGroupByPrim(data.localID); 3910 group = Scene.GetGroupByPrim(data.localID);
3909 if (group != null) 3911 if (group != null)
3910 return GetSOGUpdatePriority(group); 3912 return GetSOGUpdatePriority(group);
3911 } 3913 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
new file mode 100644
index 0000000..b68a044
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/UuidGathererTests.cs
@@ -0,0 +1,88 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using System.Text;
30using NUnit.Framework;
31using NUnit.Framework.SyntaxHelpers;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Services.Interfaces;
36using OpenSim.Tests.Common;
37using OpenSim.Tests.Common.Setup;
38using OpenSim.Tests.Common.Mock;
39
40namespace OpenSim.Region.Framework.Scenes.Tests
41{
42 [TestFixture]
43 public class UuidGathererTests
44 {
45 protected IAssetService m_assetService;
46 protected UuidGatherer m_uuidGatherer;
47
48 [SetUp]
49 public void Init()
50 {
51 m_assetService = new MockAssetService();
52 m_uuidGatherer = new UuidGatherer(m_assetService);
53 }
54
55 [Test]
56 public void TestCorruptAsset()
57 {
58 TestHelper.InMethod();
59
60 UUID corruptAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
61 AssetBase corruptAsset = AssetHelpers.CreateAsset(corruptAssetUuid, "CORRUPT ASSET");
62 m_assetService.Store(corruptAsset);
63
64 IDictionary<UUID, int> foundAssetUuids = new Dictionary<UUID, int>();
65 m_uuidGatherer.GatherAssetUuids(corruptAssetUuid, AssetType.Object, foundAssetUuids);
66
67 // We count the uuid as gathered even if the asset itself is corrupt.
68 Assert.That(foundAssetUuids.Count, Is.EqualTo(1));
69 }
70
71 /// <summary>
72 /// Test requests made for non-existent assets while we're gathering
73 /// </summary>
74 [Test]
75 public void TestMissingAsset()
76 {
77 TestHelper.InMethod();
78
79 UUID missingAssetUuid = UUID.Parse("00000000-0000-0000-0000-000000000666");
80 IDictionary<UUID, int> foundAssetUuids = new Dictionary<UUID, int>();
81
82 m_uuidGatherer.GatherAssetUuids(missingAssetUuid, AssetType.Object, foundAssetUuids);
83
84 // We count the uuid as gathered even if the asset itself is missing.
85 Assert.That(foundAssetUuids.Count, Is.EqualTo(1));
86 }
87 }
88}
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
index 525a93a..930af81 100644
--- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
+++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs
@@ -273,7 +273,9 @@ namespace OpenSim.Region.Framework.Scenes
273 { 273 {
274 string xml = Utils.BytesToString(objectAsset.Data); 274 string xml = Utils.BytesToString(objectAsset.Data);
275 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); 275 SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
276 GatherAssetUuids(sog, assetUuids); 276
277 if (null != sog)
278 GatherAssetUuids(sog, assetUuids);
277 } 279 }
278 } 280 }
279 } 281 }
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs
index 4c2a4b9..cfe1278 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView
40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 40 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 41
42 private IRCServer m_server; 42 private IRCServer m_server;
43 private Scene m_scene; 43// private Scene m_scene;
44 44
45 #region Implementation of IRegionModule 45 #region Implementation of IRegionModule
46 46
@@ -50,7 +50,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView
50 source.Configs["IRCd"].GetBoolean("Enabled",false)) 50 source.Configs["IRCd"].GetBoolean("Enabled",false))
51 { 51 {
52 int portNo = source.Configs["IRCd"].GetInt("Port",6666); 52 int portNo = source.Configs["IRCd"].GetInt("Port",6666);
53 m_scene = scene; 53// m_scene = scene;
54 m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), portNo, scene); 54 m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), portNo, scene);
55 m_server.OnNewIRCClient += m_server_OnNewIRCClient; 55 m_server.OnNewIRCClient += m_server_OnNewIRCClient;
56 } 56 }
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 4b0d01a..6c3e7eb 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -758,6 +758,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
758 public event FriendActionDelegate OnApproveFriendRequest; 758 public event FriendActionDelegate OnApproveFriendRequest;
759 public event FriendActionDelegate OnDenyFriendRequest; 759 public event FriendActionDelegate OnDenyFriendRequest;
760 public event FriendshipTermination OnTerminateFriendship; 760 public event FriendshipTermination OnTerminateFriendship;
761 public event GrantUserFriendRights OnGrantUserRights;
761 public event MoneyTransferRequest OnMoneyTransferRequest; 762 public event MoneyTransferRequest OnMoneyTransferRequest;
762 public event EconomyDataRequest OnEconomyDataRequest; 763 public event EconomyDataRequest OnEconomyDataRequest;
763 public event MoneyBalanceRequest OnMoneyBalanceRequest; 764 public event MoneyBalanceRequest OnMoneyBalanceRequest;
@@ -1055,7 +1056,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1055 1056
1056 } 1057 }
1057 1058
1058 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems) 1059 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems)
1059 { 1060 {
1060 1061
1061 } 1062 }
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs
index 963cab5..8ea7ad3 100644
--- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/Graphics.cs
@@ -49,11 +49,8 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
49 49
50 public UUID SaveBitmap(Bitmap data, bool lossless, bool temporary) 50 public UUID SaveBitmap(Bitmap data, bool lossless, bool temporary)
51 { 51 {
52 AssetBase asset = new AssetBase(); 52 AssetBase asset = new AssetBase(UUID.Random(), "MRMDynamicImage", (sbyte)AssetType.Texture);
53 asset.FullID = UUID.Random();
54 asset.Data = OpenJPEG.EncodeFromImage(data, lossless); 53 asset.Data = OpenJPEG.EncodeFromImage(data, lossless);
55 asset.Name = "MRMDynamicImage";
56 asset.Type = 0;
57 asset.Description = "MRM Image"; 54 asset.Description = "MRM Image";
58 asset.Local = false; 55 asset.Local = false;
59 asset.Temporary = temporary; 56 asset.Temporary = temporary;
diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
new file mode 100644
index 0000000..44c9ada
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs
@@ -0,0 +1,105 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using Nini.Config;
31using log4net;
32using OpenSim.Framework;
33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes;
35using Mono.Addins;
36using OpenMetaverse;
37
38namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
39{
40 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ScriptModuleCommsModule")]
41 class ScriptModuleCommsModule : INonSharedRegionModule, IScriptModuleComms
42 {
43 private static readonly ILog m_log =
44 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45
46 private IScriptModule m_scriptModule = null;
47
48 public event ScriptCommand OnScriptCommand;
49
50 public void Initialise(IConfigSource config)
51 {
52 }
53
54 public void AddRegion(Scene scene)
55 {
56 scene.RegisterModuleInterface<IScriptModuleComms>(this);
57 }
58
59 public void RemoveRegion(Scene scene)
60 {
61 }
62
63 public void RegionLoaded(Scene scene)
64 {
65 m_scriptModule = scene.RequestModuleInterface<IScriptModule>();
66
67 if (m_scriptModule != null)
68 m_log.Info("[MODULE COMMANDS]: Script engine found, module active");
69 }
70
71 public string Name
72 {
73 get { return "ScriptModuleCommsModule"; }
74 }
75
76 public Type ReplaceableInterface
77 {
78 get { return null; }
79 }
80
81 public void Close()
82 {
83 }
84
85 public void RaiseEvent(UUID script, string id, string module, string command, string k)
86 {
87 ScriptCommand c = OnScriptCommand;
88
89 if (c == null)
90 return;
91
92 c(script, id, module, command, k);
93 }
94
95 public void DispatchReply(UUID script, int code, string text, string k)
96 {
97 if (m_scriptModule == null)
98 return;
99
100 Object[] args = new Object[] {-1, code, text, k};
101
102 m_scriptModule.PostScriptEvent(script, "link_message", args);
103 }
104 }
105}
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index f7cadaa..cf36d08 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -283,6 +283,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
283 public event FriendActionDelegate OnApproveFriendRequest; 283 public event FriendActionDelegate OnApproveFriendRequest;
284 public event FriendActionDelegate OnDenyFriendRequest; 284 public event FriendActionDelegate OnDenyFriendRequest;
285 public event FriendshipTermination OnTerminateFriendship; 285 public event FriendshipTermination OnTerminateFriendship;
286 public event GrantUserFriendRights OnGrantUserRights;
286 287
287 public event EconomyDataRequest OnEconomyDataRequest; 288 public event EconomyDataRequest OnEconomyDataRequest;
288 public event MoneyBalanceRequest OnMoneyBalanceRequest; 289 public event MoneyBalanceRequest OnMoneyBalanceRequest;
@@ -627,6 +628,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
627 public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID, 628 public virtual void SendInventoryFolderDetails(UUID ownerID, UUID folderID,
628 List<InventoryItemBase> items, 629 List<InventoryItemBase> items,
629 List<InventoryFolderBase> folders, 630 List<InventoryFolderBase> folders,
631 int version,
630 bool fetchFolders, 632 bool fetchFolders,
631 bool fetchItems) 633 bool fetchItems)
632 { 634 {
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index cbe73bb..1e94ee2 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -347,6 +347,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
347 { 347 {
348 indexBase = mesh.getIndexListAsInt(); 348 indexBase = mesh.getIndexListAsInt();
349 vertexBase = new Vector3[iVertexCount]; 349 vertexBase = new Vector3[iVertexCount];
350
350 for (int i = 0; i < iVertexCount; i++) 351 for (int i = 0; i < iVertexCount; i++)
351 { 352 {
352 OpenMetaverse.Vector3 v = mesh.getVertexList()[i]; 353 OpenMetaverse.Vector3 v = mesh.getVertexList()[i];
@@ -355,6 +356,7 @@ namespace OpenSim.Region.Physics.BulletXPlugin
355 else 356 else
356 vertexBase[i] = Vector3.Zero; 357 vertexBase[i] = Vector3.Zero;
357 } 358 }
359
358 for (int ix = 0; ix < iIndexCount; ix += 3) 360 for (int ix = 0; ix < iIndexCount; ix += 3)
359 { 361 {
360 int ia = indexBase[ix + 0]; 362 int ia = indexBase[ix + 0];
diff --git a/OpenSim/Region/Physics/Meshing/PrimMesher.cs b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
index 47ce615..2a213c3 100644
--- a/OpenSim/Region/Physics/Meshing/PrimMesher.cs
+++ b/OpenSim/Region/Physics/Meshing/PrimMesher.cs
@@ -67,11 +67,6 @@ namespace PrimMesher
67 Normalize(); 67 Normalize();
68 } 68 }
69 69
70 public Quat Identity()
71 {
72 return new Quat(0.0f, 0.0f, 0.0f, 1.0f);
73 }
74
75 public float Length() 70 public float Length()
76 { 71 {
77 return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W); 72 return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
@@ -660,7 +655,7 @@ namespace PrimMesher
660 this.faceNumbers = new List<int>(); 655 this.faceNumbers = new List<int>();
661 656
662 Coord center = new Coord(0.0f, 0.0f, 0.0f); 657 Coord center = new Coord(0.0f, 0.0f, 0.0f);
663 bool hasCenter = false; 658 //bool hasCenter = false;
664 659
665 List<Coord> hollowCoords = new List<Coord>(); 660 List<Coord> hollowCoords = new List<Coord>();
666 List<Coord> hollowNormals = new List<Coord>(); 661 List<Coord> hollowNormals = new List<Coord>();
@@ -727,7 +722,7 @@ namespace PrimMesher
727 else if (!simpleFace) 722 else if (!simpleFace)
728 { 723 {
729 this.coords.Add(center); 724 this.coords.Add(center);
730 hasCenter = true; 725 //hasCenter = true;
731 if (this.calcVertexNormals) 726 if (this.calcVertexNormals)
732 this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f)); 727 this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
733 this.us.Add(0.0f); 728 this.us.Add(0.0f);
@@ -1353,7 +1348,7 @@ namespace PrimMesher
1353 float stepSize = twoPi / this.stepsPerRevolution; 1348 float stepSize = twoPi / this.stepsPerRevolution;
1354 1349
1355 int step = (int)(startAngle / stepSize); 1350 int step = (int)(startAngle / stepSize);
1356 int firstStep = step; 1351// int firstStep = step;
1357 float angle = startAngle; 1352 float angle = startAngle;
1358 1353
1359 bool done = false; 1354 bool done = false;
@@ -1541,7 +1536,7 @@ namespace PrimMesher
1541 } 1536 }
1542 1537
1543 /// <summary> 1538 /// <summary>
1544 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. 1539 /// Extrudes a profile along a path.
1545 /// </summary> 1540 /// </summary>
1546 public void Extrude(PathType pathType) 1541 public void Extrude(PathType pathType)
1547 { 1542 {
@@ -1557,7 +1552,6 @@ namespace PrimMesher
1557 if (this.calcVertexNormals) 1552 if (this.calcVertexNormals)
1558 this.normals = new List<Coord>(); 1553 this.normals = new List<Coord>();
1559 1554
1560 //int step = 0;
1561 int steps = 1; 1555 int steps = 1;
1562 1556
1563 float length = this.pathCutEnd - this.pathCutBegin; 1557 float length = this.pathCutEnd - this.pathCutBegin;
@@ -1579,20 +1573,6 @@ namespace PrimMesher
1579 if (twistTotalAbs > 0.01f) 1573 if (twistTotalAbs > 0.01f)
1580 steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number 1574 steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
1581 1575
1582 //float start = -0.5f;
1583 //float stepSize = length / (float)steps;
1584 //float percentOfPathMultiplier = stepSize;
1585 //float xProfileScale = 1.0f;
1586 //float yProfileScale = 1.0f;
1587 //float xOffset = 0.0f;
1588 //float yOffset = 0.0f;
1589 //float zOffset = start;
1590 //float xOffsetStepIncrement = this.topShearX / steps;
1591 //float yOffsetStepIncrement = this.topShearY / steps;
1592
1593 //float percentOfPath = this.pathCutBegin;
1594 //zOffset += percentOfPath;
1595
1596 float hollow = this.hollow; 1576 float hollow = this.hollow;
1597 1577
1598 // sanity checks 1578 // sanity checks
@@ -1662,7 +1642,6 @@ namespace PrimMesher
1662 cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts; 1642 cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
1663 } 1643 }
1664 1644
1665
1666 if (initialProfileRot != 0.0f) 1645 if (initialProfileRot != 0.0f)
1667 { 1646 {
1668 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot)); 1647 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
@@ -1693,24 +1672,6 @@ namespace PrimMesher
1693 path.stepsPerRevolution = stepsPerRevolution; 1672 path.stepsPerRevolution = stepsPerRevolution;
1694 1673
1695 path.Create(pathType, steps); 1674 path.Create(pathType, steps);
1696 /*
1697 public int twistBegin = 0;
1698 public int twistEnd = 0;
1699 public float topShearX = 0.0f;
1700 public float topShearY = 0.0f;
1701 public float pathCutBegin = 0.0f;
1702 public float pathCutEnd = 1.0f;
1703 public float dimpleBegin = 0.0f;
1704 public float dimpleEnd = 1.0f;
1705 public float skew = 0.0f;
1706 public float holeSizeX = 1.0f; // called pathScaleX in pbs
1707 public float holeSizeY = 0.25f;
1708 public float taperX = 0.0f;
1709 public float taperY = 0.0f;
1710 public float radius = 0.0f;
1711 public float revolutions = 1.0f;
1712 public int stepsPerRevolution = 24;
1713 */
1714 1675
1715 bool needEndFaces = false; 1676 bool needEndFaces = false;
1716 if (pathType == PathType.Circular) 1677 if (pathType == PathType.Circular)
@@ -1777,7 +1738,7 @@ namespace PrimMesher
1777 // append this layer 1738 // append this layer
1778 1739
1779 int coordsLen = this.coords.Count; 1740 int coordsLen = this.coords.Count;
1780 int lastCoordsLen = coordsLen; 1741// int lastCoordsLen = coordsLen;
1781 newLayer.AddValue2FaceVertexIndices(coordsLen); 1742 newLayer.AddValue2FaceVertexIndices(coordsLen);
1782 1743
1783 this.coords.AddRange(newLayer.coords); 1744 this.coords.AddRange(newLayer.coords);
@@ -1796,7 +1757,6 @@ namespace PrimMesher
1796 int numVerts = newLayer.coords.Count; 1757 int numVerts = newLayer.coords.Count;
1797 Face newFace = new Face(); 1758 Face newFace = new Face();
1798 1759
1799 //if (step > 0)
1800 if (nodeIndex > 0) 1760 if (nodeIndex > 0)
1801 { 1761 {
1802 int startVert = coordsLen + 1; 1762 int startVert = coordsLen + 1;
@@ -1812,7 +1772,6 @@ namespace PrimMesher
1812 iNext = startVert; 1772 iNext = startVert;
1813 1773
1814 int whichVert = i - startVert; 1774 int whichVert = i - startVert;
1815 //int whichVert2 = i - lastCoordsLen;
1816 1775
1817 newFace.v1 = i; 1776 newFace.v1 = i;
1818 newFace.v2 = i - numVerts; 1777 newFace.v2 = i - numVerts;
@@ -1982,809 +1941,27 @@ namespace PrimMesher
1982 1941
1983 1942
1984 /// <summary> 1943 /// <summary>
1944 /// DEPRICATED - use Extrude(PathType.Linear) instead
1985 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism. 1945 /// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
1986 /// </summary> 1946 /// </summary>
1947 ///
1987 public void ExtrudeLinear() 1948 public void ExtrudeLinear()
1988 { 1949 {
1989 this.coords = new List<Coord>(); 1950 this.Extrude(PathType.Linear);
1990 this.faces = new List<Face>();
1991
1992 if (this.viewerMode)
1993 {
1994 this.viewerFaces = new List<ViewerFace>();
1995 this.calcVertexNormals = true;
1996 }
1997
1998 if (this.calcVertexNormals)
1999 this.normals = new List<Coord>();
2000
2001 int step = 0;
2002 int steps = 1;
2003
2004 float length = this.pathCutEnd - this.pathCutBegin;
2005 normalsProcessed = false;
2006
2007 if (this.viewerMode && this.sides == 3)
2008 {
2009 // prisms don't taper well so add some vertical resolution
2010 // other prims may benefit from this but just do prisms for now
2011 if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01)
2012 steps = (int)(steps * 4.5 * length);
2013 }
2014
2015
2016 float twistBegin = this.twistBegin / 360.0f * twoPi;
2017 float twistEnd = this.twistEnd / 360.0f * twoPi;
2018 float twistTotal = twistEnd - twistBegin;
2019 float twistTotalAbs = Math.Abs(twistTotal);
2020 if (twistTotalAbs > 0.01f)
2021 steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
2022
2023 float start = -0.5f;
2024 float stepSize = length / (float)steps;
2025 float percentOfPathMultiplier = stepSize;
2026 float xProfileScale = 1.0f;
2027 float yProfileScale = 1.0f;
2028 float xOffset = 0.0f;
2029 float yOffset = 0.0f;
2030 float zOffset = start;
2031 float xOffsetStepIncrement = this.topShearX / steps;
2032 float yOffsetStepIncrement = this.topShearY / steps;
2033
2034 float percentOfPath = this.pathCutBegin;
2035 zOffset += percentOfPath;
2036
2037 float hollow = this.hollow;
2038
2039 // sanity checks
2040 float initialProfileRot = 0.0f;
2041 if (this.sides == 3)
2042 {
2043 if (this.hollowSides == 4)
2044 {
2045 if (hollow > 0.7f)
2046 hollow = 0.7f;
2047 hollow *= 0.707f;
2048 }
2049 else hollow *= 0.5f;
2050 }
2051 else if (this.sides == 4)
2052 {
2053 initialProfileRot = 1.25f * (float)Math.PI;
2054 if (this.hollowSides != 4)
2055 hollow *= 0.707f;
2056 }
2057 else if (this.sides == 24 && this.hollowSides == 4)
2058 hollow *= 1.414f;
2059
2060 Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals);
2061 this.errorMessage = profile.errorMessage;
2062
2063 this.numPrimFaces = profile.numPrimFaces;
2064
2065 int cut1Vert = -1;
2066 int cut2Vert = -1;
2067 if (hasProfileCut)
2068 {
2069 cut1Vert = hasHollow ? profile.coords.Count - 1 : 0;
2070 cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
2071 }
2072
2073 if (initialProfileRot != 0.0f)
2074 {
2075 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
2076 if (viewerMode)
2077 profile.MakeFaceUVs();
2078 }
2079
2080 Coord lastCutNormal1 = new Coord();
2081 Coord lastCutNormal2 = new Coord();
2082 float lastV = 1.0f;
2083
2084 bool done = false;
2085 while (!done)
2086 {
2087 Profile newLayer = profile.Copy();
2088
2089 if (this.taperX == 0.0f)
2090 xProfileScale = 1.0f;
2091 else if (this.taperX > 0.0f)
2092 xProfileScale = 1.0f - percentOfPath * this.taperX;
2093 else xProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperX;
2094
2095 if (this.taperY == 0.0f)
2096 yProfileScale = 1.0f;
2097 else if (this.taperY > 0.0f)
2098 yProfileScale = 1.0f - percentOfPath * this.taperY;
2099 else yProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperY;
2100
2101 if (xProfileScale != 1.0f || yProfileScale != 1.0f)
2102 newLayer.Scale(xProfileScale, yProfileScale);
2103
2104 float twist = twistBegin + twistTotal * percentOfPath;
2105 if (twist != 0.0f)
2106 newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist));
2107
2108 newLayer.AddPos(xOffset, yOffset, zOffset);
2109
2110 if (step == 0)
2111 {
2112 newLayer.FlipNormals();
2113
2114 // add the top faces to the viewerFaces list here
2115 if (this.viewerMode)
2116 {
2117 Coord faceNormal = newLayer.faceNormal;
2118 ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber);
2119 int numFaces = newLayer.faces.Count;
2120 List<Face> faces = newLayer.faces;
2121
2122 for (int i = 0; i < numFaces; i++)
2123 {
2124 Face face = faces[i];
2125 newViewerFace.v1 = newLayer.coords[face.v1];
2126 newViewerFace.v2 = newLayer.coords[face.v2];
2127 newViewerFace.v3 = newLayer.coords[face.v3];
2128
2129 newViewerFace.coordIndex1 = face.v1;
2130 newViewerFace.coordIndex2 = face.v2;
2131 newViewerFace.coordIndex3 = face.v3;
2132
2133 newViewerFace.n1 = faceNormal;
2134 newViewerFace.n2 = faceNormal;
2135 newViewerFace.n3 = faceNormal;
2136
2137 newViewerFace.uv1 = newLayer.faceUVs[face.v1];
2138 newViewerFace.uv2 = newLayer.faceUVs[face.v2];
2139 newViewerFace.uv3 = newLayer.faceUVs[face.v3];
2140
2141 this.viewerFaces.Add(newViewerFace);
2142 }
2143 }
2144 }
2145
2146 // append this layer
2147
2148 int coordsLen = this.coords.Count;
2149 int lastCoordsLen = coordsLen;
2150 newLayer.AddValue2FaceVertexIndices(coordsLen);
2151
2152 this.coords.AddRange(newLayer.coords);
2153
2154 if (this.calcVertexNormals)
2155 {
2156 newLayer.AddValue2FaceNormalIndices(this.normals.Count);
2157 this.normals.AddRange(newLayer.vertexNormals);
2158 }
2159
2160 if (percentOfPath < this.pathCutBegin + 0.01f || percentOfPath > this.pathCutEnd - 0.01f)
2161 this.faces.AddRange(newLayer.faces);
2162
2163 // fill faces between layers
2164
2165 int numVerts = newLayer.coords.Count;
2166 Face newFace = new Face();
2167
2168 if (step > 0)
2169 {
2170 int startVert = coordsLen + 1;
2171 int endVert = this.coords.Count;
2172
2173 if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
2174 startVert--;
2175
2176 for (int i = startVert; i < endVert; i++)
2177 {
2178 int iNext = i + 1;
2179 if (i == endVert - 1)
2180 iNext = startVert;
2181
2182 int whichVert = i - startVert;
2183 //int whichVert2 = i - lastCoordsLen;
2184
2185 newFace.v1 = i;
2186 newFace.v2 = i - numVerts;
2187 newFace.v3 = iNext - numVerts;
2188 this.faces.Add(newFace);
2189
2190 newFace.v2 = iNext - numVerts;
2191 newFace.v3 = iNext;
2192 this.faces.Add(newFace);
2193
2194 if (this.viewerMode)
2195 {
2196 // add the side faces to the list of viewerFaces here
2197 //int primFaceNum = 1;
2198 //if (whichVert >= sides)
2199 // primFaceNum = 2;
2200 int primFaceNum = profile.faceNumbers[whichVert];
2201
2202 ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
2203 ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
2204
2205 float u1 = newLayer.us[whichVert];
2206 float u2 = 1.0f;
2207 if (whichVert < newLayer.us.Count - 1)
2208 u2 = newLayer.us[whichVert + 1];
2209
2210 if (whichVert == cut1Vert || whichVert == cut2Vert)
2211 {
2212 u1 = 0.0f;
2213 u2 = 1.0f;
2214 }
2215 else if (sides < 5)
2216 { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
2217 // to reflect the entire texture width
2218 u1 *= sides;
2219 u2 *= sides;
2220 u2 -= (int)u1;
2221 u1 -= (int)u1;
2222 if (u2 < 0.1f)
2223 u2 = 1.0f;
2224
2225 //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
2226 }
2227
2228 newViewerFace1.uv1.U = u1;
2229 newViewerFace1.uv2.U = u1;
2230 newViewerFace1.uv3.U = u2;
2231
2232 newViewerFace1.uv1.V = 1.0f - percentOfPath;
2233 newViewerFace1.uv2.V = lastV;
2234 newViewerFace1.uv3.V = lastV;
2235
2236 newViewerFace2.uv1.U = u1;
2237 newViewerFace2.uv2.U = u2;
2238 newViewerFace2.uv3.U = u2;
2239
2240 newViewerFace2.uv1.V = 1.0f - percentOfPath;
2241 newViewerFace2.uv2.V = lastV;
2242 newViewerFace2.uv3.V = 1.0f - percentOfPath;
2243
2244 newViewerFace1.v1 = this.coords[i];
2245 newViewerFace1.v2 = this.coords[i - numVerts];
2246 newViewerFace1.v3 = this.coords[iNext - numVerts];
2247
2248 newViewerFace2.v1 = this.coords[i];
2249 newViewerFace2.v2 = this.coords[iNext - numVerts];
2250 newViewerFace2.v3 = this.coords[iNext];
2251
2252 newViewerFace1.coordIndex1 = i;
2253 newViewerFace1.coordIndex2 = i - numVerts;
2254 newViewerFace1.coordIndex3 = iNext - numVerts;
2255
2256 newViewerFace2.coordIndex1 = i;
2257 newViewerFace2.coordIndex2 = iNext - numVerts;
2258 newViewerFace2.coordIndex3 = iNext;
2259
2260 // profile cut faces
2261 if (whichVert == cut1Vert)
2262 {
2263 newViewerFace1.n1 = newLayer.cutNormal1;
2264 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
2265
2266 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
2267 newViewerFace2.n2 = lastCutNormal1;
2268 }
2269 else if (whichVert == cut2Vert)
2270 {
2271 newViewerFace1.n1 = newLayer.cutNormal2;
2272 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
2273
2274 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
2275 newViewerFace2.n2 = lastCutNormal2;
2276 }
2277
2278 else // outer and hollow faces
2279 {
2280 if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts))
2281 {
2282 newViewerFace1.CalcSurfaceNormal();
2283 newViewerFace2.CalcSurfaceNormal();
2284 }
2285 else
2286 {
2287 newViewerFace1.n1 = this.normals[i];
2288 newViewerFace1.n2 = this.normals[i - numVerts];
2289 newViewerFace1.n3 = this.normals[iNext - numVerts];
2290
2291 newViewerFace2.n1 = this.normals[i];
2292 newViewerFace2.n2 = this.normals[iNext - numVerts];
2293 newViewerFace2.n3 = this.normals[iNext];
2294 }
2295 }
2296
2297 //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = newLayer.faceNumbers[whichVert];
2298
2299 this.viewerFaces.Add(newViewerFace1);
2300 this.viewerFaces.Add(newViewerFace2);
2301
2302 }
2303 }
2304 }
2305
2306 lastCutNormal1 = newLayer.cutNormal1;
2307 lastCutNormal2 = newLayer.cutNormal2;
2308 lastV = 1.0f - percentOfPath;
2309
2310 // calc the step for the next iteration of the loop
2311
2312 if (step < steps)
2313 {
2314 step += 1;
2315 percentOfPath += percentOfPathMultiplier;
2316 xOffset += xOffsetStepIncrement;
2317 yOffset += yOffsetStepIncrement;
2318 zOffset += stepSize;
2319 if (percentOfPath > this.pathCutEnd)
2320 done = true;
2321 }
2322 else done = true;
2323
2324 if (done && viewerMode)
2325 {
2326 // add the top faces to the viewerFaces list here
2327 Coord faceNormal = newLayer.faceNormal;
2328 ViewerFace newViewerFace = new ViewerFace();
2329 newViewerFace.primFaceNumber = 0;
2330 int numFaces = newLayer.faces.Count;
2331 List<Face> faces = newLayer.faces;
2332
2333 for (int i = 0; i < numFaces; i++)
2334 {
2335 Face face = faces[i];
2336 newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
2337 newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
2338 newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
2339
2340 newViewerFace.coordIndex1 = face.v1 - coordsLen;
2341 newViewerFace.coordIndex2 = face.v2 - coordsLen;
2342 newViewerFace.coordIndex3 = face.v3 - coordsLen;
2343
2344 newViewerFace.n1 = faceNormal;
2345 newViewerFace.n2 = faceNormal;
2346 newViewerFace.n3 = faceNormal;
2347
2348 newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen];
2349 newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen];
2350 newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen];
2351
2352 this.viewerFaces.Add(newViewerFace);
2353 }
2354 }
2355 }
2356 } 1951 }
2357 1952
2358 1953
2359 /// <summary> 1954 /// <summary>
1955 /// DEPRICATED - use Extrude(PathType.Circular) instead
2360 /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring. 1956 /// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring.
2361 /// </summary> 1957 /// </summary>
1958 ///
2362 public void ExtrudeCircular() 1959 public void ExtrudeCircular()
2363 { 1960 {
2364 this.coords = new List<Coord>(); 1961 this.Extrude(PathType.Circular);
2365 this.faces = new List<Face>();
2366
2367 if (this.viewerMode)
2368 {
2369 this.viewerFaces = new List<ViewerFace>();
2370 this.calcVertexNormals = true;
2371 }
2372
2373 if (this.calcVertexNormals)
2374 this.normals = new List<Coord>();
2375
2376 int step = 0;
2377 int steps = 24;
2378
2379 normalsProcessed = false;
2380
2381 float twistBegin = this.twistBegin / 360.0f * twoPi;
2382 float twistEnd = this.twistEnd / 360.0f * twoPi;
2383 float twistTotal = twistEnd - twistBegin;
2384
2385 // if the profile has a lot of twist, add more layers otherwise the layers may overlap
2386 // and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't
2387 // accurately match the viewer
2388 float twistTotalAbs = Math.Abs(twistTotal);
2389 if (twistTotalAbs > 0.01f)
2390 {
2391 if (twistTotalAbs > Math.PI * 1.5f)
2392 steps *= 2;
2393 if (twistTotalAbs > Math.PI * 3.0f)
2394 steps *= 2;
2395 }
2396
2397 float yPathScale = this.holeSizeY * 0.5f;
2398 float pathLength = this.pathCutEnd - this.pathCutBegin;
2399 float totalSkew = this.skew * 2.0f * pathLength;
2400 float skewStart = this.pathCutBegin * 2.0f * this.skew - this.skew;
2401 float xOffsetTopShearXFactor = this.topShearX * (0.25f + 0.5f * (0.5f - this.holeSizeY));
2402 float yShearCompensation = 1.0f + Math.Abs(this.topShearY) * 0.25f;
2403
2404 // It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end
2405 // angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used
2406 // to calculate the sine for generating the path radius appears to approximate it's effects there
2407 // too, but there are some subtle differences in the radius which are noticeable as the prim size
2408 // increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on
2409 // the meshes generated with this technique appear nearly identical in shape to the same prims when
2410 // displayed by the viewer.
2411
2412 float startAngle = (twoPi * this.pathCutBegin * this.revolutions) - this.topShearY * 0.9f;
2413 float endAngle = (twoPi * this.pathCutEnd * this.revolutions) - this.topShearY * 0.9f;
2414 float stepSize = twoPi / this.stepsPerRevolution;
2415
2416 step = (int)(startAngle / stepSize);
2417 int firstStep = step;
2418 float angle = startAngle;
2419 float hollow = this.hollow;
2420
2421 // sanity checks
2422 float initialProfileRot = 0.0f;
2423 if (this.sides == 3)
2424 {
2425 initialProfileRot = (float)Math.PI;
2426 if (this.hollowSides == 4)
2427 {
2428 if (hollow > 0.7f)
2429 hollow = 0.7f;
2430 hollow *= 0.707f;
2431 }
2432 else hollow *= 0.5f;
2433 }
2434 else if (this.sides == 4)
2435 {
2436 initialProfileRot = 0.25f * (float)Math.PI;
2437 if (this.hollowSides != 4)
2438 hollow *= 0.707f;
2439 }
2440 else if (this.sides > 4)
2441 {
2442 initialProfileRot = (float)Math.PI;
2443 if (this.hollowSides == 4)
2444 {
2445 if (hollow > 0.7f)
2446 hollow = 0.7f;
2447 hollow /= 0.7f;
2448 }
2449 }
2450
2451 bool needEndFaces = false;
2452 if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f)
2453 needEndFaces = true;
2454 else if (this.taperX != 0.0f || this.taperY != 0.0f)
2455 needEndFaces = true;
2456 else if (this.skew != 0.0f)
2457 needEndFaces = true;
2458 else if (twistTotal != 0.0f)
2459 needEndFaces = true;
2460 else if (this.radius != 0.0f)
2461 needEndFaces = true;
2462
2463 Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, needEndFaces, calcVertexNormals);
2464 this.errorMessage = profile.errorMessage;
2465
2466 this.numPrimFaces = profile.numPrimFaces;
2467
2468 int cut1Vert = -1;
2469 int cut2Vert = -1;
2470 if (hasProfileCut)
2471 {
2472 cut1Vert = hasHollow ? profile.coords.Count - 1 : 0;
2473 cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
2474 }
2475
2476 if (initialProfileRot != 0.0f)
2477 {
2478 profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
2479 if (viewerMode)
2480 profile.MakeFaceUVs();
2481 }
2482
2483 Coord lastCutNormal1 = new Coord();
2484 Coord lastCutNormal2 = new Coord();
2485 float lastV = 1.0f;
2486
2487 bool done = false;
2488 while (!done) // loop through the length of the path and add the layers
2489 {
2490 bool isEndLayer = false;
2491 if (angle <= startAngle + .01f || angle >= endAngle - .01f)
2492 isEndLayer = true;
2493
2494 Profile newLayer = profile.Copy();
2495
2496 float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX;
2497 float yProfileScale = this.holeSizeY;
2498
2499 float percentOfPath = angle / (twoPi * this.revolutions);
2500 float percentOfAngles = (angle - startAngle) / (endAngle - startAngle);
2501
2502 if (this.taperX > 0.01f)
2503 xProfileScale *= 1.0f - percentOfPath * this.taperX;
2504 else if (this.taperX < -0.01f)
2505 xProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperX;
2506
2507 if (this.taperY > 0.01f)
2508 yProfileScale *= 1.0f - percentOfPath * this.taperY;
2509 else if (this.taperY < -0.01f)
2510 yProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperY;
2511
2512 if (xProfileScale != 1.0f || yProfileScale != 1.0f)
2513 newLayer.Scale(xProfileScale, yProfileScale);
2514
2515 float radiusScale = 1.0f;
2516 if (this.radius > 0.001f)
2517 radiusScale = 1.0f - this.radius * percentOfPath;
2518 else if (this.radius < 0.001f)
2519 radiusScale = 1.0f + this.radius * (1.0f - percentOfPath);
2520
2521 float twist = twistBegin + twistTotal * percentOfPath;
2522
2523 float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles);
2524 xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor;
2525
2526 float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale;
2527
2528 float zOffset = (float)Math.Sin(angle + this.topShearY) * (0.5f - yPathScale) * radiusScale;
2529
2530 // next apply twist rotation to the profile layer
2531 if (twistTotal != 0.0f || twistBegin != 0.0f)
2532 newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist));
2533
2534 // now orient the rotation of the profile layer relative to it's position on the path
2535 // adding taperY to the angle used to generate the quat appears to approximate the viewer
2536 newLayer.AddRot(new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY));
2537 newLayer.AddPos(xOffset, yOffset, zOffset);
2538
2539 if (isEndLayer && angle <= startAngle + .01f)
2540 {
2541 newLayer.FlipNormals();
2542
2543 // add the top faces to the viewerFaces list here
2544 if (this.viewerMode && needEndFaces)
2545 {
2546 Coord faceNormal = newLayer.faceNormal;
2547 ViewerFace newViewerFace = new ViewerFace();
2548 newViewerFace.primFaceNumber = 0;
2549 foreach (Face face in newLayer.faces)
2550 {
2551 newViewerFace.v1 = newLayer.coords[face.v1];
2552 newViewerFace.v2 = newLayer.coords[face.v2];
2553 newViewerFace.v3 = newLayer.coords[face.v3];
2554
2555 newViewerFace.coordIndex1 = face.v1;
2556 newViewerFace.coordIndex2 = face.v2;
2557 newViewerFace.coordIndex3 = face.v3;
2558
2559 newViewerFace.n1 = faceNormal;
2560 newViewerFace.n2 = faceNormal;
2561 newViewerFace.n3 = faceNormal;
2562
2563 newViewerFace.uv1 = newLayer.faceUVs[face.v1];
2564 newViewerFace.uv2 = newLayer.faceUVs[face.v2];
2565 newViewerFace.uv3 = newLayer.faceUVs[face.v3];
2566
2567 this.viewerFaces.Add(newViewerFace);
2568 }
2569 }
2570 }
2571
2572 // append the layer and fill in the sides
2573
2574 int coordsLen = this.coords.Count;
2575 newLayer.AddValue2FaceVertexIndices(coordsLen);
2576
2577 this.coords.AddRange(newLayer.coords);
2578
2579 if (this.calcVertexNormals)
2580 {
2581 newLayer.AddValue2FaceNormalIndices(this.normals.Count);
2582 this.normals.AddRange(newLayer.vertexNormals);
2583 }
2584
2585 if (isEndLayer)
2586 this.faces.AddRange(newLayer.faces);
2587
2588 // fill faces between layers
2589
2590 int numVerts = newLayer.coords.Count;
2591 Face newFace = new Face();
2592 if (step > firstStep)
2593 {
2594 int startVert = coordsLen + 1;
2595 int endVert = this.coords.Count;
2596
2597 if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
2598 startVert--;
2599
2600 for (int i = startVert; i < endVert; i++)
2601 {
2602 int iNext = i + 1;
2603 if (i == endVert - 1)
2604 iNext = startVert;
2605
2606 int whichVert = i - startVert;
2607
2608 newFace.v1 = i;
2609 newFace.v2 = i - numVerts;
2610 newFace.v3 = iNext - numVerts;
2611 this.faces.Add(newFace);
2612
2613 newFace.v2 = iNext - numVerts;
2614 newFace.v3 = iNext;
2615 this.faces.Add(newFace);
2616
2617 if (this.viewerMode)
2618 {
2619 int primFaceNumber = profile.faceNumbers[whichVert];
2620 if (!needEndFaces)
2621 primFaceNumber -= 1;
2622
2623 // add the side faces to the list of viewerFaces here
2624 ViewerFace newViewerFace1 = new ViewerFace(primFaceNumber);
2625 ViewerFace newViewerFace2 = new ViewerFace(primFaceNumber);
2626 float u1 = newLayer.us[whichVert];
2627 float u2 = 1.0f;
2628 if (whichVert < newLayer.us.Count - 1)
2629 u2 = newLayer.us[whichVert + 1];
2630
2631 if (whichVert == cut1Vert || whichVert == cut2Vert)
2632 {
2633 u1 = 0.0f;
2634 u2 = 1.0f;
2635 }
2636 else if (sides < 5)
2637 { // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
2638 // to reflect the entire texture width
2639 u1 *= sides;
2640 u2 *= sides;
2641 u2 -= (int)u1;
2642 u1 -= (int)u1;
2643 if (u2 < 0.1f)
2644 u2 = 1.0f;
2645
2646 //newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
2647 }
2648
2649 newViewerFace1.uv1.U = u1;
2650 newViewerFace1.uv2.U = u1;
2651 newViewerFace1.uv3.U = u2;
2652
2653 newViewerFace1.uv1.V = 1.0f - percentOfPath;
2654 newViewerFace1.uv2.V = lastV;
2655 newViewerFace1.uv3.V = lastV;
2656
2657 newViewerFace2.uv1.U = u1;
2658 newViewerFace2.uv2.U = u2;
2659 newViewerFace2.uv3.U = u2;
2660
2661 newViewerFace2.uv1.V = 1.0f - percentOfPath;
2662 newViewerFace2.uv2.V = lastV;
2663 newViewerFace2.uv3.V = 1.0f - percentOfPath;
2664
2665 newViewerFace1.v1 = this.coords[i];
2666 newViewerFace1.v2 = this.coords[i - numVerts];
2667 newViewerFace1.v3 = this.coords[iNext - numVerts];
2668
2669 newViewerFace2.v1 = this.coords[i];
2670 newViewerFace2.v2 = this.coords[iNext - numVerts];
2671 newViewerFace2.v3 = this.coords[iNext];
2672
2673 newViewerFace1.coordIndex1 = i;
2674 newViewerFace1.coordIndex2 = i - numVerts;
2675 newViewerFace1.coordIndex3 = iNext - numVerts;
2676
2677 newViewerFace2.coordIndex1 = i;
2678 newViewerFace2.coordIndex2 = iNext - numVerts;
2679 newViewerFace2.coordIndex3 = iNext;
2680
2681 // profile cut faces
2682 if (whichVert == cut1Vert)
2683 {
2684 newViewerFace1.n1 = newLayer.cutNormal1;
2685 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
2686
2687 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
2688 newViewerFace2.n2 = lastCutNormal1;
2689 }
2690 else if (whichVert == cut2Vert)
2691 {
2692 newViewerFace1.n1 = newLayer.cutNormal2;
2693 newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
2694
2695 newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
2696 newViewerFace2.n2 = lastCutNormal2;
2697 }
2698 else // periphery faces
2699 {
2700 if (sides < 5 && whichVert < newLayer.numOuterVerts)
2701 {
2702 newViewerFace1.n1 = this.normals[i];
2703 newViewerFace1.n2 = this.normals[i - numVerts];
2704 newViewerFace1.n3 = this.normals[i - numVerts];
2705
2706 newViewerFace2.n1 = this.normals[i];
2707 newViewerFace2.n2 = this.normals[i - numVerts];
2708 newViewerFace2.n3 = this.normals[i];
2709 }
2710 else if (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)
2711 {
2712 newViewerFace1.n1 = this.normals[iNext];
2713 newViewerFace1.n2 = this.normals[iNext - numVerts];
2714 newViewerFace1.n3 = this.normals[iNext - numVerts];
2715
2716 newViewerFace2.n1 = this.normals[iNext];
2717 newViewerFace2.n2 = this.normals[iNext - numVerts];
2718 newViewerFace2.n3 = this.normals[iNext];
2719 }
2720 else
2721 {
2722 newViewerFace1.n1 = this.normals[i];
2723 newViewerFace1.n2 = this.normals[i - numVerts];
2724 newViewerFace1.n3 = this.normals[iNext - numVerts];
2725
2726 newViewerFace2.n1 = this.normals[i];
2727 newViewerFace2.n2 = this.normals[iNext - numVerts];
2728 newViewerFace2.n3 = this.normals[iNext];
2729 }
2730 }
2731
2732 //newViewerFace1.primFaceNumber = newViewerFace2.primFaceNumber = newLayer.faceNumbers[whichVert];
2733 this.viewerFaces.Add(newViewerFace1);
2734 this.viewerFaces.Add(newViewerFace2);
2735
2736 }
2737 }
2738 }
2739
2740 lastCutNormal1 = newLayer.cutNormal1;
2741 lastCutNormal2 = newLayer.cutNormal2;
2742 lastV = 1.0f - percentOfPath;
2743
2744 // calculate terms for next iteration
2745 // calculate the angle for the next iteration of the loop
2746
2747 if (angle >= endAngle - 0.01)
2748 done = true;
2749 else
2750 {
2751 step += 1;
2752 angle = stepSize * step;
2753 if (angle > endAngle)
2754 angle = endAngle;
2755 }
2756
2757 if (done && viewerMode && needEndFaces)
2758 {
2759 // add the bottom faces to the viewerFaces list here
2760 Coord faceNormal = newLayer.faceNormal;
2761 ViewerFace newViewerFace = new ViewerFace();
2762 //newViewerFace.primFaceNumber = newLayer.bottomFaceNumber + 1;
2763 newViewerFace.primFaceNumber = newLayer.bottomFaceNumber;
2764 foreach (Face face in newLayer.faces)
2765 {
2766 newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
2767 newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
2768 newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
2769
2770 newViewerFace.coordIndex1 = face.v1 - coordsLen;
2771 newViewerFace.coordIndex2 = face.v2 - coordsLen;
2772 newViewerFace.coordIndex3 = face.v3 - coordsLen;
2773
2774 newViewerFace.n1 = faceNormal;
2775 newViewerFace.n2 = faceNormal;
2776 newViewerFace.n3 = faceNormal;
2777
2778 newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen];
2779 newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen];
2780 newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen];
2781
2782 this.viewerFaces.Add(newViewerFace);
2783 }
2784 }
2785 }
2786 } 1962 }
2787 1963
1964
2788 private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3) 1965 private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3)
2789 { 1966 {
2790 Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z); 1967 Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z);
diff --git a/OpenSim/Region/Physics/Meshing/SculptMesh.cs b/OpenSim/Region/Physics/Meshing/SculptMesh.cs
index f1dd586..4dc6e2e 100644
--- a/OpenSim/Region/Physics/Meshing/SculptMesh.cs
+++ b/OpenSim/Region/Physics/Meshing/SculptMesh.cs
@@ -25,12 +25,18 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28// to build without references to System.Drawing, comment this out
29#define SYSTEM_DRAWING
30
28using System; 31using System;
29using System.Collections.Generic; 32using System.Collections.Generic;
30using System.Text; 33using System.Text;
31using System.IO; 34using System.IO;
35
36#if SYSTEM_DRAWING
32using System.Drawing; 37using System.Drawing;
33using System.Drawing.Imaging; 38using System.Drawing.Imaging;
39#endif
34 40
35namespace PrimMesher 41namespace PrimMesher
36{ 42{
@@ -46,6 +52,7 @@ namespace PrimMesher
46 52
47 public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; 53 public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 };
48 54
55#if SYSTEM_DRAWING
49 // private Bitmap ScaleImage(Bitmap srcImage, float scale) 56 // private Bitmap ScaleImage(Bitmap srcImage, float scale)
50 // { 57 // {
51 // int sourceWidth = srcImage.Width; 58 // int sourceWidth = srcImage.Width;
@@ -83,6 +90,7 @@ namespace PrimMesher
83 // return scaledImage; 90 // return scaledImage;
84 // } 91 // }
85 92
93
86 public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) 94 public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
87 { 95 {
88 Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName); 96 Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName);
@@ -97,6 +105,7 @@ namespace PrimMesher
97 _SculptMesh(bitmap, (SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0); 105 _SculptMesh(bitmap, (SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0);
98 bitmap.Dispose(); 106 bitmap.Dispose();
99 } 107 }
108#endif
100 109
101 /// <summary> 110 /// <summary>
102 /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications 111 /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications
@@ -201,6 +210,7 @@ namespace PrimMesher
201 calcVertexNormals(SculptType.plane, numXElements, numYElements); 210 calcVertexNormals(SculptType.plane, numXElements, numYElements);
202 } 211 }
203 212
213#if SYSTEM_DRAWING
204 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode) 214 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
205 { 215 {
206 _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false); 216 _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false);
@@ -210,9 +220,16 @@ namespace PrimMesher
210 { 220 {
211 _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert); 221 _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert);
212 } 222 }
223#endif
224
225 public SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert)
226 {
227 _SculptMesh(rows, sculptType, viewerMode, mirror, invert);
228 }
213 229
230#if SYSTEM_DRAWING
214 /// <summary> 231 /// <summary>
215 /// converts a bitmap to a list lists of coords, while scaling the image. 232 /// converts a bitmap to a list of lists of coords, while scaling the image.
216 /// the scaling is done in floating point so as to allow for reduced vertex position 233 /// the scaling is done in floating point so as to allow for reduced vertex position
217 /// quantization as the position will be averaged between pixel values. this routine will 234 /// quantization as the position will be averaged between pixel values. this routine will
218 /// likely fail if the bitmap width and height are not powers of 2. 235 /// likely fail if the bitmap width and height are not powers of 2.
@@ -267,6 +284,7 @@ namespace PrimMesher
267 return rows; 284 return rows;
268 } 285 }
269 286
287
270 void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) 288 void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert)
271 { 289 {
272 coords = new List<Coord>(); 290 coords = new List<Coord>();
@@ -285,12 +303,27 @@ namespace PrimMesher
285 int scale = (int)(1.0f / sourceScaleFactor); 303 int scale = (int)(1.0f / sourceScaleFactor);
286 if (scale < 1) scale = 1; 304 if (scale < 1) scale = 1;
287 305
288 List<List<Coord>> rows = bitmap2Coords(sculptBitmap, scale, mirror); 306 _SculptMesh(bitmap2Coords(sculptBitmap, scale, mirror), sculptType, viewerMode, mirror, invert);
307 }
308#endif
309
310
311 void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert)
312 {
313 coords = new List<Coord>();
314 faces = new List<Face>();
315 normals = new List<Coord>();
316 uvs = new List<UVCoord>();
317
318 sculptType = (SculptType)(((int)sculptType) & 0x07);
319
320 if (mirror)
321 if (sculptType == SculptType.plane)
322 invert = !invert;
289 323
290 viewerFaces = new List<ViewerFace>(); 324 viewerFaces = new List<ViewerFace>();
291 325
292 int width = sculptBitmap.Width / scale; 326 int width = rows[0].Count;
293 // int height = sculptBitmap.Height / scale;
294 327
295 int p1, p2, p3, p4; 328 int p1, p2, p3, p4;
296 329
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
index 4a802cd..39cdc0f 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs
@@ -67,8 +67,8 @@ namespace OpenSim.Region.Physics.OdePlugin
67 67
68 // private OdeScene m_parentScene = null; 68 // private OdeScene m_parentScene = null;
69 private IntPtr m_body = IntPtr.Zero; 69 private IntPtr m_body = IntPtr.Zero;
70 private IntPtr m_jointGroup = IntPtr.Zero; 70// private IntPtr m_jointGroup = IntPtr.Zero;
71 private IntPtr m_aMotor = IntPtr.Zero; 71// private IntPtr m_aMotor = IntPtr.Zero;
72 72
73 73
74 // Vehicle properties 74 // Vehicle properties
@@ -117,7 +117,7 @@ namespace OpenSim.Region.Physics.OdePlugin
117 117
118 //Hover and Buoyancy properties 118 //Hover and Buoyancy properties
119 private float m_VhoverHeight = 0f; 119 private float m_VhoverHeight = 0f;
120 private float m_VhoverEfficiency = 0f; 120// private float m_VhoverEfficiency = 0f;
121 private float m_VhoverTimescale = 0f; 121 private float m_VhoverTimescale = 0f;
122 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height 122 private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
123 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. 123 private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
@@ -170,11 +170,11 @@ namespace OpenSim.Region.Physics.OdePlugin
170 if (pValue > 1f) pValue = 1f; 170 if (pValue > 1f) pValue = 1f;
171 m_VehicleBuoyancy = pValue; 171 m_VehicleBuoyancy = pValue;
172 break; 172 break;
173 case Vehicle.HOVER_EFFICIENCY: 173// case Vehicle.HOVER_EFFICIENCY:
174 if (pValue < 0f) pValue = 0f; 174// if (pValue < 0f) pValue = 0f;
175 if (pValue > 1f) pValue = 1f; 175// if (pValue > 1f) pValue = 1f;
176 m_VhoverEfficiency = pValue; 176// m_VhoverEfficiency = pValue;
177 break; 177// break;
178 case Vehicle.HOVER_HEIGHT: 178 case Vehicle.HOVER_HEIGHT:
179 m_VhoverHeight = pValue; 179 m_VhoverHeight = pValue;
180 break; 180 break;
@@ -291,7 +291,7 @@ namespace OpenSim.Region.Physics.OdePlugin
291 m_angularMotorTimescale = 1000; 291 m_angularMotorTimescale = 1000;
292 m_angularMotorDecayTimescale = 120; 292 m_angularMotorDecayTimescale = 120;
293 m_VhoverHeight = 0; 293 m_VhoverHeight = 0;
294 m_VhoverEfficiency = 1; 294// m_VhoverEfficiency = 1;
295 m_VhoverTimescale = 10; 295 m_VhoverTimescale = 10;
296 m_VehicleBuoyancy = 0; 296 m_VehicleBuoyancy = 0;
297 // m_linearDeflectionEfficiency = 1; 297 // m_linearDeflectionEfficiency = 1;
@@ -317,7 +317,7 @@ namespace OpenSim.Region.Physics.OdePlugin
317 m_angularMotorTimescale = 1; 317 m_angularMotorTimescale = 1;
318 m_angularMotorDecayTimescale = 0.8f; 318 m_angularMotorDecayTimescale = 0.8f;
319 m_VhoverHeight = 0; 319 m_VhoverHeight = 0;
320 m_VhoverEfficiency = 0; 320// m_VhoverEfficiency = 0;
321 m_VhoverTimescale = 1000; 321 m_VhoverTimescale = 1000;
322 m_VehicleBuoyancy = 0; 322 m_VehicleBuoyancy = 0;
323 // // m_linearDeflectionEfficiency = 1; 323 // // m_linearDeflectionEfficiency = 1;
@@ -344,7 +344,7 @@ namespace OpenSim.Region.Physics.OdePlugin
344 m_angularMotorTimescale = 4; 344 m_angularMotorTimescale = 4;
345 m_angularMotorDecayTimescale = 4; 345 m_angularMotorDecayTimescale = 4;
346 m_VhoverHeight = 0; 346 m_VhoverHeight = 0;
347 m_VhoverEfficiency = 0.5f; 347// m_VhoverEfficiency = 0.5f;
348 m_VhoverTimescale = 2; 348 m_VhoverTimescale = 2;
349 m_VehicleBuoyancy = 1; 349 m_VehicleBuoyancy = 1;
350 // m_linearDeflectionEfficiency = 0.5f; 350 // m_linearDeflectionEfficiency = 0.5f;
@@ -372,7 +372,7 @@ namespace OpenSim.Region.Physics.OdePlugin
372 m_angularMotorTimescale = 4; 372 m_angularMotorTimescale = 4;
373 m_angularMotorDecayTimescale = 4; 373 m_angularMotorDecayTimescale = 4;
374 m_VhoverHeight = 0; 374 m_VhoverHeight = 0;
375 m_VhoverEfficiency = 0.5f; 375// m_VhoverEfficiency = 0.5f;
376 m_VhoverTimescale = 1000; 376 m_VhoverTimescale = 1000;
377 m_VehicleBuoyancy = 0; 377 m_VehicleBuoyancy = 0;
378 // m_linearDeflectionEfficiency = 0.5f; 378 // m_linearDeflectionEfficiency = 0.5f;
@@ -399,7 +399,7 @@ namespace OpenSim.Region.Physics.OdePlugin
399 m_angularMotorTimescale = 6; 399 m_angularMotorTimescale = 6;
400 m_angularMotorDecayTimescale = 10; 400 m_angularMotorDecayTimescale = 10;
401 m_VhoverHeight = 5; 401 m_VhoverHeight = 5;
402 m_VhoverEfficiency = 0.8f; 402// m_VhoverEfficiency = 0.8f;
403 m_VhoverTimescale = 10; 403 m_VhoverTimescale = 10;
404 m_VehicleBuoyancy = 1; 404 m_VehicleBuoyancy = 1;
405 // m_linearDeflectionEfficiency = 0; 405 // m_linearDeflectionEfficiency = 0;
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index f4b502a..fa42023 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -2643,7 +2643,7 @@ Console.WriteLine(" JointCreateFixed");
2643 //outofBounds = true; 2643 //outofBounds = true;
2644 } 2644 }
2645 2645
2646 float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); 2646// float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation));
2647//Console.WriteLine("Adiff " + m_primName + " = " + Adiff); 2647//Console.WriteLine("Adiff " + m_primName + " = " + Adiff);
2648 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) 2648 if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
2649 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) 2649 && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index a8e006b..981cf43 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -439,7 +439,7 @@ namespace OpenSim.Region.Physics.OdePlugin
439 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); 439 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f);
440 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); 440 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f);
441 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); 441 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f);
442 avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", true); 442 avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false);
443 443
444 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); 444 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
445 445
@@ -3541,7 +3541,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3541 public override void UnCombine(PhysicsScene pScene) 3541 public override void UnCombine(PhysicsScene pScene)
3542 { 3542 {
3543 IntPtr localGround = IntPtr.Zero; 3543 IntPtr localGround = IntPtr.Zero;
3544 float[] localHeightfield; 3544// float[] localHeightfield;
3545 bool proceed = false; 3545 bool proceed = false;
3546 List<IntPtr> geomDestroyList = new List<IntPtr>(); 3546 List<IntPtr> geomDestroyList = new List<IntPtr>();
3547 3547
@@ -3553,7 +3553,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3553 { 3553 {
3554 if (geom == localGround) 3554 if (geom == localGround)
3555 { 3555 {
3556 localHeightfield = TerrainHeightFieldHeights[geom]; 3556// localHeightfield = TerrainHeightFieldHeights[geom];
3557 proceed = true; 3557 proceed = true;
3558 } 3558 }
3559 else 3559 else
@@ -3575,7 +3575,7 @@ namespace OpenSim.Region.Physics.OdePlugin
3575 // memory corruption 3575 // memory corruption
3576 if (TerrainHeightFieldHeights.ContainsKey(g)) 3576 if (TerrainHeightFieldHeights.ContainsKey(g))
3577 { 3577 {
3578 float[] removingHeightField = TerrainHeightFieldHeights[g]; 3578// float[] removingHeightField = TerrainHeightFieldHeights[g];
3579 TerrainHeightFieldHeights.Remove(g); 3579 TerrainHeightFieldHeights.Remove(g);
3580 3580
3581 if (RegionTerrain.ContainsKey(g)) 3581 if (RegionTerrain.ContainsKey(g))
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerClientEventForwarder.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerClientEventForwarder.cs
index 70d6de3..721d396 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerClientEventForwarder.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerClientEventForwarder.cs
@@ -30,7 +30,7 @@ using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenSim.Region.Framework.Scenes; 31using OpenSim.Region.Framework.Scenes;
32 32
33namespace OpenSim.Region.CoreModules.World.Land 33namespace OpenSim.Region.RegionCombinerModule
34{ 34{
35public class RegionCombinerClientEventForwarder 35public class RegionCombinerClientEventForwarder
36 { 36 {
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerIndividualEventForwarder.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs
index 2cbaf96..9d41c9c 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerIndividualEventForwarder.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerIndividualEventForwarder.cs
@@ -30,7 +30,7 @@ using OpenMetaverse;
30using OpenSim.Framework; 30using OpenSim.Framework;
31using OpenSim.Region.Framework.Scenes; 31using OpenSim.Region.Framework.Scenes;
32 32
33namespace OpenSim.Region.CoreModules.World.Land 33namespace OpenSim.Region.RegionCombinerModule
34{ 34{
35 public class RegionCombinerIndividualEventForwarder 35 public class RegionCombinerIndividualEventForwarder
36 { 36 {
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
index 7df836c..146ec66 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerLargeLandChannel.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
@@ -30,8 +30,9 @@ using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.CoreModules.World.Land;
33 34
34namespace OpenSim.Region.CoreModules.World.Land 35namespace OpenSim.Region.RegionCombinerModule
35{ 36{
36public class RegionCombinerLargeLandChannel : ILandChannel 37public class RegionCombinerLargeLandChannel : ILandChannel
37 { 38 {
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
index d8c5ed9..7ec1d4b 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs
@@ -36,9 +36,15 @@ using OpenSim.Framework.Client;
36using OpenSim.Region.Framework.Interfaces; 36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Framework.Console; 38using OpenSim.Framework.Console;
39using OpenSim.Region.Physics.Manager;
40using Mono.Addins;
39 41
40namespace OpenSim.Region.CoreModules.World.Land 42[assembly: Addin("RegionCombinerModule", "0.1")]
43[assembly: AddinDependency("OpenSim", "0.5")]
44namespace OpenSim.Region.RegionCombinerModule
41{ 45{
46
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
42 public class RegionCombinerModule : ISharedRegionModule 48 public class RegionCombinerModule : ISharedRegionModule
43 { 49 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -299,76 +305,13 @@ namespace OpenSim.Region.CoreModules.World.Land
299 //xxy 305 //xxy
300 //xxx 306 //xxx
301 307
308
302 if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd 309 if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd
303 >= (regionConnections.X * (int)Constants.RegionSize)) 310 >= (regionConnections.X * (int)Constants.RegionSize))
304 && (((int)conn.Y * (int)Constants.RegionSize) 311 && (((int)conn.Y * (int)Constants.RegionSize)
305 >= (regionConnections.Y * (int)Constants.RegionSize))) 312 >= (regionConnections.Y * (int)Constants.RegionSize)))
306 { 313 {
307 Vector3 offset = Vector3.Zero; 314 connectedYN = DoWorkForOneRegionOverPlusXY(conn, regionConnections, scene);
308 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
309 ((conn.X * (int)Constants.RegionSize)));
310 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
311 ((conn.Y * (int)Constants.RegionSize)));
312
313 Vector3 extents = Vector3.Zero;
314 extents.Y = conn.YEnd;
315 extents.X = conn.XEnd + regionConnections.XEnd;
316
317 conn.UpdateExtents(extents);
318
319 m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}",
320 conn.RegionScene.RegionInfo.RegionName,
321 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
322
323 scene.BordersLocked = true;
324 conn.RegionScene.BordersLocked = true;
325
326 RegionData ConnectedRegion = new RegionData();
327 ConnectedRegion.Offset = offset;
328 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
329 ConnectedRegion.RegionScene = scene;
330 conn.ConnectedRegions.Add(ConnectedRegion);
331
332 // Inform root region Physics about the extents of this region
333 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
334
335 // Inform Child region that it needs to forward it's terrain to the root region
336 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
337
338 // Extend the borders as appropriate
339 lock (conn.RegionScene.EastBorders)
340 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
341
342 lock (conn.RegionScene.NorthBorders)
343 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
344
345 lock (conn.RegionScene.SouthBorders)
346 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
347
348 lock (scene.WestBorders)
349 {
350
351
352 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
353
354 // Trigger auto teleport to root region
355 scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
356 scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
357 }
358
359 // Reset Terrain.. since terrain loads before we get here, we need to load
360 // it again so it loads in the root region
361
362 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
363
364 // Unlock borders
365 conn.RegionScene.BordersLocked = false;
366 scene.BordersLocked = false;
367
368 // Create a client event forwarder and add this region's events to the root region.
369 if (conn.ClientEventForwarder != null)
370 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
371 connectedYN = true;
372 break; 315 break;
373 } 316 }
374 317
@@ -381,57 +324,8 @@ namespace OpenSim.Region.CoreModules.World.Land
381 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd 324 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
382 >= (regionConnections.Y * (int)Constants.RegionSize))) 325 >= (regionConnections.Y * (int)Constants.RegionSize)))
383 { 326 {
384 Vector3 offset = Vector3.Zero; 327 connectedYN = DoWorkForOneRegionOverXPlusY(conn, regionConnections, scene);
385 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - 328 break;
386 ((conn.X * (int)Constants.RegionSize)));
387 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
388 ((conn.Y * (int)Constants.RegionSize)));
389
390 Vector3 extents = Vector3.Zero;
391 extents.Y = regionConnections.YEnd + conn.YEnd;
392 extents.X = conn.XEnd;
393 conn.UpdateExtents(extents);
394
395 scene.BordersLocked = true;
396 conn.RegionScene.BordersLocked = true;
397
398 RegionData ConnectedRegion = new RegionData();
399 ConnectedRegion.Offset = offset;
400 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
401 ConnectedRegion.RegionScene = scene;
402 conn.ConnectedRegions.Add(ConnectedRegion);
403
404 m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}",
405 conn.RegionScene.RegionInfo.RegionName,
406 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
407
408 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
409 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
410
411 lock (conn.RegionScene.NorthBorders)
412 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
413 lock (conn.RegionScene.EastBorders)
414 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
415 lock (conn.RegionScene.WestBorders)
416 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
417 lock (scene.SouthBorders)
418 {
419 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
420 scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
421 scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
422 }
423
424 // Reset Terrain.. since terrain normally loads first.
425 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
426 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
427 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
428
429 scene.BordersLocked = false;
430 conn.RegionScene.BordersLocked = false;
431 if (conn.ClientEventForwarder != null)
432 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
433 connectedYN = true;
434 break;
435 } 329 }
436 330
437 // If we're one region over +x +y 331 // If we're one region over +x +y
@@ -443,140 +337,276 @@ namespace OpenSim.Region.CoreModules.World.Land
443 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd 337 && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd
444 >= (regionConnections.Y * (int)Constants.RegionSize))) 338 >= (regionConnections.Y * (int)Constants.RegionSize)))
445 { 339 {
446 Vector3 offset = Vector3.Zero; 340 connectedYN = DoWorkForOneRegionOverPlusXPlusY(conn, regionConnections, scene);
447 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - 341 break;
448 ((conn.X * (int)Constants.RegionSize)));
449 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
450 ((conn.Y * (int)Constants.RegionSize)));
451 342
452 Vector3 extents = Vector3.Zero; 343 }
453 extents.Y = regionConnections.YEnd + conn.YEnd; 344 }
454 extents.X = regionConnections.XEnd + conn.XEnd;
455 conn.UpdateExtents(extents);
456 345
457 scene.BordersLocked = true; 346 // If !connectYN means that this region is a root region
458 conn.RegionScene.BordersLocked = true; 347 if (!connectedYN)
348 {
349 DoWorkForRootRegion(regionConnections, scene);
459 350
460 RegionData ConnectedRegion = new RegionData(); 351 }
461 ConnectedRegion.Offset = offset; 352 }
462 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; 353 // Set up infinite borders around the entire AABB of the combined ConnectedRegions
463 ConnectedRegion.RegionScene = scene; 354 AdjustLargeRegionBounds();
355 }
464 356
465 conn.ConnectedRegions.Add(ConnectedRegion); 357 private bool DoWorkForOneRegionOverPlusXY(RegionConnections conn, RegionConnections regionConnections, Scene scene)
358 {
359 Vector3 offset = Vector3.Zero;
360 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
361 ((conn.X * (int)Constants.RegionSize)));
362 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
363 ((conn.Y * (int)Constants.RegionSize)));
466 364
467 m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}", 365 Vector3 extents = Vector3.Zero;
468 conn.RegionScene.RegionInfo.RegionName, 366 extents.Y = conn.YEnd;
469 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); 367 extents.X = conn.XEnd + regionConnections.XEnd;
470 368
471 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); 369 conn.UpdateExtents(extents);
472 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
473 lock (conn.RegionScene.NorthBorders)
474 {
475 if (conn.RegionScene.NorthBorders.Count == 1)// && 2)
476 {
477 //compound border
478 // already locked above
479 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
480
481 lock (conn.RegionScene.EastBorders)
482 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
483 lock (conn.RegionScene.WestBorders)
484 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
485 }
486 }
487 370
488 lock (scene.SouthBorders) 371 m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}",
489 { 372 conn.RegionScene.RegionInfo.RegionName,
490 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south 373 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
491 scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
492 scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
493 }
494 374
495 lock (conn.RegionScene.EastBorders) 375 scene.BordersLocked = true;
496 { 376 conn.RegionScene.BordersLocked = true;
497 if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2)
498 {
499 377
500 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; 378 RegionData ConnectedRegion = new RegionData();
501 lock (conn.RegionScene.NorthBorders) 379 ConnectedRegion.Offset = offset;
502 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; 380 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
503 lock (conn.RegionScene.SouthBorders) 381 ConnectedRegion.RegionScene = scene;
504 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; 382 conn.ConnectedRegions.Add(ConnectedRegion);
505 383
384 // Inform root region Physics about the extents of this region
385 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
506 386
507 } 387 // Inform Child region that it needs to forward it's terrain to the root region
508 } 388 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
509 389
510 lock (scene.WestBorders) 390 // Extend the borders as appropriate
511 { 391 lock (conn.RegionScene.EastBorders)
512 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West 392 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
513 scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
514 scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
515 }
516 393
517 /* 394 lock (conn.RegionScene.NorthBorders)
518 else 395 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
519 { 396
520 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; 397 lock (conn.RegionScene.SouthBorders)
521 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; 398 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
522 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
523 scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south
524 }
525 */
526 399
400 lock (scene.WestBorders)
401 {
527 402
528 // Reset Terrain.. since terrain normally loads first.
529 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
530 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
531 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
532 scene.BordersLocked = false;
533 conn.RegionScene.BordersLocked = false;
534 403
535 if (conn.ClientEventForwarder != null) 404 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
536 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
537 405
538 connectedYN = true; 406 // Trigger auto teleport to root region
407 scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
408 scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
409 }
539 410
540 //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); 411 // Reset Terrain.. since terrain loads before we get here, we need to load
412 // it again so it loads in the root region
541 413
542 break; 414 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
543 } 415
416 // Unlock borders
417 conn.RegionScene.BordersLocked = false;
418 scene.BordersLocked = false;
419
420 // Create a client event forwarder and add this region's events to the root region.
421 if (conn.ClientEventForwarder != null)
422 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
423
424 return true;
425 }
426
427 private bool DoWorkForOneRegionOverXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene)
428 {
429 Vector3 offset = Vector3.Zero;
430 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
431 ((conn.X * (int)Constants.RegionSize)));
432 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
433 ((conn.Y * (int)Constants.RegionSize)));
434
435 Vector3 extents = Vector3.Zero;
436 extents.Y = regionConnections.YEnd + conn.YEnd;
437 extents.X = conn.XEnd;
438 conn.UpdateExtents(extents);
439
440 scene.BordersLocked = true;
441 conn.RegionScene.BordersLocked = true;
442
443 RegionData ConnectedRegion = new RegionData();
444 ConnectedRegion.Offset = offset;
445 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
446 ConnectedRegion.RegionScene = scene;
447 conn.ConnectedRegions.Add(ConnectedRegion);
448
449 m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}",
450 conn.RegionScene.RegionInfo.RegionName,
451 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
452
453 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
454 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
455
456 lock (conn.RegionScene.NorthBorders)
457 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
458 lock (conn.RegionScene.EastBorders)
459 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
460 lock (conn.RegionScene.WestBorders)
461 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
462 lock (scene.SouthBorders)
463 {
464 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
465 scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
466 scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
467 }
468
469 // Reset Terrain.. since terrain normally loads first.
470 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
471 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
472 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
473
474 scene.BordersLocked = false;
475 conn.RegionScene.BordersLocked = false;
476 if (conn.ClientEventForwarder != null)
477 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
478 return true;
479 }
480
481 private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene)
482 {
483 Vector3 offset = Vector3.Zero;
484 offset.X = (((regionConnections.X * (int)Constants.RegionSize)) -
485 ((conn.X * (int)Constants.RegionSize)));
486 offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) -
487 ((conn.Y * (int)Constants.RegionSize)));
488
489 Vector3 extents = Vector3.Zero;
490 extents.Y = regionConnections.YEnd + conn.YEnd;
491 extents.X = regionConnections.XEnd + conn.XEnd;
492 conn.UpdateExtents(extents);
493
494 scene.BordersLocked = true;
495 conn.RegionScene.BordersLocked = true;
496
497 RegionData ConnectedRegion = new RegionData();
498 ConnectedRegion.Offset = offset;
499 ConnectedRegion.RegionId = scene.RegionInfo.originRegionID;
500 ConnectedRegion.RegionScene = scene;
501
502 conn.ConnectedRegions.Add(ConnectedRegion);
503
504 m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}",
505 conn.RegionScene.RegionInfo.RegionName,
506 regionConnections.RegionScene.RegionInfo.RegionName, offset, extents);
507
508 conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents);
509 scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero);
510 lock (conn.RegionScene.NorthBorders)
511 {
512 if (conn.RegionScene.NorthBorders.Count == 1)// && 2)
513 {
514 //compound border
515 // already locked above
516 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
517
518 lock (conn.RegionScene.EastBorders)
519 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
520 lock (conn.RegionScene.WestBorders)
521 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
544 } 522 }
523 }
545 524
546 // If !connectYN means that this region is a root region 525 lock (scene.SouthBorders)
547 if (!connectedYN) 526 {
527 scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south
528 scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
529 scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
530 }
531
532 lock (conn.RegionScene.EastBorders)
533 {
534 if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2)
548 { 535 {
549 RegionData rdata = new RegionData();
550 rdata.Offset = Vector3.Zero;
551 rdata.RegionId = scene.RegionInfo.originRegionID;
552 rdata.RegionScene = scene;
553 // save it's land channel
554 regionConnections.RegionLandChannel = scene.LandChannel;
555
556 // Substitue our landchannel
557 RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel,
558 regionConnections.ConnectedRegions);
559 scene.LandChannel = lnd;
560 // Forward the permissions modules of each of the connected regions to the root region
561 lock (m_regions)
562 {
563 foreach (RegionData r in regionConnections.ConnectedRegions)
564 {
565 ForwardPermissionRequests(regionConnections, r.RegionScene);
566 }
567 }
568 // Create the root region's Client Event Forwarder
569 regionConnections.ClientEventForwarder = new RegionCombinerClientEventForwarder(regionConnections);
570 536
571 // Sets up the CoarseLocationUpdate forwarder for this root region 537 conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize;
572 scene.EventManager.OnNewPresence += SetCourseLocationDelegate; 538 lock (conn.RegionScene.NorthBorders)
539 conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
540 lock (conn.RegionScene.SouthBorders)
541 conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize;
542
573 543
574 // Adds this root region to a dictionary of regions that are connectable
575 m_regions.Add(scene.RegionInfo.originRegionID, regionConnections);
576 } 544 }
577 } 545 }
578 // Set up infinite borders around the entire AABB of the combined ConnectedRegions 546
579 AdjustLargeRegionBounds(); 547 lock (scene.WestBorders)
548 {
549 scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West
550 scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX;
551 scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY;
552 }
553
554 /*
555 else
556 {
557 conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize;
558 conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize;
559 conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize;
560 scene.SouthBorders[0].BorderLine.Z += (int)Constants.RegionSize; //auto teleport south
561 }
562 */
563
564
565 // Reset Terrain.. since terrain normally loads first.
566 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
567 scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised());
568 //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised());
569 scene.BordersLocked = false;
570 conn.RegionScene.BordersLocked = false;
571
572 if (conn.ClientEventForwarder != null)
573 conn.ClientEventForwarder.AddSceneToEventForwarding(scene);
574
575 return true;
576
577 //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents);
578
579 }
580
581 private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene)
582 {
583 RegionData rdata = new RegionData();
584 rdata.Offset = Vector3.Zero;
585 rdata.RegionId = scene.RegionInfo.originRegionID;
586 rdata.RegionScene = scene;
587 // save it's land channel
588 regionConnections.RegionLandChannel = scene.LandChannel;
589
590 // Substitue our landchannel
591 RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel,
592 regionConnections.ConnectedRegions);
593 scene.LandChannel = lnd;
594 // Forward the permissions modules of each of the connected regions to the root region
595 lock (m_regions)
596 {
597 foreach (RegionData r in regionConnections.ConnectedRegions)
598 {
599 ForwardPermissionRequests(regionConnections, r.RegionScene);
600 }
601 }
602 // Create the root region's Client Event Forwarder
603 regionConnections.ClientEventForwarder = new RegionCombinerClientEventForwarder(regionConnections);
604
605 // Sets up the CoarseLocationUpdate forwarder for this root region
606 scene.EventManager.OnNewPresence += SetCourseLocationDelegate;
607
608 // Adds this root region to a dictionary of regions that are connectable
609 m_regions.Add(scene.RegionInfo.originRegionID, regionConnections);
580 } 610 }
581 611
582 private void SetCourseLocationDelegate(ScenePresence presence) 612 private void SetCourseLocationDelegate(ScenePresence presence)
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerPermissionModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs
index 76ca5e3..4d1af57 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerPermissionModule.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs
@@ -32,7 +32,7 @@ using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces; 32using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
34 34
35namespace OpenSim.Region.CoreModules.World.Land 35namespace OpenSim.Region.RegionCombinerModule
36{ 36{
37 public class RegionCombinerPermissionModule 37 public class RegionCombinerPermissionModule
38 { 38 {
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionConnections.cs b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs
index 419ed74..3aa9f20 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionConnections.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs
@@ -31,7 +31,7 @@ using OpenMetaverse;
31using OpenSim.Region.Framework.Interfaces; 31using OpenSim.Region.Framework.Interfaces;
32using OpenSim.Region.Framework.Scenes; 32using OpenSim.Region.Framework.Scenes;
33 33
34namespace OpenSim.Region.CoreModules.World.Land 34namespace OpenSim.Region.RegionCombinerModule
35{ 35{
36 public class RegionConnections 36 public class RegionConnections
37 { 37 {
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCourseLocation.cs b/OpenSim/Region/RegionCombinerModule/RegionCourseLocation.cs
index 175ca89..53a678f 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionCourseLocation.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCourseLocation.cs
@@ -30,7 +30,7 @@ using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using OpenSim.Framework; 31using OpenSim.Framework;
32 32
33namespace OpenSim.Region.CoreModules.World.Land 33namespace OpenSim.Region.RegionCombinerModule
34{ 34{
35 35
36 struct RegionCourseLocationStruct 36 struct RegionCourseLocationStruct
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionData.cs b/OpenSim/Region/RegionCombinerModule/RegionData.cs
index 3383527..bd0e398 100644
--- a/OpenSim/Region/CoreModules/World/Land/RegionData.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionData.cs
@@ -28,7 +28,7 @@
28using OpenMetaverse; 28using OpenMetaverse;
29using OpenSim.Region.Framework.Scenes; 29using OpenSim.Region.Framework.Scenes;
30 30
31namespace OpenSim.Region.CoreModules.World.Land 31namespace OpenSim.Region.RegionCombinerModule
32{ 32{
33 public class RegionData 33 public class RegionData
34 { 34 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
new file mode 100644
index 0000000..d4facdd
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -0,0 +1,134 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.ScriptEngine.Shared;
40using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
41using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
42using OpenSim.Region.ScriptEngine.Interfaces;
43using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
44
45using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
46using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
47using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
48using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
49using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
50using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
52
53namespace OpenSim.Region.ScriptEngine.Shared.Api
54{
55 [Serializable]
56 public class MOD_Api : MarshalByRefObject, IMOD_Api, IScriptApi
57 {
58 internal IScriptEngine m_ScriptEngine;
59 internal SceneObjectPart m_host;
60 internal uint m_localID;
61 internal UUID m_itemID;
62 internal bool m_MODFunctionsEnabled = false;
63 internal IScriptModuleComms m_comms = null;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_localID = localID;
70 m_itemID = itemID;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowMODFunctions", false))
73 m_MODFunctionsEnabled = true;
74
75 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
76 if (m_comms == null)
77 m_MODFunctionsEnabled = false;
78 }
79
80 public override Object InitializeLifetimeService()
81 {
82 ILease lease = (ILease)base.InitializeLifetimeService();
83
84 if (lease.CurrentState == LeaseState.Initial)
85 {
86 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
87// lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
88// lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
89 }
90 return lease;
91 }
92
93 public Scene World
94 {
95 get { return m_ScriptEngine.World; }
96 }
97
98 internal void MODError(string msg)
99 {
100 throw new Exception("MOD Runtime Error: " + msg);
101 }
102
103 //
104 //Dumps an error message on the debug console.
105 //
106
107 internal void MODShoutError(string message)
108 {
109 if (message.Length > 1023)
110 message = message.Substring(0, 1023);
111
112 World.SimChat(Utils.StringToBytes(message),
113 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
114
115 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
116 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
117 }
118
119 public string modSendCommand(string module, string command, string k)
120 {
121 if (!m_MODFunctionsEnabled)
122 {
123 MODShoutError("Module command functions not enabled");
124 return UUID.Zero.ToString();;
125 }
126
127 UUID req = UUID.Random();
128
129 m_comms.RaiseEvent(m_itemID, req.ToString(), module, command, k);
130
131 return req.ToString();
132 }
133 }
134}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 52396b6..3ffcff0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -199,7 +199,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
199 //Dumps an error message on the debug console. 199 //Dumps an error message on the debug console.
200 // 200 //
201 201
202 internal void OSSLShoutError(string message) 202 internal void OSSLShoutError(string message)
203 { 203 {
204 if (message.Length > 1023) 204 if (message.Length > 1023)
205 message = message.Substring(0, 1023); 205 message = message.Substring(0, 1023);
@@ -384,7 +384,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 m_host.AddScriptLPS(1); 384 m_host.AddScriptLPS(1);
385 if (World.Entities.ContainsKey(target)) 385 if (World.Entities.ContainsKey(target))
386 { 386 {
387 World.Entities[target].Rotation = rotation; 387 EntityBase entity;
388 if (World.Entities.TryGetValue(target, out entity))
389 {
390 if (entity is SceneObjectGroup)
391 ((SceneObjectGroup)entity).Rotation = rotation;
392 else if (entity is ScenePresence)
393 ((ScenePresence)entity).Rotation = rotation;
394 }
388 } 395 }
389 else 396 else
390 { 397 {
@@ -1169,7 +1176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1169 1176
1170 land.SetMediaUrl(url); 1177 land.SetMediaUrl(url);
1171 } 1178 }
1172 1179
1173 public void osSetParcelSIPAddress(string SIPAddress) 1180 public void osSetParcelSIPAddress(string SIPAddress)
1174 { 1181 {
1175 // What actually is the difference to the LL function? 1182 // What actually is the difference to the LL function?
@@ -1177,7 +1184,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL"); 1184 CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL");
1178 1185
1179 m_host.AddScriptLPS(1); 1186 m_host.AddScriptLPS(1);
1180 1187
1181 1188
1182 ILandObject land 1189 ILandObject land
1183 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 1190 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
@@ -1187,16 +1194,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1187 OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function"); 1194 OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function");
1188 return; 1195 return;
1189 } 1196 }
1190 1197
1191 // get the voice module 1198 // get the voice module
1192 IVoiceModule voiceModule = World.RequestModuleInterface<IVoiceModule>(); 1199 IVoiceModule voiceModule = World.RequestModuleInterface<IVoiceModule>();
1193 1200
1194 if (voiceModule != null) 1201 if (voiceModule != null)
1195 voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID); 1202 voiceModule.setLandSIPAddress(SIPAddress,land.LandData.GlobalID);
1196 else 1203 else
1197 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land"); 1204 OSSLError("osSetParcelSIPAddress: No voice module enabled for this land");
1198 1205
1199 1206
1200 } 1207 }
1201 1208
1202 public string osGetScriptEngineName() 1209 public string osGetScriptEngineName()
@@ -1476,12 +1483,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1476 m_host.AddScriptLPS(1); 1483 m_host.AddScriptLPS(1);
1477 1484
1478 // Create new asset 1485 // Create new asset
1479 AssetBase asset = new AssetBase(); 1486 AssetBase asset = new AssetBase(UUID.Random(), notecardName, (sbyte)AssetType.Notecard);
1480 asset.Name = notecardName;
1481 asset.Description = "Script Generated Notecard"; 1487 asset.Description = "Script Generated Notecard";
1482 asset.Type = 7; 1488 string notecardData = String.Empty;
1483 asset.FullID = UUID.Random();
1484 string notecardData = "";
1485 1489
1486 for (int i = 0; i < contents.Length; i++) { 1490 for (int i = 0; i < contents.Length; i++) {
1487 notecardData += contents.GetLSLStringItem(i) + "\n"; 1491 notecardData += contents.GetLSLStringItem(i) + "\n";
@@ -1521,10 +1525,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1521 } 1525 }
1522 1526
1523 1527
1524 /*Instead of using the LSL Dataserver event to pull notecard data, 1528 /*Instead of using the LSL Dataserver event to pull notecard data,
1525 this will simply read the requested line and return its data as a string. 1529 this will simply read the requested line and return its data as a string.
1526 1530
1527 Warning - due to the synchronous method this function uses to fetch assets, its use 1531 Warning - due to the synchronous method this function uses to fetch assets, its use
1528 may be dangerous and unreliable while running in grid mode. 1532 may be dangerous and unreliable while running in grid mode.
1529 */ 1533 */
1530 public string osGetNotecardLine(string name, int line) 1534 public string osGetNotecardLine(string name, int line)
@@ -1572,10 +1576,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1572 1576
1573 } 1577 }
1574 1578
1575 /*Instead of using the LSL Dataserver event to pull notecard data line by line, 1579 /*Instead of using the LSL Dataserver event to pull notecard data line by line,
1576 this will simply read the entire notecard and return its data as a string. 1580 this will simply read the entire notecard and return its data as a string.
1577 1581
1578 Warning - due to the synchronous method this function uses to fetch assets, its use 1582 Warning - due to the synchronous method this function uses to fetch assets, its use
1579 may be dangerous and unreliable while running in grid mode. 1583 may be dangerous and unreliable while running in grid mode.
1580 */ 1584 */
1581 1585
@@ -1630,10 +1634,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1630 1634
1631 } 1635 }
1632 1636
1633 /*Instead of using the LSL Dataserver event to pull notecard data, 1637 /*Instead of using the LSL Dataserver event to pull notecard data,
1634 this will simply read the number of note card lines and return this data as an integer. 1638 this will simply read the number of note card lines and return this data as an integer.
1635 1639
1636 Warning - due to the synchronous method this function uses to fetch assets, its use 1640 Warning - due to the synchronous method this function uses to fetch assets, its use
1637 may be dangerous and unreliable while running in grid mode. 1641 may be dangerous and unreliable while running in grid mode.
1638 */ 1642 */
1639 1643
@@ -1833,7 +1837,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1833 1837
1834 return World.RegionInfo.RegionSettings.LoadedCreationID; 1838 return World.RegionInfo.RegionSettings.LoadedCreationID;
1835 } 1839 }
1836 1840
1837 // Threat level is 'Low' because certain users could possibly be tricked into 1841 // Threat level is 'Low' because certain users could possibly be tricked into
1838 // dropping an unverified script into one of their own objects, which could 1842 // dropping an unverified script into one of their own objects, which could
1839 // then gather the physical construction details of the object and transmit it 1843 // then gather the physical construction details of the object and transmit it
@@ -1857,7 +1861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1857 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom) 1861 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, LSL_Key cloneFrom)
1858 { 1862 {
1859 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 1863 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
1860 //QueueUserWorkItem 1864 //QueueUserWorkItem
1861 1865
1862 INPCModule module = World.RequestModuleInterface<INPCModule>(); 1866 INPCModule module = World.RequestModuleInterface<INPCModule>();
1863 if (module != null) 1867 if (module != null)
@@ -1906,5 +1910,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1906 module.DeleteNPC(new UUID(npc.m_string), World); 1910 module.DeleteNPC(new UUID(npc.m_string), World);
1907 } 1911 }
1908 } 1912 }
1913
1914 /// <summary>
1915 /// Get current region's map texture UUID
1916 /// </summary>
1917 /// <returns></returns>
1918 public LSL_Key osGetMapTexture()
1919 {
1920 CheckThreatLevel(ThreatLevel.None, "osGetMapTexture");
1921 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString();
1922 }
1923
1924 /// <summary>
1925 /// Get a region's map texture UUID by region UUID or name.
1926 /// </summary>
1927 /// <param name="regionName"></param>
1928 /// <returns></returns>
1929 public LSL_Key osGetRegionMapTexture(string regionName)
1930 {
1931 CheckThreatLevel(ThreatLevel.High, "osGetRegionMapTexture");
1932 Scene scene = m_ScriptEngine.World;
1933 UUID key = UUID.Zero;
1934 GridRegion region;
1935
1936 //If string is a key, use it. Otherwise, try to locate region by name.
1937 if (UUID.TryParse(regionName, out key))
1938 region = scene.GridService.GetRegionByUUID(UUID.Zero, key);
1939 else
1940 region = scene.GridService.GetRegionByName(UUID.Zero, regionName);
1941
1942 // If region was found, return the regions map texture key.
1943 if (region != null)
1944 key = region.TerrainImage;
1945
1946 ScriptSleep(1000);
1947
1948 return key.ToString();
1949 }
1909 } 1950 }
1910} 1951}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs
new file mode 100644
index 0000000..e08eca5
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IMOD_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface IMOD_Api
42 {
43 //Module functions
44 string modSendCommand(string modules, string command, string k);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index d8d3c31..2a403bf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
79 79
80 // Avatar Info Commands 80 // Avatar Info Commands
81 string osGetAgentIP(string agent); 81 string osGetAgentIP(string agent);
82 LSL_List osGetAgents(); 82 LSL_List osGetAgents();
83 83
84 // Teleport commands 84 // Teleport commands
85 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 85 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
@@ -127,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
127 string osGetScriptEngineName(); 127 string osGetScriptEngineName();
128 string osGetSimulatorVersion(); 128 string osGetSimulatorVersion();
129 Hashtable osParseJSON(string JSON); 129 Hashtable osParseJSON(string JSON);
130 130
131 void osMessageObject(key objectUUID,string message); 131 void osMessageObject(key objectUUID,string message);
132 132
133 void osMakeNotecard(string notecardName, LSL_Types.list contents); 133 void osMakeNotecard(string notecardName, LSL_Types.list contents);
@@ -138,7 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
138 138
139 string osAvatarName2Key(string firstname, string lastname); 139 string osAvatarName2Key(string firstname, string lastname);
140 string osKey2Name(string id); 140 string osKey2Name(string id);
141 141
142 // Grid Info Functions 142 // Grid Info Functions
143 string osGetGridNick(); 143 string osGetGridNick();
144 string osGetGridName(); 144 string osGetGridName();
@@ -151,7 +151,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
151 string osLoadedCreationDate(); 151 string osLoadedCreationDate();
152 string osLoadedCreationTime(); 152 string osLoadedCreationTime();
153 string osLoadedCreationID(); 153 string osLoadedCreationID();
154 154
155 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); 155 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules);
156 156
157 157
@@ -160,5 +160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
160 void osNpcSay(key npc, string message); 160 void osNpcSay(key npc, string message);
161 void osNpcRemove(key npc); 161 void osNpcRemove(key npc);
162 162
163 key osGetMapTexture();
164 key osGetRegionMapTexture(string regionName);
163 } 165 }
164} 166}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs
new file mode 100644
index 0000000..6525c76
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/MOD_Stub.cs
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public IMOD_Api m_MOD_Functions;
52
53 public void ApiTypeMOD(IScriptApi api)
54 {
55 if (!(api is IMOD_Api))
56 return;
57
58 m_MOD_Functions = (IMOD_Api)api;
59 }
60
61 public string modSendCommand(string module, string command, string k)
62 {
63 return m_MOD_Functions.modSendCommand(module, command, k);
64 }
65 }
66}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 8dcb1f5..4928e90 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
94 { 94 {
95 return m_OSSL_Functions.osWindActiveModelPluginName(); 95 return m_OSSL_Functions.osWindActiveModelPluginName();
96 } 96 }
97 97
98// Not yet plugged in as available OSSL functions, so commented out 98// Not yet plugged in as available OSSL functions, so commented out
99// void osWindParamSet(string plugin, string param, float value) 99// void osWindParamSet(string plugin, string param, float value)
100// { 100// {
@@ -138,14 +138,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
138 public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams, 138 public string osSetDynamicTextureURLBlendFace(string dynamicID, string contentType, string url, string extraParams,
139 bool blend, int disp, int timer, int alpha, int face) 139 bool blend, int disp, int timer, int alpha, int face)
140 { 140 {
141 return m_OSSL_Functions.osSetDynamicTextureURLBlendFace(dynamicID, contentType, url, extraParams, 141 return m_OSSL_Functions.osSetDynamicTextureURLBlendFace(dynamicID, contentType, url, extraParams,
142 blend, disp, timer, alpha, face); 142 blend, disp, timer, alpha, face);
143 } 143 }
144 144
145 public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams, 145 public string osSetDynamicTextureDataBlendFace(string dynamicID, string contentType, string data, string extraParams,
146 bool blend, int disp, int timer, int alpha, int face) 146 bool blend, int disp, int timer, int alpha, int face)
147 { 147 {
148 return m_OSSL_Functions.osSetDynamicTextureDataBlendFace(dynamicID, contentType, data, extraParams, 148 return m_OSSL_Functions.osSetDynamicTextureDataBlendFace(dynamicID, contentType, data, extraParams,
149 blend, disp, timer, alpha, face); 149 blend, disp, timer, alpha, face);
150 } 150 }
151 151
@@ -183,7 +183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
183 { 183 {
184 m_OSSL_Functions.osSetParcelMediaURL(url); 184 m_OSSL_Functions.osSetParcelMediaURL(url);
185 } 185 }
186 186
187 public void osSetParcelSIPAddress(string SIPAddress) 187 public void osSetParcelSIPAddress(string SIPAddress)
188 { 188 {
189 m_OSSL_Functions.osSetParcelSIPAddress(SIPAddress); 189 m_OSSL_Functions.osSetParcelSIPAddress(SIPAddress);
@@ -211,7 +211,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
211 m_OSSL_Functions.osTeleportAgent(agent, position, lookat); 211 m_OSSL_Functions.osTeleportAgent(agent, position, lookat);
212 } 212 }
213 213
214 // Avatar info functions 214 // Avatar info functions
215 public string osGetAgentIP(string agent) 215 public string osGetAgentIP(string agent)
216 { 216 {
217 return m_OSSL_Functions.osGetAgentIP(agent); 217 return m_OSSL_Functions.osGetAgentIP(agent);
@@ -326,17 +326,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
326 { 326 {
327 return m_OSSL_Functions.osGetScriptEngineName(); 327 return m_OSSL_Functions.osGetScriptEngineName();
328 } 328 }
329 329
330 public string osGetSimulatorVersion() 330 public string osGetSimulatorVersion()
331 { 331 {
332 return m_OSSL_Functions.osGetSimulatorVersion(); 332 return m_OSSL_Functions.osGetSimulatorVersion();
333 } 333 }
334 334
335 public Hashtable osParseJSON(string JSON) 335 public Hashtable osParseJSON(string JSON)
336 { 336 {
337 return m_OSSL_Functions.osParseJSON(JSON); 337 return m_OSSL_Functions.osParseJSON(JSON);
338 } 338 }
339 339
340 public void osMessageObject(key objectUUID,string message) 340 public void osMessageObject(key objectUUID,string message)
341 { 341 {
342 m_OSSL_Functions.osMessageObject(objectUUID,message); 342 m_OSSL_Functions.osMessageObject(objectUUID,message);
@@ -412,7 +412,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
412 { 412 {
413 return m_OSSL_Functions.osLoadedCreationID(); 413 return m_OSSL_Functions.osLoadedCreationID();
414 } 414 }
415 415
416 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules) 416 public LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules)
417 { 417 {
418 return m_OSSL_Functions.osGetLinkPrimitiveParams(linknumber, rules); 418 return m_OSSL_Functions.osGetLinkPrimitiveParams(linknumber, rules);
@@ -622,5 +622,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
622 } 622 }
623 } 623 }
624 } 624 }
625
626 public key osGetMapTexture()
627 {
628 return m_OSSL_Functions.osGetMapTexture();
629 }
630
631 public key osGetRegionMapTexture(string regionName)
632 {
633 return m_OSSL_Functions.osGetRegionMapTexture(regionName);
634 }
625 } 635 }
626} 636}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
index feff86a..98bbc68 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp
@@ -20,6 +20,7 @@
20 <File name="./Executor.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 20 <File name="./Executor.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
21 <File name="./LSL_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 21 <File name="./LSL_Constants.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
22 <File name="./LSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 22 <File name="./LSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
23 <File name="./MOD_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
23 <File name="./OSSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 24 <File name="./OSSL_Stub.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
24 <File name="./ScriptBase.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 25 <File name="./ScriptBase.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
25 <File name="./ScriptSponsor.cs" subtype="Code" buildaction="Compile" dependson="" data="" /> 26 <File name="./ScriptSponsor.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index b0fce75..a60c0ba 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -51,7 +51,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance;
51using OpenSim.Region.ScriptEngine.Interfaces; 51using OpenSim.Region.ScriptEngine.Interfaces;
52 52
53using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; 53using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>;
54using Parallel = OpenSim.Framework.Parallel;
55 54
56namespace OpenSim.Region.ScriptEngine.XEngine 55namespace OpenSim.Region.ScriptEngine.XEngine
57{ 56{
@@ -494,7 +493,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine
494 493
495 if (m_CurrentCompile == null) 494 if (m_CurrentCompile == null)
496 { 495 {
497 m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); 496 // NOTE: Although we use a lockless queue, the lock here
497 // is required. It ensures that there are never two
498 // compile threads running, which, due to a race
499 // conndition, might otherwise happen
500 //
501 lock (m_CompileQueue)
502 {
503 if (m_CurrentCompile == null)
504 m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null);
505 }
498 } 506 }
499 } 507 }
500 } 508 }
@@ -514,16 +522,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine
514 } 522 }
515 } 523 }
516 524
517 List<object[]> compiles = new List<object[]>();
518 object[] o; 525 object[] o;
519 while (m_CompileQueue.Dequeue(out o)) 526 while (m_CompileQueue.Dequeue(out o))
527 DoOnRezScript(o);
528
529 // NOTE: Despite having a lockless queue, this lock is required
530 // to make sure there is never no compile thread while there
531 // are still scripts to compile. This could otherwise happen
532 // due to a race condition
533 //
534 lock (m_CompileQueue)
520 { 535 {
521 compiles.Add(o); 536 m_CurrentCompile = null;
522 } 537 }
523
524 Parallel.For(0, compiles.Count, delegate(int i) { DoOnRezScript(compiles[i]); });
525
526 m_CurrentCompile = null;
527 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, 538 m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount,
528 m_ScriptErrorMessage); 539 m_ScriptErrorMessage);
529 m_ScriptFailCount = 0; 540 m_ScriptFailCount = 0;