diff options
author | Melanie | 2009-11-04 01:56:19 +0000 |
---|---|---|
committer | Melanie | 2009-11-04 01:56:19 +0000 |
commit | c72f78215bb3435ee2bbb507746c23eccec4dd34 (patch) | |
tree | 468f870831bdb78d35475aaf70b168b868b441ae /OpenSim/Region/ClientStack | |
parent | Remove parallel loading from XEngine, but retain the new design where (diff) | |
download | opensim-SC-c72f78215bb3435ee2bbb507746c23eccec4dd34.zip opensim-SC-c72f78215bb3435ee2bbb507746c23eccec4dd34.tar.gz opensim-SC-c72f78215bb3435ee2bbb507746c23eccec4dd34.tar.bz2 opensim-SC-c72f78215bb3435ee2bbb507746c23eccec4dd34.tar.xz |
Backport the fixes to WebFetchInventoryDescendents to the UDP
InventoryDescendents packet. Testing has shown that UDP inventory now
works flawlessly and, unlike CAPS inventory, doesn't download the entire
agent inventory on start. Neither does it incessantly re-request folder
NULL_KEY. Therefore, I have disabled CAPS inventory.
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 246 |
1 files changed, 94 insertions, 152 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index db0c3b8..bd5df19 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -1251,7 +1251,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1251 | /// <param name="fetchFolders">Do we need to send folder information?</param> | 1251 | /// <param name="fetchFolders">Do we need to send folder information?</param> |
1252 | /// <param name="fetchItems">Do we need to send item information?</param> | 1252 | /// <param name="fetchItems">Do we need to send item information?</param> |
1253 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, | 1253 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, |
1254 | List<InventoryFolderBase> folders, | 1254 | List<InventoryFolderBase> folders, int version, |
1255 | bool fetchFolders, bool fetchItems) | 1255 | bool fetchFolders, bool fetchItems) |
1256 | { | 1256 | { |
1257 | // An inventory descendents packet consists of a single agent section and an inventory details | 1257 | // An inventory descendents packet consists of a single agent section and an inventory details |
@@ -1266,172 +1266,104 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1266 | // 6 to 7 items at a time, so let's stick with 6 | 1266 | // 6 to 7 items at a time, so let's stick with 6 |
1267 | int MAX_ITEMS_PER_PACKET = 6; | 1267 | int MAX_ITEMS_PER_PACKET = 6; |
1268 | 1268 | ||
1269 | //Ckrinke This variable is not used, so comment out to remove the warning from the compiler (3-21-08) | 1269 | int totalItems = fetchItems ? items.Count : 0; |
1270 | //Ckrinke uint FULL_MASK_PERMISSIONS = 2147483647; | 1270 | int totalFolders = fetchFolders ? folders.Count : 0; |
1271 | |||
1272 | int itemsSent = 0; | 1271 | int itemsSent = 0; |
1273 | if (fetchItems) | 1272 | int foldersSent = 0; |
1274 | { | 1273 | int foldersToSend = 0; |
1275 | InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); | 1274 | int itemsToSend = 0; |
1276 | |||
1277 | if (items.Count < MAX_ITEMS_PER_PACKET) | ||
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 | 1275 | ||
1286 | // Descendents must contain the *total* number of descendents (plus folders, whether we | 1276 | InventoryDescendentsPacket currentPacket = null; |
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 | 1277 | ||
1293 | int count = 0; | 1278 | // Handle empty folders |
1294 | int i = 0; | 1279 | // |
1295 | foreach (InventoryItemBase item in items) | 1280 | if (totalItems == 0 && totalFolders == 0) |
1281 | currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, 0, 0); | ||
1282 | |||
1283 | // To preserve SL compatibility, we will NOT combine folders and items in one packet | ||
1284 | // | ||
1285 | while(itemsSent < totalItems || foldersSent < totalFolders) | ||
1286 | { | ||
1287 | if (currentPacket == null) // Start a new packet | ||
1296 | { | 1288 | { |
1297 | descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock(); | 1289 | foldersToSend = totalFolders - foldersSent; |
1298 | descend.ItemData[i].ItemID = item.ID; | 1290 | if (foldersToSend > MAX_ITEMS_PER_PACKET) |
1299 | descend.ItemData[i].AssetID = item.AssetID; | 1291 | foldersToSend = MAX_ITEMS_PER_PACKET; |
1300 | descend.ItemData[i].CreatorID = item.CreatorIdAsUuid; | 1292 | |
1301 | descend.ItemData[i].BaseMask = item.BasePermissions; | 1293 | if (foldersToSend == 0) |
1302 | descend.ItemData[i].Description = Util.StringToBytes256(item.Description); | 1294 | { |
1303 | descend.ItemData[i].EveryoneMask = item.EveryOnePermissions; | 1295 | itemsToSend = totalItems - itemsSent; |
1304 | descend.ItemData[i].OwnerMask = item.CurrentPermissions; | 1296 | if (itemsToSend > MAX_ITEMS_PER_PACKET) |
1305 | descend.ItemData[i].FolderID = item.Folder; | 1297 | 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 | } | 1298 | } |
1355 | } | ||
1356 | 1299 | ||
1357 | if (0 < i && i < MAX_ITEMS_PER_PACKET) | 1300 | currentPacket = CreateInventoryDescendentsPacket(ownerID, folderID, version, foldersToSend, itemsToSend); |
1358 | { | ||
1359 | AddNullFolderBlockToDecendentsPacket(ref descend); | ||
1360 | OutPacket(descend, ThrottleOutPacketType.Asset); | ||
1361 | } | 1301 | } |
1362 | } | ||
1363 | |||
1364 | //send subfolders | ||
1365 | if (fetchFolders) | ||
1366 | { | ||
1367 | InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); | ||
1368 | 1302 | ||
1369 | if (folders.Count < MAX_ITEMS_PER_PACKET) | 1303 | if (foldersToSend-- > 0) |
1370 | { | 1304 | currentPacket.FolderData[foldersSent % MAX_ITEMS_PER_PACKET] = CreateFolderDataBlock(folders[foldersSent++]); |
1371 | descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[folders.Count]; | 1305 | else if(itemsToSend-- > 0) |
1372 | } | 1306 | currentPacket.ItemData[itemsSent % MAX_ITEMS_PER_PACKET] = CreateItemDataBlock(items[itemsSent++]); |
1373 | else | 1307 | else |
1374 | { | 1308 | { |
1375 | descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[MAX_ITEMS_PER_PACKET]; | 1309 | OutPacket(currentPacket, ThrottleOutPacketType.Asset); |
1310 | currentPacket = null; | ||
1376 | } | 1311 | } |
1377 | 1312 | ||
1378 | // Not sure if this scenario ever actually occurs, but nonetheless we include the items | 1313 | } |
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 | 1314 | ||
1382 | int i = 0; | 1315 | if (currentPacket != null) |
1383 | int count = 0; | 1316 | OutPacket(currentPacket, ThrottleOutPacketType.Asset); |
1384 | foreach (InventoryFolderBase folder in folders) | 1317 | } |
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 | 1318 | ||
1392 | i++; | 1319 | private InventoryDescendentsPacket.FolderDataBlock CreateFolderDataBlock(InventoryFolderBase folder) |
1393 | count++; | 1320 | { |
1394 | itemsSent++; | 1321 | InventoryDescendentsPacket.FolderDataBlock newBlock = new InventoryDescendentsPacket.FolderDataBlock(); |
1395 | if (i == MAX_ITEMS_PER_PACKET) | 1322 | newBlock.FolderID = folder.ID; |
1396 | { | 1323 | newBlock.Name = Util.StringToBytes256(folder.Name); |
1397 | AddNullItemBlockToDescendentsPacket(ref descend); | 1324 | newBlock.ParentID = folder.ParentID; |
1398 | OutPacket(descend, ThrottleOutPacketType.Asset); | 1325 | newBlock.Type = (sbyte)folder.Type; |
1399 | 1326 | ||
1400 | if ((folders.Count - count) > 0) | 1327 | return newBlock; |
1401 | { | 1328 | } |
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 | 1329 | ||
1419 | if (0 < i && i < MAX_ITEMS_PER_PACKET) | 1330 | private InventoryDescendentsPacket.ItemDataBlock CreateItemDataBlock(InventoryItemBase item) |
1420 | { | 1331 | { |
1421 | AddNullItemBlockToDescendentsPacket(ref descend); | 1332 | InventoryDescendentsPacket.ItemDataBlock newBlock = new InventoryDescendentsPacket.ItemDataBlock(); |
1422 | OutPacket(descend, ThrottleOutPacketType.Asset); | 1333 | newBlock.ItemID = item.ID; |
1423 | } | 1334 | newBlock.AssetID = item.AssetID; |
1424 | } | 1335 | newBlock.CreatorID = item.CreatorIdAsUuid; |
1336 | newBlock.BaseMask = item.BasePermissions; | ||
1337 | newBlock.Description = Util.StringToBytes256(item.Description); | ||
1338 | newBlock.EveryoneMask = item.EveryOnePermissions; | ||
1339 | newBlock.OwnerMask = item.CurrentPermissions; | ||
1340 | newBlock.FolderID = item.Folder; | ||
1341 | newBlock.InvType = (sbyte)item.InvType; | ||
1342 | newBlock.Name = Util.StringToBytes256(item.Name); | ||
1343 | newBlock.NextOwnerMask = item.NextPermissions; | ||
1344 | newBlock.OwnerID = item.Owner; | ||
1345 | newBlock.Type = (sbyte)item.AssetType; | ||
1425 | 1346 | ||
1426 | if (itemsSent == 0) | 1347 | newBlock.GroupID = item.GroupID; |
1427 | { | 1348 | newBlock.GroupOwned = item.GroupOwned; |
1428 | // no items found. | 1349 | newBlock.GroupMask = item.GroupPermissions; |
1429 | InventoryDescendentsPacket descend = CreateInventoryDescendentsPacket(ownerID, folderID); | 1350 | newBlock.CreationDate = item.CreationDate; |
1430 | descend.AgentData.Descendents = 0; | 1351 | newBlock.SalePrice = item.SalePrice; |
1431 | AddNullItemBlockToDescendentsPacket(ref descend); | 1352 | newBlock.SaleType = item.SaleType; |
1432 | AddNullFolderBlockToDecendentsPacket(ref descend); | 1353 | newBlock.Flags = item.Flags; |
1433 | OutPacket(descend, ThrottleOutPacketType.Asset); | 1354 | |
1434 | } | 1355 | newBlock.CRC = |
1356 | Helpers.InventoryCRC(newBlock.CreationDate, newBlock.SaleType, | ||
1357 | newBlock.InvType, newBlock.Type, | ||
1358 | newBlock.AssetID, newBlock.GroupID, | ||
1359 | newBlock.SalePrice, | ||
1360 | newBlock.OwnerID, newBlock.CreatorID, | ||
1361 | newBlock.ItemID, newBlock.FolderID, | ||
1362 | newBlock.EveryoneMask, | ||
1363 | newBlock.Flags, newBlock.OwnerMask, | ||
1364 | newBlock.GroupMask, newBlock.NextOwnerMask); | ||
1365 | |||
1366 | return newBlock; | ||
1435 | } | 1367 | } |
1436 | 1368 | ||
1437 | private void AddNullFolderBlockToDecendentsPacket(ref InventoryDescendentsPacket packet) | 1369 | private void AddNullFolderBlockToDecendentsPacket(ref InventoryDescendentsPacket packet) |
@@ -1473,14 +1405,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1473 | // No need to add CRC | 1405 | // No need to add CRC |
1474 | } | 1406 | } |
1475 | 1407 | ||
1476 | private InventoryDescendentsPacket CreateInventoryDescendentsPacket(UUID ownerID, UUID folderID) | 1408 | private InventoryDescendentsPacket CreateInventoryDescendentsPacket(UUID ownerID, UUID folderID, int version, int folders, int items) |
1477 | { | 1409 | { |
1478 | InventoryDescendentsPacket descend = (InventoryDescendentsPacket)PacketPool.Instance.GetPacket(PacketType.InventoryDescendents); | 1410 | InventoryDescendentsPacket descend = (InventoryDescendentsPacket)PacketPool.Instance.GetPacket(PacketType.InventoryDescendents); |
1479 | descend.Header.Zerocoded = true; | 1411 | descend.Header.Zerocoded = true; |
1480 | descend.AgentData.AgentID = AgentId; | 1412 | descend.AgentData.AgentID = AgentId; |
1481 | descend.AgentData.OwnerID = ownerID; | 1413 | descend.AgentData.OwnerID = ownerID; |
1482 | descend.AgentData.FolderID = folderID; | 1414 | descend.AgentData.FolderID = folderID; |
1483 | descend.AgentData.Version = 1; | 1415 | descend.AgentData.Version = version; |
1416 | |||
1417 | if (folders > 0) | ||
1418 | descend.FolderData = new InventoryDescendentsPacket.FolderDataBlock[folders]; | ||
1419 | else | ||
1420 | AddNullFolderBlockToDecendentsPacket(ref descend); | ||
1421 | |||
1422 | if (items > 0) | ||
1423 | descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[items]; | ||
1424 | else | ||
1425 | AddNullItemBlockToDescendentsPacket(ref descend); | ||
1484 | 1426 | ||
1485 | return descend; | 1427 | return descend; |
1486 | } | 1428 | } |