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