aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-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
4 files changed, 269 insertions, 173 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) { }