aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs159
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs8
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs20
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs1079
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs4
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
8 files changed, 856 insertions, 486 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 8ec2f20..ef6dedb 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -96,7 +96,10 @@ namespace OpenSim.Region.ClientStack.Linden
96 // private static readonly string m_fetchInventoryPath = "0006/"; 96 // private static readonly string m_fetchInventoryPath = "0006/";
97 private static readonly string m_copyFromNotecardPath = "0007/"; 97 private static readonly string m_copyFromNotecardPath = "0007/";
98 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. 98 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
99 99 private static readonly string m_getObjectPhysicsDataPath = "0101/";
100 private static readonly string m_getObjectCostPath = "0102/";
101 private static readonly string m_ResourceCostSelectedPath = "0103/";
102
100 103
101 // These are callbacks which will be setup by the scene so that we can update scene data when we 104 // These are callbacks which will be setup by the scene so that we can update scene data when we
102 // receive capability calls 105 // receive capability calls
@@ -186,7 +189,14 @@ namespace OpenSim.Region.ClientStack.Linden
186 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 189 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
187 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 190 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
188 m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard)); 191 m_HostCapsObj.RegisterHandler("CopyInventoryFromNotecard", new RestStreamHandler("POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard));
189 192 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
193 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
194 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
195 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
196 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
197 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
198
199
190 // As of RC 1.22.9 of the Linden client this is 200 // As of RC 1.22.9 of the Linden client this is
191 // supported 201 // supported
192 202
@@ -819,6 +829,151 @@ namespace OpenSim.Region.ClientStack.Linden
819 response["int_response_code"] = 200; 829 response["int_response_code"] = 200;
820 return LLSDHelpers.SerialiseLLSDReply(response); 830 return LLSDHelpers.SerialiseLLSDReply(response);
821 } 831 }
832
833 public string GetObjectPhysicsData(string request, string path,
834 string param, IOSHttpRequest httpRequest,
835 IOSHttpResponse httpResponse)
836 {
837 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
838 OSDMap resp = new OSDMap();
839 OSDArray object_ids = (OSDArray)req["object_ids"];
840
841 for (int i = 0 ; i < object_ids.Count ; i++)
842 {
843 UUID uuid = object_ids[i].AsUUID();
844
845 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
846 if (obj != null)
847 {
848 OSDMap object_data = new OSDMap();
849
850 object_data["PhysicsShapeType"] = obj.PhysicsShapeType;
851 object_data["Density"] = obj.Density;
852 object_data["Friction"] = obj.Friction;
853 object_data["Restitution"] = obj.Bounciness;
854 object_data["GravityMultiplier"] = obj.GravityModifier;
855
856 resp[uuid.ToString()] = object_data;
857 }
858 }
859
860 string response = OSDParser.SerializeLLSDXmlString(resp);
861 return response;
862 }
863
864 public string GetObjectCost(string request, string path,
865 string param, IOSHttpRequest httpRequest,
866 IOSHttpResponse httpResponse)
867 {
868 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
869 OSDMap resp = new OSDMap();
870
871 OSDArray object_ids = (OSDArray)req["object_ids"];
872
873 for (int i = 0; i < object_ids.Count; i++)
874 {
875 UUID uuid = object_ids[i].AsUUID();
876
877 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
878
879 if (part != null)
880 {
881 SceneObjectGroup grp = part.ParentGroup;
882 if (grp != null)
883 {
884 float linksetCost;
885 float linksetPhysCost;
886 float partCost;
887 float partPhysCost;
888
889 grp.GetResourcesCosts(part, out linksetCost, out linksetPhysCost, out partCost, out partPhysCost);
890
891 OSDMap object_data = new OSDMap();
892 object_data["linked_set_resource_cost"] = linksetCost;
893 object_data["resource_cost"] = partCost;
894 object_data["physics_cost"] = partPhysCost;
895 object_data["linked_set_physics_cost"] = linksetPhysCost;
896
897 resp[uuid.ToString()] = object_data;
898 }
899 }
900 }
901
902 string response = OSDParser.SerializeLLSDXmlString(resp);
903 return response;
904 }
905
906 public string ResourceCostSelected(string request, string path,
907 string param, IOSHttpRequest httpRequest,
908 IOSHttpResponse httpResponse)
909 {
910 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
911 OSDMap resp = new OSDMap();
912
913
914 float phys=0;
915 float stream=0;
916 float simul=0;
917
918 if (req.ContainsKey("selected_roots"))
919 {
920 OSDArray object_ids = (OSDArray)req["selected_roots"];
921
922 // should go by SOG suming costs for all parts
923 // ll v3 works ok with several objects select we get the list and adds ok
924 // FS calls per object so results are wrong guess fs bug
925 for (int i = 0; i < object_ids.Count; i++)
926 {
927 UUID uuid = object_ids[i].AsUUID();
928 float Physc;
929 float simulc;
930 float streamc;
931
932 SceneObjectGroup grp = m_Scene.GetGroupByPrim(uuid);
933 if (grp != null)
934 {
935 grp.GetSelectedCosts(out Physc, out streamc, out simulc);
936 phys += Physc;
937 stream += streamc;
938 simul += simulc;
939 }
940 }
941 }
942 else if (req.ContainsKey("selected_prims"))
943 {
944 OSDArray object_ids = (OSDArray)req["selected_prims"];
945
946 // don't see in use in any of the 2 viewers
947 // guess it should be for edit linked but... nothing
948 // should go to SOP per part
949 for (int i = 0; i < object_ids.Count; i++)
950 {
951 UUID uuid = object_ids[i].AsUUID();
952
953 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
954 if (part != null)
955 {
956 phys += part.PhysicsCost;
957 stream += part.StreamingCost;
958 simul += part.SimulationCost;
959 }
960 }
961 }
962
963 if (simul != 0)
964 {
965 OSDMap object_data = new OSDMap();
966
967 object_data["physics"] = phys;
968 object_data["streaming"] = stream;
969 object_data["simulation"] = simul;
970
971 resp["selected"] = object_data;
972 }
973
974 string response = OSDParser.SerializeLLSDXmlString(resp);
975 return response;
976 }
822 } 977 }
823 978
824 public class AssetUploader 979 public class AssetUploader
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 7c07c56..a91b02c 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -805,5 +805,13 @@ namespace OpenSim.Region.ClientStack.Linden
805 { 805 {
806 return EventQueueHelper.BuildEvent(eventName, eventBody); 806 return EventQueueHelper.BuildEvent(eventName, eventBody);
807 } 807 }
808
809 public void partPhysicsProperties(uint localID, byte physhapetype,
810 float density, float friction, float bounce, float gravmod,UUID avatarID)
811 {
812 OSD item = EventQueueHelper.partPhysicsProperties(localID, physhapetype,
813 density, friction, bounce, gravmod);
814 Enqueue(item, avatarID);
815 }
808 } 816 }
809} 817}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
index 3f49aba..b9222e3 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
@@ -395,5 +395,25 @@ namespace OpenSim.Region.ClientStack.Linden
395 return message; 395 return message;
396 } 396 }
397 397
398 public static OSD partPhysicsProperties(uint localID, byte physhapetype,
399 float density, float friction, float bounce, float gravmod)
400 {
401
402 OSDMap physinfo = new OSDMap(6);
403 physinfo["LocalID"] = localID;
404 physinfo["Density"] = density;
405 physinfo["Friction"] = friction;
406 physinfo["GravityMultiplier"] = gravmod;
407 physinfo["Restitution"] = bounce;
408 physinfo["PhysicsShapeType"] = (int)physhapetype;
409
410 OSDArray array = new OSDArray(1);
411 array.Add(physinfo);
412
413 OSDMap llsdBody = new OSDMap(1);
414 llsdBody.Add("ObjectData", array);
415
416 return BuildEvent("ObjectPhysicsProperties", llsdBody);
417 }
398 } 418 }
399} 419}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
index afbe56b..3995620 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs
@@ -234,6 +234,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
234 m_stopPacket = TexturePacketCount(); 234 m_stopPacket = TexturePacketCount();
235 } 235 }
236 236
237 //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way)
238 if (m_stopPacket == 1 && m_layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++;
239
237 m_currentPacket = StartPacket; 240 m_currentPacket = StartPacket;
238 } 241 }
239 } 242 }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 3470fa9..3118613 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -125,6 +125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
126 public event UpdatePrimFlags OnUpdatePrimFlags; 126 public event UpdatePrimFlags OnUpdatePrimFlags;
127 public event UpdatePrimTexture OnUpdatePrimTexture; 127 public event UpdatePrimTexture OnUpdatePrimTexture;
128 public event ClientChangeObject onClientChangeObject;
128 public event UpdateVector OnUpdatePrimGroupPosition; 129 public event UpdateVector OnUpdatePrimGroupPosition;
129 public event UpdateVector OnUpdatePrimSinglePosition; 130 public event UpdateVector OnUpdatePrimSinglePosition;
130 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 131 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -158,6 +159,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 159 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 160 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 161 public event CopyInventoryItem OnCopyInventoryItem;
162 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 163 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 164 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 165 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -256,7 +258,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 258 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 259 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 260 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 261 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 262 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 263 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 264 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +289,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 289 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 290 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 291 public event SendPostcard OnSendPostcard;
292 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 293 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 294 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 295 public event GodlikeMessage onGodlikeMessage;
@@ -336,7 +339,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 339 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
337 /// ownerless phantom. 340 /// ownerless phantom.
338 /// 341 ///
339 /// All manipulation of this set has to occur under a lock 342 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
340 /// 343 ///
341 /// </value> 344 /// </value>
342 protected HashSet<uint> m_killRecord; 345 protected HashSet<uint> m_killRecord;
@@ -344,6 +347,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
344// protected HashSet<uint> m_attachmentsSent; 347// protected HashSet<uint> m_attachmentsSent;
345 348
346 private int m_moneyBalance; 349 private int m_moneyBalance;
350 private bool m_deliverPackets = true;
347 private int m_animationSequenceNumber = 1; 351 private int m_animationSequenceNumber = 1;
348 private bool m_SendLogoutPacketWhenClosing = true; 352 private bool m_SendLogoutPacketWhenClosing = true;
349 private AgentUpdateArgs lastarg; 353 private AgentUpdateArgs lastarg;
@@ -383,6 +387,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
383 get { return m_startpos; } 387 get { return m_startpos; }
384 set { m_startpos = value; } 388 set { m_startpos = value; }
385 } 389 }
390 public bool DeliverPackets
391 {
392 get { return m_deliverPackets; }
393 set {
394 m_deliverPackets = value;
395 m_udpClient.m_deliverPackets = value;
396 }
397 }
386 public UUID AgentId { get { return m_agentId; } } 398 public UUID AgentId { get { return m_agentId; } }
387 public ISceneAgent SceneAgent { get; set; } 399 public ISceneAgent SceneAgent { get; set; }
388 public UUID ActiveGroupId { get { return m_activeGroupID; } } 400 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -485,18 +497,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
485 497
486 #region Client Methods 498 #region Client Methods
487 499
500
488 /// <summary> 501 /// <summary>
489 /// Shut down the client view 502 /// Shut down the client view
490 /// </summary> 503 /// </summary>
491 public void Close() 504 public void Close()
492 { 505 {
506 Close(true);
507 }
508
509 /// <summary>
510 /// Shut down the client view
511 /// </summary>
512 public void Close(bool sendStop)
513 {
493 m_log.DebugFormat( 514 m_log.DebugFormat(
494 "[CLIENT]: Close has been called for {0} attached to scene {1}", 515 "[CLIENT]: Close has been called for {0} attached to scene {1}",
495 Name, m_scene.RegionInfo.RegionName); 516 Name, m_scene.RegionInfo.RegionName);
496 517
497 // Send the STOP packet 518 if (sendStop)
498 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 519 {
499 OutPacket(disable, ThrottleOutPacketType.Unknown); 520 // Send the STOP packet
521 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
522 OutPacket(disable, ThrottleOutPacketType.Unknown);
523 }
500 524
501 IsActive = false; 525 IsActive = false;
502 526
@@ -796,7 +820,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
796 reply.ChatData.OwnerID = fromAgentID; 820 reply.ChatData.OwnerID = fromAgentID;
797 reply.ChatData.SourceID = fromAgentID; 821 reply.ChatData.SourceID = fromAgentID;
798 822
799 OutPacket(reply, ThrottleOutPacketType.Task); 823 OutPacket(reply, ThrottleOutPacketType.Unknown);
800 } 824 }
801 825
802 /// <summary> 826 /// <summary>
@@ -1082,6 +1106,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1082 public virtual void SendLayerData(float[] map) 1106 public virtual void SendLayerData(float[] map)
1083 { 1107 {
1084 Util.FireAndForget(DoSendLayerData, map); 1108 Util.FireAndForget(DoSendLayerData, map);
1109
1110 // Send it sync, and async. It's not that much data
1111 // and it improves user experience just so much!
1112 DoSendLayerData(map);
1085 } 1113 }
1086 1114
1087 /// <summary> 1115 /// <summary>
@@ -1094,16 +1122,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1094 1122
1095 try 1123 try
1096 { 1124 {
1097 //for (int y = 0; y < 16; y++) 1125 for (int y = 0; y < 16; y++)
1098 //{ 1126 {
1099 // for (int x = 0; x < 16; x++) 1127 for (int x = 0; x < 16; x+=4)
1100 // { 1128 {
1101 // SendLayerData(x, y, map); 1129 SendLayerPacket(x, y, map);
1102 // } 1130 }
1103 //} 1131 }
1104
1105 // Send LayerData in a spiral pattern. Fun!
1106 SendLayerTopRight(map, 0, 0, 15, 15);
1107 } 1132 }
1108 catch (Exception e) 1133 catch (Exception e)
1109 { 1134 {
@@ -1111,51 +1136,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1111 } 1136 }
1112 } 1137 }
1113 1138
1114 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1115 {
1116 // Row
1117 for (int i = x1; i <= x2; i++)
1118 SendLayerData(i, y1, map);
1119
1120 // Column
1121 for (int j = y1 + 1; j <= y2; j++)
1122 SendLayerData(x2, j, map);
1123
1124 if (x2 - x1 > 0)
1125 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1126 }
1127
1128 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1129 {
1130 // Row in reverse
1131 for (int i = x2; i >= x1; i--)
1132 SendLayerData(i, y2, map);
1133
1134 // Column in reverse
1135 for (int j = y2 - 1; j >= y1; j--)
1136 SendLayerData(x1, j, map);
1137
1138 if (x2 - x1 > 0)
1139 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1140 }
1141
1142 /// <summary> 1139 /// <summary>
1143 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1140 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1144 /// </summary> 1141 /// </summary>
1145 /// <param name="map">heightmap</param> 1142 /// <param name="map">heightmap</param>
1146 /// <param name="px">X coordinate for patches 0..12</param> 1143 /// <param name="px">X coordinate for patches 0..12</param>
1147 /// <param name="py">Y coordinate for patches 0..15</param> 1144 /// <param name="py">Y coordinate for patches 0..15</param>
1148 // private void SendLayerPacket(float[] map, int y, int x) 1145 private void SendLayerPacket(int x, int y, float[] map)
1149 // { 1146 {
1150 // int[] patches = new int[4]; 1147 int[] patches = new int[4];
1151 // patches[0] = x + 0 + y * 16; 1148 patches[0] = x + 0 + y * 16;
1152 // patches[1] = x + 1 + y * 16; 1149 patches[1] = x + 1 + y * 16;
1153 // patches[2] = x + 2 + y * 16; 1150 patches[2] = x + 2 + y * 16;
1154 // patches[3] = x + 3 + y * 16; 1151 patches[3] = x + 3 + y * 16;
1155 1152
1156 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1153 float[] heightmap = (map.Length == 65536) ?
1157 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1154 map :
1158 // } 1155 LLHeightFieldMoronize(map);
1156
1157 try
1158 {
1159 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1160 OutPacket(layerpack, ThrottleOutPacketType.Land);
1161 }
1162 catch
1163 {
1164 for (int px = x ; px < x + 4 ; px++)
1165 SendLayerData(px, y, map);
1166 }
1167 }
1159 1168
1160 /// <summary> 1169 /// <summary>
1161 /// Sends a specified patch to a client 1170 /// Sends a specified patch to a client
@@ -1175,7 +1184,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1175 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1184 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1176 layerpack.Header.Reliable = true; 1185 layerpack.Header.Reliable = true;
1177 1186
1178 OutPacket(layerpack, ThrottleOutPacketType.Land); 1187 OutPacket(layerpack, ThrottleOutPacketType.Task);
1179 } 1188 }
1180 catch (Exception e) 1189 catch (Exception e)
1181 { 1190 {
@@ -1538,7 +1547,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1538 1547
1539 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1548 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1540 { 1549 {
1541// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1550// foreach (uint id in localIDs)
1551// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1542 1552
1543 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1553 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1544 // TODO: don't create new blocks if recycling an old packet 1554 // TODO: don't create new blocks if recycling an old packet
@@ -2299,6 +2309,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2299 OutPacket(sound, ThrottleOutPacketType.Task); 2309 OutPacket(sound, ThrottleOutPacketType.Task);
2300 } 2310 }
2301 2311
2312 public void SendTransferAbort(TransferRequestPacket transferRequest)
2313 {
2314 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2315 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2316 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2317 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2318 OutPacket(abort, ThrottleOutPacketType.Task);
2319 }
2320
2302 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2321 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2303 { 2322 {
2304 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2323 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2591,6 +2610,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2591 } 2610 }
2592 } 2611 }
2593 2612
2613 public void SendPartPhysicsProprieties(ISceneEntity entity)
2614 {
2615 SceneObjectPart part = (SceneObjectPart)entity;
2616 if (part != null && AgentId != UUID.Zero)
2617 {
2618 try
2619 {
2620 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2621 if (eq != null)
2622 {
2623 uint localid = part.LocalId;
2624 byte physshapetype = part.PhysicsShapeType;
2625 float density = part.Density;
2626 float friction = part.Friction;
2627 float bounce = part.Bounciness;
2628 float gravmod = part.GravityModifier;
2629
2630 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2631 }
2632 }
2633 catch (Exception ex)
2634 {
2635 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2636 }
2637 part.UpdatePhysRequired = false;
2638 }
2639 }
2640
2641
2594 2642
2595 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2643 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2596 { 2644 {
@@ -2746,7 +2794,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2746 reply.Data.ParcelID = parcelID; 2794 reply.Data.ParcelID = parcelID;
2747 reply.Data.OwnerID = land.OwnerID; 2795 reply.Data.OwnerID = land.OwnerID;
2748 reply.Data.Name = Utils.StringToBytes(land.Name); 2796 reply.Data.Name = Utils.StringToBytes(land.Name);
2749 reply.Data.Desc = Utils.StringToBytes(land.Description); 2797 if (land != null && land.Description != null && land.Description != String.Empty)
2798 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2799 else
2800 reply.Data.Desc = new Byte[0];
2750 reply.Data.ActualArea = land.Area; 2801 reply.Data.ActualArea = land.Area;
2751 reply.Data.BillableArea = land.Area; // TODO: what is this? 2802 reply.Data.BillableArea = land.Area; // TODO: what is this?
2752 2803
@@ -3609,7 +3660,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3609 /// </summary> 3660 /// </summary>
3610 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3661 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3611 { 3662 {
3612 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3663 if (entity is SceneObjectPart)
3664 {
3665 SceneObjectPart e = (SceneObjectPart)entity;
3666 SceneObjectGroup g = e.ParentGroup;
3667 if (g.RootPart.Shape.State > 30) // HUD
3668 if (g.OwnerID != AgentId)
3669 return; // Don't send updates for other people's HUDs
3670 }
3671
3613 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3672 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3614 3673
3615 lock (m_entityUpdates.SyncRoot) 3674 lock (m_entityUpdates.SyncRoot)
@@ -3676,211 +3735,238 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3676 3735
3677 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3736 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3678 // condition where a kill can be processed before an out-of-date update for the same object. 3737 // condition where a kill can be processed before an out-of-date update for the same object.
3679 lock (m_killRecord) 3738 float avgTimeDilation = 1.0f;
3739 IEntityUpdate iupdate;
3740 Int32 timeinqueue; // this is just debugging code & can be dropped later
3741
3742 while (updatesThisCall < maxUpdates)
3680 { 3743 {
3681 float avgTimeDilation = 1.0f; 3744 lock (m_entityUpdates.SyncRoot)
3682 IEntityUpdate iupdate; 3745 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3683 Int32 timeinqueue; // this is just debugging code & can be dropped later 3746 break;
3684
3685 while (updatesThisCall < maxUpdates)
3686 {
3687 lock (m_entityUpdates.SyncRoot)
3688 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3689 break;
3690 3747
3691 EntityUpdate update = (EntityUpdate)iupdate; 3748 EntityUpdate update = (EntityUpdate)iupdate;
3692 3749
3693 avgTimeDilation += update.TimeDilation; 3750 avgTimeDilation += update.TimeDilation;
3694 avgTimeDilation *= 0.5f; 3751 avgTimeDilation *= 0.5f;
3695 3752
3696 if (update.Entity is SceneObjectPart) 3753 if (update.Entity is SceneObjectPart)
3754 {
3755 SceneObjectPart part = (SceneObjectPart)update.Entity;
3756
3757 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3758 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3759 // safety measure.
3760 //
3761 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3762 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3763 // updates and kills on different threads with different scheduling strategies, hence this protection.
3764 //
3765 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3766 // after the root prim has been deleted.
3767 lock (m_killRecord)
3697 { 3768 {
3698 SceneObjectPart part = (SceneObjectPart)update.Entity;
3699
3700 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3701 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3702 // safety measure.
3703 //
3704 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3705 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3706 // updates and kills on different threads with different scheduling strategies, hence this protection.
3707 //
3708 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3709 // after the root prim has been deleted.
3710 if (m_killRecord.Contains(part.LocalId)) 3769 if (m_killRecord.Contains(part.LocalId))
3711 {
3712 // m_log.WarnFormat(
3713 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3714 // part.LocalId, Name);
3715 continue; 3770 continue;
3716 } 3771 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3717 3772 continue;
3718 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3773 }
3774
3775 if (part.ParentGroup.IsDeleted)
3776 continue;
3777
3778 if (part.ParentGroup.IsAttachment)
3779 { // Someone else's HUD, why are we getting these?
3780 if (part.ParentGroup.OwnerID != AgentId &&
3781 part.ParentGroup.RootPart.Shape.State >= 30)
3782 continue;
3783 ScenePresence sp;
3784 // Owner is not in the sim, don't update it to
3785 // anyone
3786 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3787 continue;
3788
3789 List<SceneObjectGroup> atts = sp.GetAttachments();
3790 bool found = false;
3791 foreach (SceneObjectGroup att in atts)
3719 { 3792 {
3720 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3793 if (att == part.ParentGroup)
3721 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3722 { 3794 {
3723 part.Shape.LightEntry = false; 3795 found = true;
3796 break;
3724 } 3797 }
3725 } 3798 }
3799
3800 // It's an attachment of a valid avatar, but
3801 // doesn't seem to be attached, skip
3802 if (!found)
3803 continue;
3804
3805 // On vehicle crossing, the attachments are received
3806 // while the avatar is still a child. Don't send
3807 // updates here because the LocalId has not yet
3808 // been updated and the viewer will derender the
3809 // attachments until the avatar becomes root.
3810 if (sp.IsChildAgent)
3811 continue;
3726 } 3812 }
3727 3813 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3728 ++updatesThisCall;
3729
3730 #region UpdateFlags to packet type conversion
3731
3732 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3733
3734 bool canUseCompressed = true;
3735 bool canUseImproved = true;
3736
3737 // Compressed object updates only make sense for LL primitives
3738 if (!(update.Entity is SceneObjectPart))
3739 {
3740 canUseCompressed = false;
3741 }
3742
3743 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3744 {
3745 canUseCompressed = false;
3746 canUseImproved = false;
3747 }
3748 else
3749 { 3814 {
3750 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3815 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3751 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3816 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3752 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3753 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3754 {
3755 canUseCompressed = false;
3756 }
3757
3758 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3759 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3772 { 3817 {
3773 canUseImproved = false; 3818 part.Shape.LightEntry = false;
3774 } 3819 }
3775 } 3820 }
3776 3821 }
3777 #endregion UpdateFlags to packet type conversion 3822
3778 3823 ++updatesThisCall;
3779 #region Block Construction 3824
3780 3825 #region UpdateFlags to packet type conversion
3781 // TODO: Remove this once we can build compressed updates 3826
3827 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3828
3829 bool canUseCompressed = true;
3830 bool canUseImproved = true;
3831
3832 // Compressed object updates only make sense for LL primitives
3833 if (!(update.Entity is SceneObjectPart))
3834 {
3782 canUseCompressed = false; 3835 canUseCompressed = false;
3783 3836 }
3784 if (!canUseImproved && !canUseCompressed) 3837
3785 { 3838 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3786 if (update.Entity is ScenePresence) 3839 {
3787 { 3840 canUseCompressed = false;
3788 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3841 canUseImproved = false;
3789 objectUpdates.Value.Add(update); 3842 }
3790 } 3843 else
3791 else 3844 {
3792 { 3845 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3793 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3846 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3794 objectUpdates.Value.Add(update); 3847 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3795 } 3848 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3796 }
3797 else if (!canUseImproved)
3798 { 3849 {
3799 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3850 canUseCompressed = false;
3800 compressedUpdates.Value.Add(update);
3801 } 3851 }
3802 else 3852
3853 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3854 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3855 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3856 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3857 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3858 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3859 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3860 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3861 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3862 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3863 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3864 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3865 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3866 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3803 { 3867 {
3804 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3868 canUseImproved = false;
3805 {
3806 // Self updates go into a special list
3807 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3808 terseAgentUpdates.Value.Add(update);
3809 }
3810 else
3811 {
3812 // Everything else goes here
3813 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3814 terseUpdates.Value.Add(update);
3815 }
3816 } 3869 }
3817
3818 #endregion Block Construction
3819 } 3870 }
3820
3821
3822 #region Packet Sending
3823 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3824 3871
3825 if (terseAgentUpdateBlocks.IsValueCreated) 3872 #endregion UpdateFlags to packet type conversion
3826 {
3827 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3828 3873
3829 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3874 #region Block Construction
3830 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3831 packet.RegionData.TimeDilation = timeDilation;
3832 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3833 3875
3834 for (int i = 0; i < blocks.Count; i++) 3876 // TODO: Remove this once we can build compressed updates
3835 packet.ObjectData[i] = blocks[i]; 3877 canUseCompressed = false;
3836 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3837 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3838 }
3839 3878
3840 if (objectUpdateBlocks.IsValueCreated) 3879 if (!canUseImproved && !canUseCompressed)
3841 { 3880 {
3842 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3881 if (update.Entity is ScenePresence)
3843 3882 {
3844 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3883 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3845 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3884 }
3846 packet.RegionData.TimeDilation = timeDilation; 3885 else
3847 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3886 {
3848 3887 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3849 for (int i = 0; i < blocks.Count; i++) 3888 }
3850 packet.ObjectData[i] = blocks[i];
3851 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3852 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3853 } 3889 }
3854 3890 else if (!canUseImproved)
3855 if (compressedUpdateBlocks.IsValueCreated)
3856 { 3891 {
3857 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3892 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3858
3859 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3860 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3861 packet.RegionData.TimeDilation = timeDilation;
3862 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3863
3864 for (int i = 0; i < blocks.Count; i++)
3865 packet.ObjectData[i] = blocks[i];
3866 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3867 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3868 } 3893 }
3869 3894 else
3870 if (terseUpdateBlocks.IsValueCreated)
3871 { 3895 {
3872 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3896 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3873 3897 // Self updates go into a special list
3874 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3898 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3875 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3899 else
3876 packet.RegionData.TimeDilation = timeDilation; 3900 // Everything else goes here
3877 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3901 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3878
3879 for (int i = 0; i < blocks.Count; i++)
3880 packet.ObjectData[i] = blocks[i];
3881 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3882 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3883 } 3902 }
3903
3904 #endregion Block Construction
3905 }
3906
3907 #region Packet Sending
3908
3909 const float TIME_DILATION = 1.0f;
3910 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3911
3912 if (terseAgentUpdateBlocks.IsValueCreated)
3913 {
3914 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3915
3916 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3917 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3918 packet.RegionData.TimeDilation = timeDilation;
3919 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3920
3921 for (int i = 0; i < blocks.Count; i++)
3922 packet.ObjectData[i] = blocks[i];
3923
3924 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3925 }
3926
3927 if (objectUpdateBlocks.IsValueCreated)
3928 {
3929 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3930
3931 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3932 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3933 packet.RegionData.TimeDilation = timeDilation;
3934 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3935
3936 for (int i = 0; i < blocks.Count; i++)
3937 packet.ObjectData[i] = blocks[i];
3938
3939 OutPacket(packet, ThrottleOutPacketType.Task, true);
3940 }
3941
3942 if (compressedUpdateBlocks.IsValueCreated)
3943 {
3944 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3945
3946 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3947 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3948 packet.RegionData.TimeDilation = timeDilation;
3949 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3950
3951 for (int i = 0; i < blocks.Count; i++)
3952 packet.ObjectData[i] = blocks[i];
3953
3954 OutPacket(packet, ThrottleOutPacketType.Task, true);
3955 }
3956
3957 if (terseUpdateBlocks.IsValueCreated)
3958 {
3959 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3960
3961 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3962 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3963 packet.RegionData.TimeDilation = timeDilation;
3964 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3965
3966 for (int i = 0; i < blocks.Count; i++)
3967 packet.ObjectData[i] = blocks[i];
3968
3969 OutPacket(packet, ThrottleOutPacketType.Task, true);
3884 } 3970 }
3885 3971
3886 #endregion Packet Sending 3972 #endregion Packet Sending
@@ -4173,11 +4259,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4173 4259
4174 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4260 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4175 // of the object rather than the properties when the packet was created 4261 // of the object rather than the properties when the packet was created
4176 OutPacket(packet, ThrottleOutPacketType.Task, true, 4262 // HACK : Remove intelligent resending until it's fixed in core
4177 delegate(OutgoingPacket oPacket) 4263 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4178 { 4264 // delegate(OutgoingPacket oPacket)
4179 ResendPropertyUpdates(updates, oPacket); 4265 // {
4180 }); 4266 // ResendPropertyUpdates(updates, oPacket);
4267 // });
4268 OutPacket(packet, ThrottleOutPacketType.Task, true);
4181 4269
4182 // pbcnt += blocks.Count; 4270 // pbcnt += blocks.Count;
4183 // ppcnt++; 4271 // ppcnt++;
@@ -4203,11 +4291,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4203 // of the object rather than the properties when the packet was created 4291 // of the object rather than the properties when the packet was created
4204 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4292 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4205 updates.Add(familyUpdates.Value[i]); 4293 updates.Add(familyUpdates.Value[i]);
4206 OutPacket(packet, ThrottleOutPacketType.Task, true, 4294 // HACK : Remove intelligent resending until it's fixed in core
4207 delegate(OutgoingPacket oPacket) 4295 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4208 { 4296 // delegate(OutgoingPacket oPacket)
4209 ResendPropertyUpdates(updates, oPacket); 4297 // {
4210 }); 4298 // ResendPropertyUpdates(updates, oPacket);
4299 // });
4300 OutPacket(packet, ThrottleOutPacketType.Task, true);
4211 4301
4212 // fpcnt++; 4302 // fpcnt++;
4213 // fbcnt++; 4303 // fbcnt++;
@@ -4356,37 +4446,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4356 if (bl[i].BannedUserID == UUID.Zero) 4446 if (bl[i].BannedUserID == UUID.Zero)
4357 continue; 4447 continue;
4358 BannedUsers.Add(bl[i].BannedUserID); 4448 BannedUsers.Add(bl[i].BannedUserID);
4359 }
4360 4449
4361 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4450 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4362 packet.AgentData.TransactionID = UUID.Random(); 4451 {
4363 packet.AgentData.AgentID = AgentId; 4452 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4364 packet.AgentData.SessionID = SessionId; 4453 packet.AgentData.TransactionID = UUID.Random();
4365 packet.MethodData.Invoice = invoice; 4454 packet.AgentData.AgentID = AgentId;
4366 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4455 packet.AgentData.SessionID = SessionId;
4456 packet.MethodData.Invoice = invoice;
4457 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4367 4458
4368 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4459 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4369 4460
4370 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4461 int j;
4371 { 4462 for (j = 0; j < (6 + BannedUsers.Count); j++)
4372 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4463 {
4373 } 4464 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4374 int j = 0; 4465 }
4466 j = 0;
4375 4467
4376 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4468 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4377 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4469 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4470 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4471 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4472 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4381 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4473 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4382 4474
4383 foreach (UUID banned in BannedUsers) 4475 foreach (UUID banned in BannedUsers)
4384 { 4476 {
4385 returnblock[j].Parameter = banned.GetBytes(); j++; 4477 returnblock[j].Parameter = banned.GetBytes(); j++;
4478 }
4479 packet.ParamList = returnblock;
4480 packet.Header.Reliable = true;
4481 OutPacket(packet, ThrottleOutPacketType.Task);
4482
4483 BannedUsers.Clear();
4484 }
4386 } 4485 }
4387 packet.ParamList = returnblock; 4486
4388 packet.Header.Reliable = false;
4389 OutPacket(packet, ThrottleOutPacketType.Task);
4390 } 4487 }
4391 4488
4392 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4489 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4572,7 +4669,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4572 4669
4573 if (landData.SimwideArea > 0) 4670 if (landData.SimwideArea > 0)
4574 { 4671 {
4575 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4672 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4673 // Never report more than sim total capacity
4674 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4675 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4576 updateMessage.SimWideMaxPrims = simulatorCapacity; 4676 updateMessage.SimWideMaxPrims = simulatorCapacity;
4577 } 4677 }
4578 else 4678 else
@@ -4701,14 +4801,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4701 4801
4702 if (notifyCount > 0) 4802 if (notifyCount > 0)
4703 { 4803 {
4704 if (notifyCount > 32) 4804// if (notifyCount > 32)
4705 { 4805// {
4706 m_log.InfoFormat( 4806// m_log.InfoFormat(
4707 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4807// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4708 + " - a developer might want to investigate whether this is a hard limit", 32); 4808// + " - a developer might want to investigate whether this is a hard limit", 32);
4709 4809//
4710 notifyCount = 32; 4810// notifyCount = 32;
4711 } 4811// }
4712 4812
4713 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4813 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4714 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4814 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4763,9 +4863,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4763 { 4863 {
4764 ScenePresence presence = (ScenePresence)entity; 4864 ScenePresence presence = (ScenePresence)entity;
4765 4865
4866 position = presence.OffsetPosition;
4867 rotation = presence.Rotation;
4868
4869 if (presence.ParentID != 0)
4870 {
4871 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4872 if (part != null && part != part.ParentGroup.RootPart)
4873 {
4874 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4875 rotation = part.RotationOffset * presence.Rotation;
4876 }
4877 }
4878
4766 attachPoint = 0; 4879 attachPoint = 0;
4767 collisionPlane = presence.CollisionPlane; 4880 collisionPlane = presence.CollisionPlane;
4768 position = presence.OffsetPosition;
4769 velocity = presence.Velocity; 4881 velocity = presence.Velocity;
4770 acceleration = Vector3.Zero; 4882 acceleration = Vector3.Zero;
4771 4883
@@ -4775,7 +4887,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4775// acceleration = new Vector3(1, 0, 0); 4887// acceleration = new Vector3(1, 0, 0);
4776 4888
4777 angularVelocity = Vector3.Zero; 4889 angularVelocity = Vector3.Zero;
4778 rotation = presence.Rotation;
4779 4890
4780 if (sendTexture) 4891 if (sendTexture)
4781 textureEntry = presence.Appearance.Texture.GetBytes(); 4892 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4880,13 +4991,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4880 4991
4881 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 4992 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4882 { 4993 {
4994 Vector3 offsetPosition = data.OffsetPosition;
4995 Quaternion rotation = data.Rotation;
4996 uint parentID = data.ParentID;
4997
4998 if (parentID != 0)
4999 {
5000 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5001 if (part != null && part != part.ParentGroup.RootPart)
5002 {
5003 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5004 rotation = part.RotationOffset * data.Rotation;
5005 parentID = part.ParentGroup.RootPart.LocalId;
5006 }
5007 }
5008
4883 byte[] objectData = new byte[76]; 5009 byte[] objectData = new byte[76];
4884 5010
4885 data.CollisionPlane.ToBytes(objectData, 0); 5011 data.CollisionPlane.ToBytes(objectData, 0);
4886 data.OffsetPosition.ToBytes(objectData, 16); 5012 offsetPosition.ToBytes(objectData, 16);
4887// data.Velocity.ToBytes(objectData, 28); 5013// data.Velocity.ToBytes(objectData, 28);
4888// data.Acceleration.ToBytes(objectData, 40); 5014// data.Acceleration.ToBytes(objectData, 40);
4889 data.Rotation.ToBytes(objectData, 52); 5015 rotation.ToBytes(objectData, 52);
4890 //data.AngularVelocity.ToBytes(objectData, 64); 5016 //data.AngularVelocity.ToBytes(objectData, 64);
4891 5017
4892 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5018 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4900,7 +5026,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4900 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5026 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4901 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5027 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4902 update.ObjectData = objectData; 5028 update.ObjectData = objectData;
4903 update.ParentID = data.ParentID; 5029 update.ParentID = parentID;
4904 update.PathCurve = 16; 5030 update.PathCurve = 16;
4905 update.PathScaleX = 100; 5031 update.PathScaleX = 100;
4906 update.PathScaleY = 100; 5032 update.PathScaleY = 100;
@@ -5241,6 +5367,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5241 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5367 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5242 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5368 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5243 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5369 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5370 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5244 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5371 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5245 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5372 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5246 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5373 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5307,6 +5434,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5307 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5434 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5308 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5435 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5309 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5436 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5437 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5310 5438
5311 AddGenericPacketHandler("autopilot", HandleAutopilot); 5439 AddGenericPacketHandler("autopilot", HandleAutopilot);
5312 } 5440 }
@@ -5342,6 +5470,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5342 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5470 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5343 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5471 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5344 (x.ControlFlags != lastarg.ControlFlags) || 5472 (x.ControlFlags != lastarg.ControlFlags) ||
5473 (x.ControlFlags != 0) ||
5345 (x.Far != lastarg.Far) || 5474 (x.Far != lastarg.Far) ||
5346 (x.Flags != lastarg.Flags) || 5475 (x.Flags != lastarg.Flags) ||
5347 (x.State != lastarg.State) || 5476 (x.State != lastarg.State) ||
@@ -5719,7 +5848,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5719 args.Channel = ch; 5848 args.Channel = ch;
5720 args.From = String.Empty; 5849 args.From = String.Empty;
5721 args.Message = Utils.BytesToString(msg); 5850 args.Message = Utils.BytesToString(msg);
5722 args.Type = ChatTypeEnum.Shout; 5851 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5723 args.Position = new Vector3(); 5852 args.Position = new Vector3();
5724 args.Scene = Scene; 5853 args.Scene = Scene;
5725 args.Sender = this; 5854 args.Sender = this;
@@ -6905,10 +7034,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6905 // 46,47,48 are special positions within the packet 7034 // 46,47,48 are special positions within the packet
6906 // This may change so perhaps we need a better way 7035 // This may change so perhaps we need a better way
6907 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7036 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6908 bool UsePhysics = (data[46] != 0) ? true : false; 7037 /*
6909 bool IsTemporary = (data[47] != 0) ? true : false; 7038 bool UsePhysics = (data[46] != 0) ? true : false;
6910 bool IsPhantom = (data[48] != 0) ? true : false; 7039 bool IsTemporary = (data[47] != 0) ? true : false;
6911 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7040 bool IsPhantom = (data[48] != 0) ? true : false;
7041 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7042 */
7043 bool UsePhysics = flags.AgentData.UsePhysics;
7044 bool IsPhantom = flags.AgentData.IsPhantom;
7045 bool IsTemporary = flags.AgentData.IsTemporary;
7046 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7047 ExtraPhysicsData physdata = new ExtraPhysicsData();
7048
7049 if (blocks == null || blocks.Length == 0)
7050 {
7051 physdata.PhysShapeType = PhysShapeType.invalid;
7052 }
7053 else
7054 {
7055 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7056 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7057 physdata.Bounce = phsblock.Restitution;
7058 physdata.Density = phsblock.Density;
7059 physdata.Friction = phsblock.Friction;
7060 physdata.GravitationModifier = phsblock.GravityMultiplier;
7061 }
7062
7063 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
6912 } 7064 }
6913 return true; 7065 return true;
6914 } 7066 }
@@ -9762,7 +9914,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9762 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9914 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9763 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9915 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9764 UpdateMuteListEntry.MuteData.MuteType, 9916 UpdateMuteListEntry.MuteData.MuteType,
9765 UpdateMuteListEntry.AgentData.AgentID); 9917 UpdateMuteListEntry.MuteData.MuteFlags);
9766 return true; 9918 return true;
9767 } 9919 }
9768 return false; 9920 return false;
@@ -9777,8 +9929,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9777 { 9929 {
9778 handlerRemoveMuteListEntry(this, 9930 handlerRemoveMuteListEntry(this,
9779 RemoveMuteListEntry.MuteData.MuteID, 9931 RemoveMuteListEntry.MuteData.MuteID,
9780 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9932 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9781 RemoveMuteListEntry.AgentData.AgentID);
9782 return true; 9933 return true;
9783 } 9934 }
9784 return false; 9935 return false;
@@ -9822,10 +9973,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9822 return false; 9973 return false;
9823 } 9974 }
9824 9975
9976 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
9977 {
9978 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
9979 (ChangeInventoryItemFlagsPacket)packet;
9980 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
9981 if (handlerChangeInventoryItemFlags != null)
9982 {
9983 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
9984 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
9985 return true;
9986 }
9987 return false;
9988 }
9989
9825 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9990 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9826 { 9991 {
9827 return true; 9992 return true;
9828 } 9993 }
9994
9995 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
9996 {
9997 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
9998
9999 #region Packet Session and User Check
10000 if (m_checkPackets)
10001 {
10002 if (packet.AgentData.SessionID != SessionId ||
10003 packet.AgentData.AgentID != AgentId)
10004 return true;
10005 }
10006 #endregion
10007 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10008 List<InventoryItemBase> items = new List<InventoryItemBase>();
10009 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10010 {
10011 InventoryItemBase b = new InventoryItemBase();
10012 b.ID = n.OldItemID;
10013 b.Folder = n.OldFolderID;
10014 items.Add(b);
10015 }
10016
10017 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10018 if (handlerMoveItemsAndLeaveCopy != null)
10019 {
10020 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10021 }
10022
10023 return true;
10024 }
9829 10025
9830 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10026 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9831 { 10027 {
@@ -10252,6 +10448,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10252 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10448 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10253 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10449 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10254 10450
10451 Scene scene = (Scene)m_scene;
10452 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10453 {
10454 ScenePresence p;
10455 if (scene.TryGetScenePresence(sender.AgentId, out p))
10456 {
10457 if (p.GodLevel >= 200)
10458 {
10459 groupProfileReply.GroupData.OpenEnrollment = true;
10460 groupProfileReply.GroupData.MembershipFee = 0;
10461 }
10462 }
10463 }
10464
10255 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10465 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10256 } 10466 }
10257 return true; 10467 return true;
@@ -10825,11 +11035,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10825 11035
10826 StartLure handlerStartLure = OnStartLure; 11036 StartLure handlerStartLure = OnStartLure;
10827 if (handlerStartLure != null) 11037 if (handlerStartLure != null)
10828 handlerStartLure(startLureRequest.Info.LureType, 11038 {
10829 Utils.BytesToString( 11039 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10830 startLureRequest.Info.Message), 11040 {
10831 startLureRequest.TargetData[0].TargetID, 11041 handlerStartLure(startLureRequest.Info.LureType,
10832 this); 11042 Utils.BytesToString(
11043 startLureRequest.Info.Message),
11044 startLureRequest.TargetData[i].TargetID,
11045 this);
11046 }
11047 }
10833 return true; 11048 return true;
10834 } 11049 }
10835 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11050 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10943,10 +11158,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10943 } 11158 }
10944 #endregion 11159 #endregion
10945 11160
10946 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11161 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10947 if (handlerClassifiedGodDelete != null) 11162 if (handlerClassifiedGodDelete != null)
10948 handlerClassifiedGodDelete( 11163 handlerClassifiedGodDelete(
10949 classifiedGodDelete.Data.ClassifiedID, 11164 classifiedGodDelete.Data.ClassifiedID,
11165 classifiedGodDelete.Data.QueryID,
10950 this); 11166 this);
10951 return true; 11167 return true;
10952 } 11168 }
@@ -11312,209 +11528,149 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11312 } 11528 }
11313 else 11529 else
11314 { 11530 {
11315// m_log.DebugFormat( 11531 ClientChangeObject updatehandler = onClientChangeObject;
11316// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11317// i, block.Type, part.Name, part.LocalId);
11318 11532
11319// // Do this once since fetch parts creates a new array. 11533 if (updatehandler != null)
11320// SceneObjectPart[] parts = part.ParentGroup.Parts; 11534 {
11321// for (int j = 0; j < parts.Length; j++) 11535 ObjectChangeData udata = new ObjectChangeData();
11322// {
11323// part.StoreUndoState();
11324// parts[j].IgnoreUndoUpdate = true;
11325// }
11326 11536
11327 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11537 /*ubit from ll JIRA:
11538 * 0x01 position
11539 * 0x02 rotation
11540 * 0x04 scale
11541
11542 * 0x08 LINK_SET
11543 * 0x10 UNIFORM for scale
11544 */
11328 11545
11329 switch (block.Type) 11546 // translate to internal changes
11330 { 11547 // not all cases .. just the ones older code did
11331 case 1:
11332 Vector3 pos1 = new Vector3(block.Data, 0);
11333 11548
11334 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11549 switch (block.Type)
11335 if (handlerUpdatePrimSinglePosition != null) 11550 {
11336 { 11551 case 1: //change position sp
11337 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11552 udata.position = new Vector3(block.Data, 0);
11338 handlerUpdatePrimSinglePosition(localId, pos1, this);
11339 }
11340 break;
11341 11553
11342 case 2: 11554 udata.change = ObjectChangeType.primP;
11343 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11555 updatehandler(localId, udata, this);
11556 break;
11344 11557
11345 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11558 case 2: // rotation sp
11346 if (handlerUpdatePrimSingleRotation != null) 11559 udata.rotation = new Quaternion(block.Data, 0, true);
11347 {
11348 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11349 handlerUpdatePrimSingleRotation(localId, rot1, this);
11350 }
11351 break;
11352 11560
11353 case 3: 11561 udata.change = ObjectChangeType.primR;
11354 Vector3 rotPos = new Vector3(block.Data, 0); 11562 updatehandler(localId, udata, this);
11355 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11563 break;
11356 11564
11357 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11565 case 3: // position plus rotation
11358 if (handlerUpdatePrimSingleRotationPosition != null) 11566 udata.position = new Vector3(block.Data, 0);
11359 { 11567 udata.rotation = new Quaternion(block.Data, 12, true);
11360 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11361 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11362 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11363 }
11364 break;
11365 11568
11366 case 4: 11569 udata.change = ObjectChangeType.primPR;
11367 case 20: 11570 updatehandler(localId, udata, this);
11368 Vector3 scale4 = new Vector3(block.Data, 0); 11571 break;
11369 11572
11370 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11573 case 4: // scale sp
11371 if (handlerUpdatePrimScale != null) 11574 udata.scale = new Vector3(block.Data, 0);
11372 { 11575 udata.change = ObjectChangeType.primS;
11373 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11374 handlerUpdatePrimScale(localId, scale4, this);
11375 }
11376 break;
11377 11576
11378 case 5: 11577 updatehandler(localId, udata, this);
11379 Vector3 scale1 = new Vector3(block.Data, 12); 11578 break;
11380 Vector3 pos11 = new Vector3(block.Data, 0);
11381 11579
11382 handlerUpdatePrimScale = OnUpdatePrimScale; 11580 case 0x14: // uniform scale sp
11383 if (handlerUpdatePrimScale != null) 11581 udata.scale = new Vector3(block.Data, 0);
11384 {
11385 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11386 handlerUpdatePrimScale(localId, scale1, this);
11387 11582
11388 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11583 udata.change = ObjectChangeType.primUS;
11389 if (handlerUpdatePrimSinglePosition != null) 11584 updatehandler(localId, udata, this);
11390 { 11585 break;
11391 handlerUpdatePrimSinglePosition(localId, pos11, this);
11392 }
11393 }
11394 break;
11395 11586
11396 case 9: 11587 case 5: // scale and position sp
11397 Vector3 pos2 = new Vector3(block.Data, 0); 11588 udata.position = new Vector3(block.Data, 0);
11589 udata.scale = new Vector3(block.Data, 12);
11398 11590
11399 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11591 udata.change = ObjectChangeType.primPS;
11592 updatehandler(localId, udata, this);
11593 break;
11400 11594
11401 if (handlerUpdateVector != null) 11595 case 0x15: //uniform scale and position
11402 { 11596 udata.position = new Vector3(block.Data, 0);
11403 handlerUpdateVector(localId, pos2, this); 11597 udata.scale = new Vector3(block.Data, 12);
11404 }
11405 break;
11406 11598
11407 case 10: 11599 udata.change = ObjectChangeType.primPUS;
11408 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11600 updatehandler(localId, udata, this);
11601 break;
11409 11602
11410 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11603 // now group related (bit 4)
11411 if (handlerUpdatePrimRotation != null) 11604 case 9: //( 8 + 1 )group position
11412 { 11605 udata.position = new Vector3(block.Data, 0);
11413 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11414 handlerUpdatePrimRotation(localId, rot3, this);
11415 }
11416 break;
11417 11606
11418 case 11: 11607 udata.change = ObjectChangeType.groupP;
11419 Vector3 pos3 = new Vector3(block.Data, 0); 11608 updatehandler(localId, udata, this);
11420 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11609 break;
11421 11610
11422 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11611 case 0x0A: // (8 + 2) group rotation
11423 if (handlerUpdatePrimGroupRotation != null) 11612 udata.rotation = new Quaternion(block.Data, 0, true);
11424 {
11425 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11426 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11427 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11428 }
11429 break;
11430 case 12:
11431 case 28:
11432 Vector3 scale7 = new Vector3(block.Data, 0);
11433 11613
11434 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11614 udata.change = ObjectChangeType.groupR;
11435 if (handlerUpdatePrimGroupScale != null) 11615 updatehandler(localId, udata, this);
11436 { 11616 break;
11437 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11438 handlerUpdatePrimGroupScale(localId, scale7, this);
11439 }
11440 break;
11441 11617
11442 case 13: 11618 case 0x0B: //( 8 + 2 + 1) group rotation and position
11443 Vector3 scale2 = new Vector3(block.Data, 12); 11619 udata.position = new Vector3(block.Data, 0);
11444 Vector3 pos4 = new Vector3(block.Data, 0); 11620 udata.rotation = new Quaternion(block.Data, 12, true);
11445 11621
11446 handlerUpdatePrimScale = OnUpdatePrimScale; 11622 udata.change = ObjectChangeType.groupPR;
11447 if (handlerUpdatePrimScale != null) 11623 updatehandler(localId, udata, this);
11448 { 11624 break;
11449 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11450 handlerUpdatePrimScale(localId, scale2, this);
11451 11625
11452 // Change the position based on scale (for bug number 246) 11626 case 0x0C: // (8 + 4) group scale
11453 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11627 // only afects root prim and only sent by viewer editor object tab scaling
11454 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11628 // mouse edition only allows uniform scaling
11455 if (handlerUpdatePrimSinglePosition != null) 11629 // SL MAY CHANGE THIS in viewers
11456 {
11457 handlerUpdatePrimSinglePosition(localId, pos4, this);
11458 }
11459 }
11460 break;
11461 11630
11462 case 29: 11631 udata.scale = new Vector3(block.Data, 0);
11463 Vector3 scale5 = new Vector3(block.Data, 12);
11464 Vector3 pos5 = new Vector3(block.Data, 0);
11465 11632
11466 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11633 // udata.change = ObjectChangeType.groupS;
11467 if (handlerUpdatePrimGroupScale != null) 11634 udata.change = ObjectChangeType.primS; // to conform to current SL
11468 { 11635 updatehandler(localId, udata, this);
11469 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11470 part.StoreUndoState(true);
11471 part.IgnoreUndoUpdate = true;
11472 handlerUpdatePrimGroupScale(localId, scale5, this);
11473 handlerUpdateVector = OnUpdatePrimGroupPosition;
11474 11636
11475 if (handlerUpdateVector != null) 11637 break;
11476 {
11477 handlerUpdateVector(localId, pos5, this);
11478 }
11479 11638
11480 part.IgnoreUndoUpdate = false; 11639 case 0x0D: //(8 + 4 + 1) group scale and position
11481 } 11640 // exception as above
11482 11641
11483 break; 11642 udata.position = new Vector3(block.Data, 0);
11643 udata.scale = new Vector3(block.Data, 12);
11484 11644
11485 case 21: 11645 // udata.change = ObjectChangeType.groupPS;
11486 Vector3 scale6 = new Vector3(block.Data, 12); 11646 udata.change = ObjectChangeType.primPS; // to conform to current SL
11487 Vector3 pos6 = new Vector3(block.Data, 0); 11647 updatehandler(localId, udata, this);
11648 break;
11488 11649
11489 handlerUpdatePrimScale = OnUpdatePrimScale; 11650 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11490 if (handlerUpdatePrimScale != null) 11651 udata.scale = new Vector3(block.Data, 0);
11491 {
11492 part.StoreUndoState(false);
11493 part.IgnoreUndoUpdate = true;
11494 11652
11495 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11653 udata.change = ObjectChangeType.groupUS;
11496 handlerUpdatePrimScale(localId, scale6, this); 11654 updatehandler(localId, udata, this);
11497 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11655 break;
11498 if (handlerUpdatePrimSinglePosition != null)
11499 {
11500 handlerUpdatePrimSinglePosition(localId, pos6, this);
11501 }
11502 11656
11503 part.IgnoreUndoUpdate = false; 11657 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11504 } 11658 udata.position = new Vector3(block.Data, 0);
11505 break; 11659 udata.scale = new Vector3(block.Data, 12);
11506 11660
11507 default: 11661 udata.change = ObjectChangeType.groupPUS;
11508 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11662 updatehandler(localId, udata, this);
11509 break; 11663 break;
11664
11665 default:
11666 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11667 break;
11668 }
11510 } 11669 }
11511 11670
11512// for (int j = 0; j < parts.Length; j++)
11513// parts[j].IgnoreUndoUpdate = false;
11514 } 11671 }
11515 } 11672 }
11516 } 11673 }
11517
11518 return true; 11674 return true;
11519 } 11675 }
11520 11676
@@ -11970,7 +12126,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11970 12126
11971// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12127// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11972 12128
12129
12130 //Note, the bool returned from the below function is useless since it is always false.
11973 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12131 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12132
11974 } 12133 }
11975 12134
11976 /// <summary> 12135 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index ffa3be4..ae72175 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -158,6 +158,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 158
159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC 159 private int m_defaultRTO = 1000; // 1sec is the recommendation in the RFC
160 private int m_maxRTO = 60000; 160 private int m_maxRTO = 60000;
161 public bool m_deliverPackets = true;
161 162
162 /// <summary> 163 /// <summary>
163 /// Default constructor 164 /// Default constructor
@@ -439,6 +440,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
439 if (category >= 0 && category < m_packetOutboxes.Length) 440 if (category >= 0 && category < m_packetOutboxes.Length)
440 { 441 {
441 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
443
444 if (m_deliverPackets == false)
445 {
446 queue.Enqueue(packet);
447 return true;
448 }
449
442 TokenBucket bucket = m_throttleCategories[category]; 450 TokenBucket bucket = m_throttleCategories[category];
443 451
444 // Don't send this packet if there is already a packet waiting in the queue 452 // Don't send this packet if there is already a packet waiting in the queue
@@ -488,7 +496,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
488 /// <returns>True if any packets were sent, otherwise false</returns> 496 /// <returns>True if any packets were sent, otherwise false</returns>
489 public bool DequeueOutgoing() 497 public bool DequeueOutgoing()
490 { 498 {
491 OutgoingPacket packet; 499 if (m_deliverPackets == false) return false;
500
501 OutgoingPacket packet = null;
492 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 502 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
493 TokenBucket bucket; 503 TokenBucket bucket;
494 bool packetSent = false; 504 bool packetSent = false;
@@ -520,32 +530,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
520 // No dequeued packet waiting to be sent, try to pull one off 530 // No dequeued packet waiting to be sent, try to pull one off
521 // this queue 531 // this queue
522 queue = m_packetOutboxes[i]; 532 queue = m_packetOutboxes[i];
523 if (queue.Dequeue(out packet)) 533 if (queue != null)
524 { 534 {
525 // A packet was pulled off the queue. See if we have 535 bool success = false;
526 // enough tokens in the bucket to send it out 536 try
527 if (bucket.RemoveTokens(packet.Buffer.DataLength))
528 { 537 {
529 // Send the packet 538 success = queue.Dequeue(out packet);
530 m_udpServer.SendPacketFinal(packet);
531 packetSent = true;
532 } 539 }
533 else 540 catch
534 { 541 {
535 // Save the dequeued packet for the next iteration 542 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
536 m_nextPackets[i] = packet;
537 } 543 }
538 544 if (success)
539 // If the queue is empty after this dequeue, fire the queue 545 {
540 // empty callback now so it has a chance to fill before we 546 // A packet was pulled off the queue. See if we have
541 // get back here 547 // enough tokens in the bucket to send it out
542 if (queue.Count == 0) 548 if (bucket.RemoveTokens(packet.Buffer.DataLength))
549 {
550 // Send the packet
551 m_udpServer.SendPacketFinal(packet);
552 packetSent = true;
553 }
554 else
555 {
556 // Save the dequeued packet for the next iteration
557 m_nextPackets[i] = packet;
558 }
559
560 // If the queue is empty after this dequeue, fire the queue
561 // empty callback now so it has a chance to fill before we
562 // get back here
563 if (queue.Count == 0)
564 emptyCategories |= CategoryToFlag(i);
565 }
566 else
567 {
568 // No packets in this queue. Fire the queue empty callback
569 // if it has not been called recently
543 emptyCategories |= CategoryToFlag(i); 570 emptyCategories |= CategoryToFlag(i);
571 }
544 } 572 }
545 else 573 else
546 { 574 {
547 // No packets in this queue. Fire the queue empty callback 575 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
548 // if it has not been called recently
549 emptyCategories |= CategoryToFlag(i); 576 emptyCategories |= CategoryToFlag(i);
550 } 577 }
551 } 578 }
@@ -703,4 +730,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
703 } 730 }
704 } 731 }
705 } 732 }
706} \ No newline at end of file 733}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index fb6b11e..75f783b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1051,7 +1051,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1051 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1051 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1052 { 1052 {
1053 client.IsLoggingOut = true; 1053 client.IsLoggingOut = true;
1054 client.Close(); 1054 client.Close(false);
1055 } 1055 }
1056 } 1056 }
1057 1057
@@ -1063,6 +1063,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1063 1063
1064 while (base.IsRunning) 1064 while (base.IsRunning)
1065 { 1065 {
1066 m_scene.ThreadAlive(1);
1066 try 1067 try
1067 { 1068 {
1068 IncomingPacket incomingPacket = null; 1069 IncomingPacket incomingPacket = null;
@@ -1105,6 +1106,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1105 1106
1106 while (base.IsRunning) 1107 while (base.IsRunning)
1107 { 1108 {
1109 m_scene.ThreadAlive(2);
1108 try 1110 try
1109 { 1111 {
1110 m_packetSent = false; 1112 m_packetSent = false;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 039379d..cfe7c9d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -100,10 +100,6 @@ namespace OpenMetaverse
100 const int SIO_UDP_CONNRESET = -1744830452; 100 const int SIO_UDP_CONNRESET = -1744830452;
101 101
102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 102 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
103
104 m_log.DebugFormat(
105 "[UDPBASE]: Binding UDP listener using internal IP address config {0}:{1}",
106 ipep.Address, ipep.Port);
107 103
108 m_udpSocket = new Socket( 104 m_udpSocket = new Socket(
109 AddressFamily.InterNetwork, 105 AddressFamily.InterNetwork,