aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs304
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs10
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs66
5 files changed, 242 insertions, 145 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
index e9e2dca..9dd6663 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
@@ -202,6 +202,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
202 m_stopPacket = TexturePacketCount(); 202 m_stopPacket = TexturePacketCount();
203 } 203 }
204 204
205 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
206 if (m_stopPacket == 1 && Layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
207
205 m_currentPacket = StartPacket; 208 m_currentPacket = StartPacket;
206 } 209 }
207 } 210 }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 2a59a0c..6a76069 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -155,6 +155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
155 public event RequestTaskInventory OnRequestTaskInventory; 155 public event RequestTaskInventory OnRequestTaskInventory;
156 public event UpdateInventoryItem OnUpdateInventoryItem; 156 public event UpdateInventoryItem OnUpdateInventoryItem;
157 public event CopyInventoryItem OnCopyInventoryItem; 157 public event CopyInventoryItem OnCopyInventoryItem;
158 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
158 public event MoveInventoryItem OnMoveInventoryItem; 159 public event MoveInventoryItem OnMoveInventoryItem;
159 public event RemoveInventoryItem OnRemoveInventoryItem; 160 public event RemoveInventoryItem OnRemoveInventoryItem;
160 public event RemoveInventoryFolder OnRemoveInventoryFolder; 161 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -335,6 +336,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
335// protected HashSet<uint> m_attachmentsSent; 336// protected HashSet<uint> m_attachmentsSent;
336 337
337 private int m_moneyBalance; 338 private int m_moneyBalance;
339 private bool m_deliverPackets = true;
338 private int m_animationSequenceNumber = 1; 340 private int m_animationSequenceNumber = 1;
339 private bool m_SendLogoutPacketWhenClosing = true; 341 private bool m_SendLogoutPacketWhenClosing = true;
340 private AgentUpdateArgs lastarg; 342 private AgentUpdateArgs lastarg;
@@ -377,6 +379,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
377 get { return m_startpos; } 379 get { return m_startpos; }
378 set { m_startpos = value; } 380 set { m_startpos = value; }
379 } 381 }
382 public bool DeliverPackets
383 {
384 get { return m_deliverPackets; }
385 set {
386 m_deliverPackets = value;
387 m_udpClient.m_deliverPackets = value;
388 }
389 }
380 public UUID AgentId { get { return m_agentId; } } 390 public UUID AgentId { get { return m_agentId; } }
381 public UUID ActiveGroupId { get { return m_activeGroupID; } } 391 public UUID ActiveGroupId { get { return m_activeGroupID; } }
382 public string ActiveGroupName { get { return m_activeGroupName; } } 392 public string ActiveGroupName { get { return m_activeGroupName; } }
@@ -475,18 +485,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
475 485
476 #region Client Methods 486 #region Client Methods
477 487
488
478 /// <summary> 489 /// <summary>
479 /// Shut down the client view 490 /// Shut down the client view
480 /// </summary> 491 /// </summary>
481 public void Close() 492 public void Close()
482 { 493 {
494 Close(true);
495 }
496
497 /// <summary>
498 /// Shut down the client view
499 /// </summary>
500 public void Close(bool sendStop)
501 {
483 m_log.DebugFormat( 502 m_log.DebugFormat(
484 "[CLIENT]: Close has been called for {0} attached to scene {1}", 503 "[CLIENT]: Close has been called for {0} attached to scene {1}",
485 Name, m_scene.RegionInfo.RegionName); 504 Name, m_scene.RegionInfo.RegionName);
486 505
487 // Send the STOP packet 506 if (sendStop)
488 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 507 {
489 OutPacket(disable, ThrottleOutPacketType.Unknown); 508 // Send the STOP packet
509 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
510 OutPacket(disable, ThrottleOutPacketType.Unknown);
511 }
490 512
491 IsActive = false; 513 IsActive = false;
492 514
@@ -767,7 +789,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
767 reply.ChatData.OwnerID = fromAgentID; 789 reply.ChatData.OwnerID = fromAgentID;
768 reply.ChatData.SourceID = fromAgentID; 790 reply.ChatData.SourceID = fromAgentID;
769 791
770 OutPacket(reply, ThrottleOutPacketType.Task); 792 OutPacket(reply, ThrottleOutPacketType.Unknown);
771 } 793 }
772 794
773 /// <summary> 795 /// <summary>
@@ -1053,6 +1075,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1053 public virtual void SendLayerData(float[] map) 1075 public virtual void SendLayerData(float[] map)
1054 { 1076 {
1055 Util.FireAndForget(DoSendLayerData, map); 1077 Util.FireAndForget(DoSendLayerData, map);
1078
1079 // Send it sync, and async. It's not that much data
1080 // and it improves user experience just so much!
1081 DoSendLayerData(map);
1056 } 1082 }
1057 1083
1058 /// <summary> 1084 /// <summary>
@@ -1065,16 +1091,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1065 1091
1066 try 1092 try
1067 { 1093 {
1068 //for (int y = 0; y < 16; y++) 1094 for (int y = 0; y < 16; y++)
1069 //{ 1095 {
1070 // for (int x = 0; x < 16; x++) 1096 for (int x = 0; x < 16; x+=4)
1071 // { 1097 {
1072 // SendLayerData(x, y, map); 1098 SendLayerPacket(x, y, map);
1073 // } 1099 }
1074 //} 1100 }
1075
1076 // Send LayerData in a spiral pattern. Fun!
1077 SendLayerTopRight(map, 0, 0, 15, 15);
1078 } 1101 }
1079 catch (Exception e) 1102 catch (Exception e)
1080 { 1103 {
@@ -1082,51 +1105,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1082 } 1105 }
1083 } 1106 }
1084 1107
1085 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1086 {
1087 // Row
1088 for (int i = x1; i <= x2; i++)
1089 SendLayerData(i, y1, map);
1090
1091 // Column
1092 for (int j = y1 + 1; j <= y2; j++)
1093 SendLayerData(x2, j, map);
1094
1095 if (x2 - x1 > 0)
1096 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1097 }
1098
1099 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1100 {
1101 // Row in reverse
1102 for (int i = x2; i >= x1; i--)
1103 SendLayerData(i, y2, map);
1104
1105 // Column in reverse
1106 for (int j = y2 - 1; j >= y1; j--)
1107 SendLayerData(x1, j, map);
1108
1109 if (x2 - x1 > 0)
1110 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1111 }
1112
1113 /// <summary> 1108 /// <summary>
1114 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1109 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1115 /// </summary> 1110 /// </summary>
1116 /// <param name="map">heightmap</param> 1111 /// <param name="map">heightmap</param>
1117 /// <param name="px">X coordinate for patches 0..12</param> 1112 /// <param name="px">X coordinate for patches 0..12</param>
1118 /// <param name="py">Y coordinate for patches 0..15</param> 1113 /// <param name="py">Y coordinate for patches 0..15</param>
1119 // private void SendLayerPacket(float[] map, int y, int x) 1114 private void SendLayerPacket(int x, int y, float[] map)
1120 // { 1115 {
1121 // int[] patches = new int[4]; 1116 int[] patches = new int[4];
1122 // patches[0] = x + 0 + y * 16; 1117 patches[0] = x + 0 + y * 16;
1123 // patches[1] = x + 1 + y * 16; 1118 patches[1] = x + 1 + y * 16;
1124 // patches[2] = x + 2 + y * 16; 1119 patches[2] = x + 2 + y * 16;
1125 // patches[3] = x + 3 + y * 16; 1120 patches[3] = x + 3 + y * 16;
1126 1121
1127 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1122 float[] heightmap = (map.Length == 65536) ?
1128 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1123 map :
1129 // } 1124 LLHeightFieldMoronize(map);
1125
1126 try
1127 {
1128 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1129 OutPacket(layerpack, ThrottleOutPacketType.Land);
1130 }
1131 catch
1132 {
1133 for (int px = x ; px < x + 4 ; px++)
1134 SendLayerData(px, y, map);
1135 }
1136 }
1130 1137
1131 /// <summary> 1138 /// <summary>
1132 /// Sends a specified patch to a client 1139 /// Sends a specified patch to a client
@@ -1146,7 +1153,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1146 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1153 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1147 layerpack.Header.Reliable = true; 1154 layerpack.Header.Reliable = true;
1148 1155
1149 OutPacket(layerpack, ThrottleOutPacketType.Land); 1156 OutPacket(layerpack, ThrottleOutPacketType.Task);
1150 } 1157 }
1151 catch (Exception e) 1158 catch (Exception e)
1152 { 1159 {
@@ -1507,35 +1514,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1507 OutPacket(pc, ThrottleOutPacketType.Unknown); 1514 OutPacket(pc, ThrottleOutPacketType.Unknown);
1508 } 1515 }
1509 1516
1510 public void SendKillObject(ulong regionHandle, uint localID) 1517 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1511 { 1518 {
1512// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1519// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle);
1513 1520
1514 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1521 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1515 // TODO: don't create new blocks if recycling an old packet 1522 // TODO: don't create new blocks if recycling an old packet
1516 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; 1523 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count];
1517 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); 1524 for (int i = 0 ; i < localIDs.Count ; i++ )
1518 kill.ObjectData[0].ID = localID; 1525 {
1526 kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock();
1527 kill.ObjectData[i].ID = localIDs[i];
1528 }
1519 kill.Header.Reliable = true; 1529 kill.Header.Reliable = true;
1520 kill.Header.Zerocoded = true; 1530 kill.Header.Zerocoded = true;
1521 1531
1522 if (m_scene.GetScenePresence(localID) == null) 1532 if (localIDs.Count == 1)
1523 { 1533 {
1524 lock (m_entityUpdates.SyncRoot) 1534 if (m_scene.GetScenePresence(localIDs[0]) != null)
1525 { 1535 {
1526 m_killRecord.Add(localID); 1536 OutPacket(kill, ThrottleOutPacketType.State);
1527 1537 return;
1528 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1529 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1530 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1531 // scene objects in a viewer until that viewer is relogged in.
1532 OutPacket(kill, ThrottleOutPacketType.Task);
1533 } 1538 }
1539 m_killRecord.Add(localIDs[0]);
1534 } 1540 }
1535 else 1541 else
1536 { 1542 {
1537 OutPacket(kill, ThrottleOutPacketType.State); 1543 lock (m_entityUpdates.SyncRoot)
1544 {
1545 foreach (uint localID in localIDs)
1546 m_killRecord.Add(localID);
1547 }
1538 } 1548 }
1549
1550 // The throttle queue used here must match that being used for
1551 // updates. Otherwise, there is a chance that a kill packet put
1552 // on a separate queue will be sent to the client before an
1553 // existing update packet on another queue. Receiving updates
1554 // after kills results in unowned and undeletable
1555 // scene objects in a viewer until that viewer is relogged in.
1556 OutPacket(kill, ThrottleOutPacketType.Task);
1539 } 1557 }
1540 1558
1541 /// <summary> 1559 /// <summary>
@@ -2241,6 +2259,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2241 OutPacket(sound, ThrottleOutPacketType.Task); 2259 OutPacket(sound, ThrottleOutPacketType.Task);
2242 } 2260 }
2243 2261
2262 public void SendTransferAbort(TransferRequestPacket transferRequest)
2263 {
2264 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2265 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2266 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2267 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2268 OutPacket(abort, ThrottleOutPacketType.Task);
2269 }
2270
2244 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2271 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2245 { 2272 {
2246 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2273 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -3542,6 +3569,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3542 /// </summary> 3569 /// </summary>
3543 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3570 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3544 { 3571 {
3572 if (entity is SceneObjectPart)
3573 {
3574 SceneObjectPart e = (SceneObjectPart)entity;
3575 SceneObjectGroup g = e.ParentGroup;
3576 if (g.RootPart.Shape.State > 30) // HUD
3577 if (g.OwnerID != AgentId)
3578 return; // Don't send updates for other people's HUDs
3579 }
3580
3545 double priority = m_prioritizer.GetUpdatePriority(this, entity); 3581 double priority = m_prioritizer.GetUpdatePriority(this, entity);
3546 3582
3547 lock (m_entityUpdates.SyncRoot) 3583 lock (m_entityUpdates.SyncRoot)
@@ -3580,13 +3616,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3580 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3616 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3581 // after the root prim has been deleted. 3617 // after the root prim has been deleted.
3582 if (m_killRecord.Contains(part.LocalId)) 3618 if (m_killRecord.Contains(part.LocalId))
3583 {
3584 // m_log.WarnFormat(
3585 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3586 // part.LocalId, Name);
3587 continue; 3619 continue;
3588 } 3620 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3589 3621 continue;
3622
3623 if (part.ParentGroup.IsDeleted)
3624 continue;
3625
3626 if (part.ParentGroup.IsAttachment)
3627 { // Someone else's HUD, why are we getting these?
3628 if (part.ParentGroup.OwnerID != AgentId &&
3629 part.ParentGroup.RootPart.Shape.State >= 30)
3630 continue;
3631 ScenePresence sp;
3632 // Owner is not in the sim, don't update it to
3633 // anyone
3634 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3635 continue;
3636
3637 List<SceneObjectGroup> atts = sp.Attachments;
3638 bool found = false;
3639 foreach (SceneObjectGroup att in atts)
3640 {
3641 if (att == part.ParentGroup)
3642 {
3643 found = true;
3644 break;
3645 }
3646 }
3647
3648 // It's an attachment of a valid avatar, but
3649 // doesn't seem to be attached, skip
3650 if (!found)
3651 continue;
3652 }
3653
3590 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3654 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3591 { 3655 {
3592 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3656 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
@@ -4038,6 +4102,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4038 { 4102 {
4039 m_propertiesPacketTimer.Stop(); 4103 m_propertiesPacketTimer.Stop();
4040 4104
4105 if (m_propertiesBlocks.Count == 0)
4106 return;
4107
4041 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; 4108 proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count];
4042 4109
4043 int index = 0; 4110 int index = 0;
@@ -4429,14 +4496,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4429 4496
4430 if (notifyCount > 0) 4497 if (notifyCount > 0)
4431 { 4498 {
4432 if (notifyCount > 32) 4499// if (notifyCount > 32)
4433 { 4500// {
4434 m_log.InfoFormat( 4501// m_log.InfoFormat(
4435 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4502// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4436 + " - a developer might want to investigate whether this is a hard limit", 32); 4503// + " - a developer might want to investigate whether this is a hard limit", 32);
4437 4504//
4438 notifyCount = 32; 4505// notifyCount = 32;
4439 } 4506// }
4440 4507
4441 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4508 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4442 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4509 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4944,6 +5011,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4944 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5011 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
4945 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5012 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
4946 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5013 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5014 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
4947 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5015 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
4948 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5016 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
4949 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5017 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5043,6 +5111,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5043 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5111 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5044 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5112 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5045 (x.ControlFlags != lastarg.ControlFlags) || 5113 (x.ControlFlags != lastarg.ControlFlags) ||
5114 (x.ControlFlags != 0) ||
5046 (x.Far != lastarg.Far) || 5115 (x.Far != lastarg.Far) ||
5047 (x.Flags != lastarg.Flags) || 5116 (x.Flags != lastarg.Flags) ||
5048 (x.State != lastarg.State) || 5117 (x.State != lastarg.State) ||
@@ -5416,7 +5485,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5416 args.Channel = ch; 5485 args.Channel = ch;
5417 args.From = String.Empty; 5486 args.From = String.Empty;
5418 args.Message = Utils.BytesToString(msg); 5487 args.Message = Utils.BytesToString(msg);
5419 args.Type = ChatTypeEnum.Shout; 5488 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5420 args.Position = new Vector3(); 5489 args.Position = new Vector3();
5421 args.Scene = Scene; 5490 args.Scene = Scene;
5422 args.Sender = this; 5491 args.Sender = this;
@@ -9460,6 +9529,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9460 { 9529 {
9461 return true; 9530 return true;
9462 } 9531 }
9532
9533 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9534 {
9535 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9536
9537 #region Packet Session and User Check
9538 if (m_checkPackets)
9539 {
9540 if (packet.AgentData.SessionID != SessionId ||
9541 packet.AgentData.AgentID != AgentId)
9542 return true;
9543 }
9544 #endregion
9545 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
9546 List<InventoryItemBase> items = new List<InventoryItemBase>();
9547 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
9548 {
9549 InventoryItemBase b = new InventoryItemBase();
9550 b.ID = n.OldItemID;
9551 b.Folder = n.OldFolderID;
9552 items.Add(b);
9553 }
9554
9555 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
9556 if (handlerMoveItemsAndLeaveCopy != null)
9557 {
9558 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
9559 }
9560
9561 return true;
9562 }
9463 9563
9464 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 9564 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9465 { 9565 {
@@ -10458,11 +10558,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10458 10558
10459 StartLure handlerStartLure = OnStartLure; 10559 StartLure handlerStartLure = OnStartLure;
10460 if (handlerStartLure != null) 10560 if (handlerStartLure != null)
10461 handlerStartLure(startLureRequest.Info.LureType, 10561 {
10462 Utils.BytesToString( 10562 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10463 startLureRequest.Info.Message), 10563 {
10464 startLureRequest.TargetData[0].TargetID, 10564 handlerStartLure(startLureRequest.Info.LureType,
10465 this); 10565 Utils.BytesToString(
10566 startLureRequest.Info.Message),
10567 startLureRequest.TargetData[i].TargetID,
10568 this);
10569 }
10570 }
10466 return true; 10571 return true;
10467 } 10572 }
10468 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 10573 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10957,7 +11062,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10957 { 11062 {
10958 // It's a ghost! tell the client to delete it from view. 11063 // It's a ghost! tell the client to delete it from view.
10959 simClient.SendKillObject(Scene.RegionInfo.RegionHandle, 11064 simClient.SendKillObject(Scene.RegionInfo.RegionHandle,
10960 localId); 11065 new List<uint>() { localId });
10961 } 11066 }
10962 else 11067 else
10963 { 11068 {
@@ -11327,22 +11432,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11327 /// <param name="Pack">OpenMetaverse.packet</param> 11432 /// <param name="Pack">OpenMetaverse.packet</param>
11328 public void ProcessInPacket(Packet packet) 11433 public void ProcessInPacket(Packet packet)
11329 { 11434 {
11330 if (m_debugPacketLevel > 0) 11435 if (m_debugPacketLevel >= 255)
11331 { 11436 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11332 bool outputPacket = true;
11333
11334 if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate)
11335 outputPacket = false;
11336
11337 if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage)
11338 outputPacket = false;
11339
11340 if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation))
11341 outputPacket = false;
11342
11343 if (outputPacket)
11344 m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type);
11345 }
11346 11437
11347 if (!ProcessPacketMethod(packet)) 11438 if (!ProcessPacketMethod(packet))
11348 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11439 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
@@ -11584,7 +11675,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11584 11675
11585// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 11676// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11586 11677
11678
11679 //Note, the bool returned from the below function is useless since it is always false.
11587 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 11680 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
11681
11588 } 11682 }
11589 11683
11590 /// <summary> 11684 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index e02783a..5aa9b40 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -149,6 +149,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
149 149
150 private int m_defaultRTO = 3000; 150 private int m_defaultRTO = 3000;
151 private int m_maxRTO = 60000; 151 private int m_maxRTO = 60000;
152 public bool m_deliverPackets = true;
152 153
153 /// <summary> 154 /// <summary>
154 /// Default constructor 155 /// Default constructor
@@ -415,6 +416,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
415 if (category >= 0 && category < m_packetOutboxes.Length) 416 if (category >= 0 && category < m_packetOutboxes.Length)
416 { 417 {
417 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 418 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
419
420 if (m_deliverPackets == false)
421 {
422 queue.Enqueue(packet);
423 return true;
424 }
425
418 TokenBucket bucket = m_throttleCategories[category]; 426 TokenBucket bucket = m_throttleCategories[category];
419 427
420 if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength)) 428 if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength))
@@ -451,6 +459,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
451 /// <returns>True if any packets were sent, otherwise false</returns> 459 /// <returns>True if any packets were sent, otherwise false</returns>
452 public bool DequeueOutgoing() 460 public bool DequeueOutgoing()
453 { 461 {
462 if (m_deliverPackets == false) return false;
463
454 OutgoingPacket packet; 464 OutgoingPacket packet;
455 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 465 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
456 TokenBucket bucket; 466 TokenBucket bucket;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 149ae9e..7396c2d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -952,7 +952,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
952 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 952 if (m_scene.TryGetClient(udpClient.AgentID, out client))
953 { 953 {
954 client.IsLoggingOut = true; 954 client.IsLoggingOut = true;
955 client.Close(); 955 client.Close(false);
956 } 956 }
957 } 957 }
958 958
@@ -964,6 +964,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
964 964
965 while (base.IsRunning) 965 while (base.IsRunning)
966 { 966 {
967 m_scene.ThreadAlive(1);
967 try 968 try
968 { 969 {
969 IncomingPacket incomingPacket = null; 970 IncomingPacket incomingPacket = null;
@@ -1006,6 +1007,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1006 1007
1007 while (base.IsRunning) 1008 while (base.IsRunning)
1008 { 1009 {
1010 m_scene.ThreadAlive(2);
1009 try 1011 try
1010 { 1012 {
1011 m_packetSent = false; 1013 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
index bdbd284..91e3d20 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
@@ -133,7 +133,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
133 this.parent = parent; 133 this.parent = parent;
134 MaxBurst = maxBurst; 134 MaxBurst = maxBurst;
135 DripRate = dripRate; 135 DripRate = dripRate;
136 lastDrip = Environment.TickCount & Int32.MaxValue; 136 lastDrip = Environment.TickCount;
137 } 137 }
138 138
139 /// <summary> 139 /// <summary>
@@ -144,40 +144,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
144 /// the bucket, otherwise false</returns> 144 /// the bucket, otherwise false</returns>
145 public bool RemoveTokens(int amount) 145 public bool RemoveTokens(int amount)
146 { 146 {
147 bool dummy;
148 return RemoveTokens(amount, out dummy);
149 }
150
151 /// <summary>
152 /// Remove a given number of tokens from the bucket
153 /// </summary>
154 /// <param name="amount">Number of tokens to remove from the bucket</param>
155 /// <param name="dripSucceeded">True if tokens were added to the bucket
156 /// during this call, otherwise false</param>
157 /// <returns>True if the requested number of tokens were removed from
158 /// the bucket, otherwise false</returns>
159 public bool RemoveTokens(int amount, out bool dripSucceeded)
160 {
161 if (maxBurst == 0) 147 if (maxBurst == 0)
162 { 148 {
163 dripSucceeded = true;
164 return true; 149 return true;
165 } 150 }
166 151
167 dripSucceeded = Drip(); 152 if (amount > maxBurst)
168
169 if (content - amount >= 0)
170 { 153 {
171 if (parent != null && !parent.RemoveTokens(amount)) 154 throw new Exception("amount " + amount + " exceeds maxBurst " + maxBurst);
172 return false; 155 }
173 156
174 content -= amount; 157 Drip();
175 return true; 158
159 if (content < amount)
160 {
161 return false;
176 } 162 }
177 else 163
164 if (parent != null && !parent.RemoveTokens(amount))
178 { 165 {
179 return false; 166 return false;
180 } 167 }
168
169 content -= amount;
170 return true;
181 } 171 }
182 172
183 /// <summary> 173 /// <summary>
@@ -193,25 +183,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
193 content = maxBurst; 183 content = maxBurst;
194 return true; 184 return true;
195 } 185 }
196 else
197 {
198 int now = Environment.TickCount & Int32.MaxValue;
199 int deltaMS = now - lastDrip;
200 186
201 if (deltaMS <= 0) 187 int now = Environment.TickCount;
202 { 188 int deltaMS = now - lastDrip;
203 if (deltaMS < 0) 189 lastDrip = now;
204 lastDrip = now;
205 return false;
206 }
207 190
208 int dripAmount = deltaMS * tokensPerMS; 191 if (deltaMS <= 0)
209 192 {
210 content = Math.Min(content + dripAmount, maxBurst); 193 return false;
211 lastDrip = now; 194 }
212 195
213 return true; 196 long dripAmount = (long)deltaMS * (long)tokensPerMS + (long)content;
197 if (dripAmount > maxBurst)
198 {
199 dripAmount = maxBurst;
214 } 200 }
201 content = (int)dripAmount;
202 return true;
215 } 203 }
216 } 204 }
217} 205}