aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs155
-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.cs1078
-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, 851 insertions, 486 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 35cb575..5542680 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,147 @@ 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 Console.WriteLine(response);
842 return response;
843 }
844
845 public string GetObjectCost(string request, string path,
846 string param, IOSHttpRequest httpRequest,
847 IOSHttpResponse httpResponse)
848 {
849 // see being triggered but see no efect .. have something wrong ??
850 //
851 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
852 OSDMap resp = new OSDMap();
853
854 OSDArray object_ids = (OSDArray)req["object_ids"];
855
856 for (int i = 0; i < object_ids.Count; i++)
857 {
858 UUID uuid = object_ids[i].AsUUID();
859
860 // only see root parts .. so guess should go by SOG only
861 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
862 if (obj != null)
863 {
864 OSDMap object_data = new OSDMap();
865
866 object_data["linked_set_resource_cost"] = 1.0f;
867 object_data["resource_cost"] = 1.0f;
868 object_data["physics_cost"] = 1.0f;
869 object_data["linked_set_physics_cost"] = 1.0f;
870
871 resp[uuid.ToString()] = object_data;
872 }
873 }
874
875 string response = OSDParser.SerializeLLSDXmlString(resp);
876 Console.WriteLine(response);
877 return response;
878 }
879
880 public string ResourceCostSelected(string request, string path,
881 string param, IOSHttpRequest httpRequest,
882 IOSHttpResponse httpResponse)
883 {
884 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
885 OSDMap resp = new OSDMap();
886
887
888 float phys=0;
889 float stream=0;
890 float simul=0;
891
892 if (req.ContainsKey("selected_roots"))
893 {
894 OSDArray object_ids = (OSDArray)req["selected_roots"];
895
896 // should go by SOG suming costs for all parts
897 // ll v3 works ok with several objects select we get the list and adds ok
898 // FS calls per object so results are wrong guess fs bug
899 for (int i = 0; i < object_ids.Count; i++)
900 {
901 UUID uuid = object_ids[i].AsUUID();
902
903 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
904 if (obj != null)
905 {
906 phys += 0.1f; // just to see...
907 stream += 0.2f;
908 simul += 0.5f;
909 }
910 }
911 }
912 else if (req.ContainsKey("selected_prims"))
913 {
914 OSDArray object_ids = (OSDArray)req["selected_prims"];
915
916 // don't see in use in any of the 2 viewers
917 // guess it should be for edit linked but... nothing
918 // should go to SOP per part
919 for (int i = 0; i < object_ids.Count; i++)
920 {
921 UUID uuid = object_ids[i].AsUUID();
922
923 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
924 if (obj != null)
925 {
926 phys += 0.1f;
927 stream += 0.2f;
928 simul += 0.5f;
929 }
930 }
931 }
932
933 if (simul != 0)
934 {
935 OSDMap object_data = new OSDMap();
936
937 object_data["physics"] = phys;
938 object_data["streaming"] = stream;
939 object_data["simulation"] = simul;
940
941 resp["selected"] = object_data;
942 }
943
944 string response = OSDParser.SerializeLLSDXmlString(resp);
945 Console.WriteLine(response);
946 return response;
947 }
948
949
950
951
952
802 } 953 }
803 954
804 public class AssetUploader 955 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..dd3b8aa 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,34 @@ 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 }
2637 }
2638
2639
2593 2640
2594 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2641 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2595 { 2642 {
@@ -2745,7 +2792,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2745 reply.Data.ParcelID = parcelID; 2792 reply.Data.ParcelID = parcelID;
2746 reply.Data.OwnerID = land.OwnerID; 2793 reply.Data.OwnerID = land.OwnerID;
2747 reply.Data.Name = Utils.StringToBytes(land.Name); 2794 reply.Data.Name = Utils.StringToBytes(land.Name);
2748 reply.Data.Desc = Utils.StringToBytes(land.Description); 2795 if (land != null && land.Description != null && land.Description != String.Empty)
2796 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2797 else
2798 reply.Data.Desc = new Byte[0];
2749 reply.Data.ActualArea = land.Area; 2799 reply.Data.ActualArea = land.Area;
2750 reply.Data.BillableArea = land.Area; // TODO: what is this? 2800 reply.Data.BillableArea = land.Area; // TODO: what is this?
2751 2801
@@ -3608,7 +3658,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3608 /// </summary> 3658 /// </summary>
3609 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3659 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3610 { 3660 {
3611 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3661 if (entity is SceneObjectPart)
3662 {
3663 SceneObjectPart e = (SceneObjectPart)entity;
3664 SceneObjectGroup g = e.ParentGroup;
3665 if (g.RootPart.Shape.State > 30) // HUD
3666 if (g.OwnerID != AgentId)
3667 return; // Don't send updates for other people's HUDs
3668 }
3669
3612 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3670 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3613 3671
3614 lock (m_entityUpdates.SyncRoot) 3672 lock (m_entityUpdates.SyncRoot)
@@ -3675,211 +3733,238 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3675 3733
3676 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3734 // 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. 3735 // condition where a kill can be processed before an out-of-date update for the same object.
3678 lock (m_killRecord) 3736 float avgTimeDilation = 1.0f;
3737 IEntityUpdate iupdate;
3738 Int32 timeinqueue; // this is just debugging code & can be dropped later
3739
3740 while (updatesThisCall < maxUpdates)
3679 { 3741 {
3680 float avgTimeDilation = 1.0f; 3742 lock (m_entityUpdates.SyncRoot)
3681 IEntityUpdate iupdate; 3743 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3682 Int32 timeinqueue; // this is just debugging code & can be dropped later 3744 break;
3683
3684 while (updatesThisCall < maxUpdates)
3685 {
3686 lock (m_entityUpdates.SyncRoot)
3687 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3688 break;
3689 3745
3690 EntityUpdate update = (EntityUpdate)iupdate; 3746 EntityUpdate update = (EntityUpdate)iupdate;
3691 3747
3692 avgTimeDilation += update.TimeDilation; 3748 avgTimeDilation += update.TimeDilation;
3693 avgTimeDilation *= 0.5f; 3749 avgTimeDilation *= 0.5f;
3694 3750
3695 if (update.Entity is SceneObjectPart) 3751 if (update.Entity is SceneObjectPart)
3752 {
3753 SceneObjectPart part = (SceneObjectPart)update.Entity;
3754
3755 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3756 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3757 // safety measure.
3758 //
3759 // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update
3760 // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs
3761 // updates and kills on different threads with different scheduling strategies, hence this protection.
3762 //
3763 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3764 // after the root prim has been deleted.
3765 lock (m_killRecord)
3696 { 3766 {
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)) 3767 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; 3768 continue;
3715 } 3769 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3716 3770 continue;
3717 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3771 }
3772
3773 if (part.ParentGroup.IsDeleted)
3774 continue;
3775
3776 if (part.ParentGroup.IsAttachment)
3777 { // Someone else's HUD, why are we getting these?
3778 if (part.ParentGroup.OwnerID != AgentId &&
3779 part.ParentGroup.RootPart.Shape.State >= 30)
3780 continue;
3781 ScenePresence sp;
3782 // Owner is not in the sim, don't update it to
3783 // anyone
3784 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3785 continue;
3786
3787 List<SceneObjectGroup> atts = sp.GetAttachments();
3788 bool found = false;
3789 foreach (SceneObjectGroup att in atts)
3718 { 3790 {
3719 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3791 if (att == part.ParentGroup)
3720 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3721 { 3792 {
3722 part.Shape.LightEntry = false; 3793 found = true;
3794 break;
3723 } 3795 }
3724 } 3796 }
3797
3798 // It's an attachment of a valid avatar, but
3799 // doesn't seem to be attached, skip
3800 if (!found)
3801 continue;
3802
3803 // On vehicle crossing, the attachments are received
3804 // while the avatar is still a child. Don't send
3805 // updates here because the LocalId has not yet
3806 // been updated and the viewer will derender the
3807 // attachments until the avatar becomes root.
3808 if (sp.IsChildAgent)
3809 continue;
3725 } 3810 }
3726 3811 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 { 3812 {
3749 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3813 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3750 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3814 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 { 3815 {
3772 canUseImproved = false; 3816 part.Shape.LightEntry = false;
3773 } 3817 }
3774 } 3818 }
3775 3819 }
3776 #endregion UpdateFlags to packet type conversion 3820
3777 3821 ++updatesThisCall;
3778 #region Block Construction 3822
3779 3823 #region UpdateFlags to packet type conversion
3780 // TODO: Remove this once we can build compressed updates 3824
3825 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3826
3827 bool canUseCompressed = true;
3828 bool canUseImproved = true;
3829
3830 // Compressed object updates only make sense for LL primitives
3831 if (!(update.Entity is SceneObjectPart))
3832 {
3781 canUseCompressed = false; 3833 canUseCompressed = false;
3782 3834 }
3783 if (!canUseImproved && !canUseCompressed) 3835
3784 { 3836 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3785 if (update.Entity is ScenePresence) 3837 {
3786 { 3838 canUseCompressed = false;
3787 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3839 canUseImproved = false;
3788 objectUpdates.Value.Add(update); 3840 }
3789 } 3841 else
3790 else 3842 {
3791 { 3843 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3792 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3844 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3793 objectUpdates.Value.Add(update); 3845 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3794 } 3846 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3795 }
3796 else if (!canUseImproved)
3797 { 3847 {
3798 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3848 canUseCompressed = false;
3799 compressedUpdates.Value.Add(update);
3800 } 3849 }
3801 else 3850
3851 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3852 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3853 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3854 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3855 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3856 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3857 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3858 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3859 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3860 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3861 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3862 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3863 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3864 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3802 { 3865 {
3803 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3866 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 } 3867 }
3816
3817 #endregion Block Construction
3818 } 3868 }
3819
3820
3821 #region Packet Sending
3822 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3823 3869
3824 if (terseAgentUpdateBlocks.IsValueCreated) 3870 #endregion UpdateFlags to packet type conversion
3825 {
3826 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3827 3871
3828 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3872 #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 3873
3833 for (int i = 0; i < blocks.Count; i++) 3874 // TODO: Remove this once we can build compressed updates
3834 packet.ObjectData[i] = blocks[i]; 3875 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 3876
3839 if (objectUpdateBlocks.IsValueCreated) 3877 if (!canUseImproved && !canUseCompressed)
3840 { 3878 {
3841 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3879 if (update.Entity is ScenePresence)
3842 3880 {
3843 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3881 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3844 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3882 }
3845 packet.RegionData.TimeDilation = timeDilation; 3883 else
3846 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3884 {
3847 3885 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3848 for (int i = 0; i < blocks.Count; i++) 3886 }
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 } 3887 }
3853 3888 else if (!canUseImproved)
3854 if (compressedUpdateBlocks.IsValueCreated)
3855 { 3889 {
3856 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3890 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 } 3891 }
3868 3892 else
3869 if (terseUpdateBlocks.IsValueCreated)
3870 { 3893 {
3871 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3894 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3872 3895 // Self updates go into a special list
3873 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3896 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3874 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3897 else
3875 packet.RegionData.TimeDilation = timeDilation; 3898 // Everything else goes here
3876 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3899 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 } 3900 }
3901
3902 #endregion Block Construction
3903 }
3904
3905 #region Packet Sending
3906
3907 const float TIME_DILATION = 1.0f;
3908 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3909
3910 if (terseAgentUpdateBlocks.IsValueCreated)
3911 {
3912 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3913
3914 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3915 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3916 packet.RegionData.TimeDilation = timeDilation;
3917 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3918
3919 for (int i = 0; i < blocks.Count; i++)
3920 packet.ObjectData[i] = blocks[i];
3921
3922 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3923 }
3924
3925 if (objectUpdateBlocks.IsValueCreated)
3926 {
3927 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3928
3929 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3930 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3931 packet.RegionData.TimeDilation = timeDilation;
3932 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3933
3934 for (int i = 0; i < blocks.Count; i++)
3935 packet.ObjectData[i] = blocks[i];
3936
3937 OutPacket(packet, ThrottleOutPacketType.Task, true);
3938 }
3939
3940 if (compressedUpdateBlocks.IsValueCreated)
3941 {
3942 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3943
3944 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3945 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3946 packet.RegionData.TimeDilation = timeDilation;
3947 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3948
3949 for (int i = 0; i < blocks.Count; i++)
3950 packet.ObjectData[i] = blocks[i];
3951
3952 OutPacket(packet, ThrottleOutPacketType.Task, true);
3953 }
3954
3955 if (terseUpdateBlocks.IsValueCreated)
3956 {
3957 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3958
3959 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3960 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3961 packet.RegionData.TimeDilation = timeDilation;
3962 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3963
3964 for (int i = 0; i < blocks.Count; i++)
3965 packet.ObjectData[i] = blocks[i];
3966
3967 OutPacket(packet, ThrottleOutPacketType.Task, true);
3883 } 3968 }
3884 3969
3885 #endregion Packet Sending 3970 #endregion Packet Sending
@@ -4172,11 +4257,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4172 4257
4173 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4258 // 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 4259 // of the object rather than the properties when the packet was created
4175 OutPacket(packet, ThrottleOutPacketType.Task, true, 4260 // HACK : Remove intelligent resending until it's fixed in core
4176 delegate(OutgoingPacket oPacket) 4261 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4177 { 4262 // delegate(OutgoingPacket oPacket)
4178 ResendPropertyUpdates(updates, oPacket); 4263 // {
4179 }); 4264 // ResendPropertyUpdates(updates, oPacket);
4265 // });
4266 OutPacket(packet, ThrottleOutPacketType.Task, true);
4180 4267
4181 // pbcnt += blocks.Count; 4268 // pbcnt += blocks.Count;
4182 // ppcnt++; 4269 // ppcnt++;
@@ -4202,11 +4289,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4202 // of the object rather than the properties when the packet was created 4289 // of the object rather than the properties when the packet was created
4203 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4290 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4204 updates.Add(familyUpdates.Value[i]); 4291 updates.Add(familyUpdates.Value[i]);
4205 OutPacket(packet, ThrottleOutPacketType.Task, true, 4292 // HACK : Remove intelligent resending until it's fixed in core
4206 delegate(OutgoingPacket oPacket) 4293 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4207 { 4294 // delegate(OutgoingPacket oPacket)
4208 ResendPropertyUpdates(updates, oPacket); 4295 // {
4209 }); 4296 // ResendPropertyUpdates(updates, oPacket);
4297 // });
4298 OutPacket(packet, ThrottleOutPacketType.Task, true);
4210 4299
4211 // fpcnt++; 4300 // fpcnt++;
4212 // fbcnt++; 4301 // fbcnt++;
@@ -4355,37 +4444,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4355 if (bl[i].BannedUserID == UUID.Zero) 4444 if (bl[i].BannedUserID == UUID.Zero)
4356 continue; 4445 continue;
4357 BannedUsers.Add(bl[i].BannedUserID); 4446 BannedUsers.Add(bl[i].BannedUserID);
4358 }
4359 4447
4360 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4448 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4361 packet.AgentData.TransactionID = UUID.Random(); 4449 {
4362 packet.AgentData.AgentID = AgentId; 4450 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4363 packet.AgentData.SessionID = SessionId; 4451 packet.AgentData.TransactionID = UUID.Random();
4364 packet.MethodData.Invoice = invoice; 4452 packet.AgentData.AgentID = AgentId;
4365 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4453 packet.AgentData.SessionID = SessionId;
4454 packet.MethodData.Invoice = invoice;
4455 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4366 4456
4367 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4457 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4368 4458
4369 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4459 int j;
4370 { 4460 for (j = 0; j < (6 + BannedUsers.Count); j++)
4371 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4461 {
4372 } 4462 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4373 int j = 0; 4463 }
4464 j = 0;
4374 4465
4375 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4466 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4376 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4467 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4377 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4468 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4469 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4470 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4471 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4381 4472
4382 foreach (UUID banned in BannedUsers) 4473 foreach (UUID banned in BannedUsers)
4383 { 4474 {
4384 returnblock[j].Parameter = banned.GetBytes(); j++; 4475 returnblock[j].Parameter = banned.GetBytes(); j++;
4476 }
4477 packet.ParamList = returnblock;
4478 packet.Header.Reliable = true;
4479 OutPacket(packet, ThrottleOutPacketType.Task);
4480
4481 BannedUsers.Clear();
4482 }
4385 } 4483 }
4386 packet.ParamList = returnblock; 4484
4387 packet.Header.Reliable = false;
4388 OutPacket(packet, ThrottleOutPacketType.Task);
4389 } 4485 }
4390 4486
4391 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4487 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4571,7 +4667,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4571 4667
4572 if (landData.SimwideArea > 0) 4668 if (landData.SimwideArea > 0)
4573 { 4669 {
4574 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4670 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4671 // Never report more than sim total capacity
4672 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4673 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4575 updateMessage.SimWideMaxPrims = simulatorCapacity; 4674 updateMessage.SimWideMaxPrims = simulatorCapacity;
4576 } 4675 }
4577 else 4676 else
@@ -4700,14 +4799,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4700 4799
4701 if (notifyCount > 0) 4800 if (notifyCount > 0)
4702 { 4801 {
4703 if (notifyCount > 32) 4802// if (notifyCount > 32)
4704 { 4803// {
4705 m_log.InfoFormat( 4804// m_log.InfoFormat(
4706 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4805// "[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); 4806// + " - a developer might want to investigate whether this is a hard limit", 32);
4708 4807//
4709 notifyCount = 32; 4808// notifyCount = 32;
4710 } 4809// }
4711 4810
4712 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4811 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4713 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4812 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4762,9 +4861,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4762 { 4861 {
4763 ScenePresence presence = (ScenePresence)entity; 4862 ScenePresence presence = (ScenePresence)entity;
4764 4863
4864 position = presence.OffsetPosition;
4865 rotation = presence.Rotation;
4866
4867 if (presence.ParentID != 0)
4868 {
4869 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4870 if (part != null && part != part.ParentGroup.RootPart)
4871 {
4872 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4873 rotation = part.RotationOffset * presence.Rotation;
4874 }
4875 }
4876
4765 attachPoint = 0; 4877 attachPoint = 0;
4766 collisionPlane = presence.CollisionPlane; 4878 collisionPlane = presence.CollisionPlane;
4767 position = presence.OffsetPosition;
4768 velocity = presence.Velocity; 4879 velocity = presence.Velocity;
4769 acceleration = Vector3.Zero; 4880 acceleration = Vector3.Zero;
4770 4881
@@ -4774,7 +4885,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4774// acceleration = new Vector3(1, 0, 0); 4885// acceleration = new Vector3(1, 0, 0);
4775 4886
4776 angularVelocity = Vector3.Zero; 4887 angularVelocity = Vector3.Zero;
4777 rotation = presence.Rotation;
4778 4888
4779 if (sendTexture) 4889 if (sendTexture)
4780 textureEntry = presence.Appearance.Texture.GetBytes(); 4890 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4879,13 +4989,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4879 4989
4880 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 4990 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4881 { 4991 {
4992 Vector3 offsetPosition = data.OffsetPosition;
4993 Quaternion rotation = data.Rotation;
4994 uint parentID = data.ParentID;
4995
4996 if (parentID != 0)
4997 {
4998 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
4999 if (part != null && part != part.ParentGroup.RootPart)
5000 {
5001 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5002 rotation = part.RotationOffset * data.Rotation;
5003 parentID = part.ParentGroup.RootPart.LocalId;
5004 }
5005 }
5006
4882 byte[] objectData = new byte[76]; 5007 byte[] objectData = new byte[76];
4883 5008
4884 data.CollisionPlane.ToBytes(objectData, 0); 5009 data.CollisionPlane.ToBytes(objectData, 0);
4885 data.OffsetPosition.ToBytes(objectData, 16); 5010 offsetPosition.ToBytes(objectData, 16);
4886// data.Velocity.ToBytes(objectData, 28); 5011// data.Velocity.ToBytes(objectData, 28);
4887// data.Acceleration.ToBytes(objectData, 40); 5012// data.Acceleration.ToBytes(objectData, 40);
4888 data.Rotation.ToBytes(objectData, 52); 5013 rotation.ToBytes(objectData, 52);
4889 //data.AngularVelocity.ToBytes(objectData, 64); 5014 //data.AngularVelocity.ToBytes(objectData, 64);
4890 5015
4891 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5016 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4899,7 +5024,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4899 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5024 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4900 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5025 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4901 update.ObjectData = objectData; 5026 update.ObjectData = objectData;
4902 update.ParentID = data.ParentID; 5027 update.ParentID = parentID;
4903 update.PathCurve = 16; 5028 update.PathCurve = 16;
4904 update.PathScaleX = 100; 5029 update.PathScaleX = 100;
4905 update.PathScaleY = 100; 5030 update.PathScaleY = 100;
@@ -5240,6 +5365,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5240 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5365 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5241 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5366 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5242 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5367 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5368 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5243 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5369 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5244 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5370 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5245 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5371 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5306,6 +5432,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5306 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5432 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5307 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5433 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5308 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5434 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5435 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5309 5436
5310 AddGenericPacketHandler("autopilot", HandleAutopilot); 5437 AddGenericPacketHandler("autopilot", HandleAutopilot);
5311 } 5438 }
@@ -5341,6 +5468,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5341 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5468 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5342 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5469 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5343 (x.ControlFlags != lastarg.ControlFlags) || 5470 (x.ControlFlags != lastarg.ControlFlags) ||
5471 (x.ControlFlags != 0) ||
5344 (x.Far != lastarg.Far) || 5472 (x.Far != lastarg.Far) ||
5345 (x.Flags != lastarg.Flags) || 5473 (x.Flags != lastarg.Flags) ||
5346 (x.State != lastarg.State) || 5474 (x.State != lastarg.State) ||
@@ -5718,7 +5846,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5718 args.Channel = ch; 5846 args.Channel = ch;
5719 args.From = String.Empty; 5847 args.From = String.Empty;
5720 args.Message = Utils.BytesToString(msg); 5848 args.Message = Utils.BytesToString(msg);
5721 args.Type = ChatTypeEnum.Shout; 5849 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5722 args.Position = new Vector3(); 5850 args.Position = new Vector3();
5723 args.Scene = Scene; 5851 args.Scene = Scene;
5724 args.Sender = this; 5852 args.Sender = this;
@@ -6906,10 +7034,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6906 // 46,47,48 are special positions within the packet 7034 // 46,47,48 are special positions within the packet
6907 // This may change so perhaps we need a better way 7035 // This may change so perhaps we need a better way
6908 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7036 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6909 bool UsePhysics = (data[46] != 0) ? true : false; 7037 /*
6910 bool IsTemporary = (data[47] != 0) ? true : false; 7038 bool UsePhysics = (data[46] != 0) ? true : false;
6911 bool IsPhantom = (data[48] != 0) ? true : false; 7039 bool IsTemporary = (data[47] != 0) ? true : false;
6912 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);
6913 } 7064 }
6914 return true; 7065 return true;
6915 } 7066 }
@@ -9763,7 +9914,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9763 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9914 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9764 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9915 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9765 UpdateMuteListEntry.MuteData.MuteType, 9916 UpdateMuteListEntry.MuteData.MuteType,
9766 UpdateMuteListEntry.AgentData.AgentID); 9917 UpdateMuteListEntry.MuteData.MuteFlags);
9767 return true; 9918 return true;
9768 } 9919 }
9769 return false; 9920 return false;
@@ -9778,8 +9929,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9778 { 9929 {
9779 handlerRemoveMuteListEntry(this, 9930 handlerRemoveMuteListEntry(this,
9780 RemoveMuteListEntry.MuteData.MuteID, 9931 RemoveMuteListEntry.MuteData.MuteID,
9781 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9932 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9782 RemoveMuteListEntry.AgentData.AgentID);
9783 return true; 9933 return true;
9784 } 9934 }
9785 return false; 9935 return false;
@@ -9823,10 +9973,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9823 return false; 9973 return false;
9824 } 9974 }
9825 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
9826 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 9990 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9827 { 9991 {
9828 return true; 9992 return true;
9829 } 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 }
9830 10025
9831 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10026 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9832 { 10027 {
@@ -10253,6 +10448,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10253 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10448 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10254 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10449 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10255 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
10256 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10465 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10257 } 10466 }
10258 return true; 10467 return true;
@@ -10826,11 +11035,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10826 11035
10827 StartLure handlerStartLure = OnStartLure; 11036 StartLure handlerStartLure = OnStartLure;
10828 if (handlerStartLure != null) 11037 if (handlerStartLure != null)
10829 handlerStartLure(startLureRequest.Info.LureType, 11038 {
10830 Utils.BytesToString( 11039 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10831 startLureRequest.Info.Message), 11040 {
10832 startLureRequest.TargetData[0].TargetID, 11041 handlerStartLure(startLureRequest.Info.LureType,
10833 this); 11042 Utils.BytesToString(
11043 startLureRequest.Info.Message),
11044 startLureRequest.TargetData[i].TargetID,
11045 this);
11046 }
11047 }
10834 return true; 11048 return true;
10835 } 11049 }
10836 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11050 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10944,10 +11158,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10944 } 11158 }
10945 #endregion 11159 #endregion
10946 11160
10947 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11161 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10948 if (handlerClassifiedGodDelete != null) 11162 if (handlerClassifiedGodDelete != null)
10949 handlerClassifiedGodDelete( 11163 handlerClassifiedGodDelete(
10950 classifiedGodDelete.Data.ClassifiedID, 11164 classifiedGodDelete.Data.ClassifiedID,
11165 classifiedGodDelete.Data.QueryID,
10951 this); 11166 this);
10952 return true; 11167 return true;
10953 } 11168 }
@@ -11317,209 +11532,149 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11317 } 11532 }
11318 else 11533 else
11319 { 11534 {
11320// m_log.DebugFormat( 11535 ClientChangeObject updatehandler = onClientChangeObject;
11321// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11322// i, block.Type, part.Name, part.LocalId);
11323 11536
11324// // Do this once since fetch parts creates a new array. 11537 if (updatehandler != null)
11325// SceneObjectPart[] parts = part.ParentGroup.Parts; 11538 {
11326// for (int j = 0; j < parts.Length; j++) 11539 ObjectChangeData udata = new ObjectChangeData();
11327// {
11328// part.StoreUndoState();
11329// parts[j].IgnoreUndoUpdate = true;
11330// }
11331 11540
11332 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11541 /*ubit from ll JIRA:
11542 * 0x01 position
11543 * 0x02 rotation
11544 * 0x04 scale
11545
11546 * 0x08 LINK_SET
11547 * 0x10 UNIFORM for scale
11548 */
11333 11549
11334 switch (block.Type) 11550 // translate to internal changes
11335 { 11551 // not all cases .. just the ones older code did
11336 case 1:
11337 Vector3 pos1 = new Vector3(block.Data, 0);
11338 11552
11339 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11553 switch (block.Type)
11340 if (handlerUpdatePrimSinglePosition != null) 11554 {
11341 { 11555 case 1: //change position sp
11342 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11556 udata.position = new Vector3(block.Data, 0);
11343 handlerUpdatePrimSinglePosition(localId, pos1, this);
11344 }
11345 break;
11346 11557
11347 case 2: 11558 udata.change = ObjectChangeType.primP;
11348 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11559 updatehandler(localId, udata, this);
11560 break;
11349 11561
11350 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11562 case 2: // rotation sp
11351 if (handlerUpdatePrimSingleRotation != null) 11563 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 11564
11358 case 3: 11565 udata.change = ObjectChangeType.primR;
11359 Vector3 rotPos = new Vector3(block.Data, 0); 11566 updatehandler(localId, udata, this);
11360 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11567 break;
11361 11568
11362 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11569 case 3: // position plus rotation
11363 if (handlerUpdatePrimSingleRotationPosition != null) 11570 udata.position = new Vector3(block.Data, 0);
11364 { 11571 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 11572
11371 case 4: 11573 udata.change = ObjectChangeType.primPR;
11372 case 20: 11574 updatehandler(localId, udata, this);
11373 Vector3 scale4 = new Vector3(block.Data, 0); 11575 break;
11374 11576
11375 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11577 case 4: // scale sp
11376 if (handlerUpdatePrimScale != null) 11578 udata.scale = new Vector3(block.Data, 0);
11377 { 11579 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 11580
11383 case 5: 11581 updatehandler(localId, udata, this);
11384 Vector3 scale1 = new Vector3(block.Data, 12); 11582 break;
11385 Vector3 pos11 = new Vector3(block.Data, 0);
11386 11583
11387 handlerUpdatePrimScale = OnUpdatePrimScale; 11584 case 0x14: // uniform scale sp
11388 if (handlerUpdatePrimScale != null) 11585 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 11586
11393 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11587 udata.change = ObjectChangeType.primUS;
11394 if (handlerUpdatePrimSinglePosition != null) 11588 updatehandler(localId, udata, this);
11395 { 11589 break;
11396 handlerUpdatePrimSinglePosition(localId, pos11, this);
11397 }
11398 }
11399 break;
11400 11590
11401 case 9: 11591 case 5: // scale and position sp
11402 Vector3 pos2 = new Vector3(block.Data, 0); 11592 udata.position = new Vector3(block.Data, 0);
11593 udata.scale = new Vector3(block.Data, 12);
11403 11594
11404 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11595 udata.change = ObjectChangeType.primPS;
11596 updatehandler(localId, udata, this);
11597 break;
11405 11598
11406 if (handlerUpdateVector != null) 11599 case 0x15: //uniform scale and position
11407 { 11600 udata.position = new Vector3(block.Data, 0);
11408 handlerUpdateVector(localId, pos2, this); 11601 udata.scale = new Vector3(block.Data, 12);
11409 }
11410 break;
11411 11602
11412 case 10: 11603 udata.change = ObjectChangeType.primPUS;
11413 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11604 updatehandler(localId, udata, this);
11605 break;
11414 11606
11415 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11607 // now group related (bit 4)
11416 if (handlerUpdatePrimRotation != null) 11608 case 9: //( 8 + 1 )group position
11417 { 11609 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 11610
11423 case 11: 11611 udata.change = ObjectChangeType.groupP;
11424 Vector3 pos3 = new Vector3(block.Data, 0); 11612 updatehandler(localId, udata, this);
11425 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11613 break;
11426 11614
11427 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11615 case 0x0A: // (8 + 2) group rotation
11428 if (handlerUpdatePrimGroupRotation != null) 11616 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 11617
11439 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11618 udata.change = ObjectChangeType.groupR;
11440 if (handlerUpdatePrimGroupScale != null) 11619 updatehandler(localId, udata, this);
11441 { 11620 break;
11442 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11443 handlerUpdatePrimGroupScale(localId, scale7, this);
11444 }
11445 break;
11446 11621
11447 case 13: 11622 case 0x0B: //( 8 + 2 + 1) group rotation and position
11448 Vector3 scale2 = new Vector3(block.Data, 12); 11623 udata.position = new Vector3(block.Data, 0);
11449 Vector3 pos4 = new Vector3(block.Data, 0); 11624 udata.rotation = new Quaternion(block.Data, 12, true);
11450 11625
11451 handlerUpdatePrimScale = OnUpdatePrimScale; 11626 udata.change = ObjectChangeType.groupPR;
11452 if (handlerUpdatePrimScale != null) 11627 updatehandler(localId, udata, this);
11453 { 11628 break;
11454 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11455 handlerUpdatePrimScale(localId, scale2, this);
11456 11629
11457 // Change the position based on scale (for bug number 246) 11630 case 0x0C: // (8 + 4) group scale
11458 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11631 // 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); 11632 // mouse edition only allows uniform scaling
11460 if (handlerUpdatePrimSinglePosition != null) 11633 // SL MAY CHANGE THIS in viewers
11461 {
11462 handlerUpdatePrimSinglePosition(localId, pos4, this);
11463 }
11464 }
11465 break;
11466 11634
11467 case 29: 11635 udata.scale = new Vector3(block.Data, 0);
11468 Vector3 scale5 = new Vector3(block.Data, 12);
11469 Vector3 pos5 = new Vector3(block.Data, 0);
11470 11636
11471 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11637 // udata.change = ObjectChangeType.groupS;
11472 if (handlerUpdatePrimGroupScale != null) 11638 udata.change = ObjectChangeType.primS; // to conform to current SL
11473 { 11639 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 11640
11480 if (handlerUpdateVector != null) 11641 break;
11481 {
11482 handlerUpdateVector(localId, pos5, this);
11483 }
11484 11642
11485 part.IgnoreUndoUpdate = false; 11643 case 0x0D: //(8 + 4 + 1) group scale and position
11486 } 11644 // exception as above
11487 11645
11488 break; 11646 udata.position = new Vector3(block.Data, 0);
11647 udata.scale = new Vector3(block.Data, 12);
11489 11648
11490 case 21: 11649 // udata.change = ObjectChangeType.groupPS;
11491 Vector3 scale6 = new Vector3(block.Data, 12); 11650 udata.change = ObjectChangeType.primPS; // to conform to current SL
11492 Vector3 pos6 = new Vector3(block.Data, 0); 11651 updatehandler(localId, udata, this);
11652 break;
11493 11653
11494 handlerUpdatePrimScale = OnUpdatePrimScale; 11654 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11495 if (handlerUpdatePrimScale != null) 11655 udata.scale = new Vector3(block.Data, 0);
11496 {
11497 part.StoreUndoState(false);
11498 part.IgnoreUndoUpdate = true;
11499 11656
11500 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11657 udata.change = ObjectChangeType.groupUS;
11501 handlerUpdatePrimScale(localId, scale6, this); 11658 updatehandler(localId, udata, this);
11502 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11659 break;
11503 if (handlerUpdatePrimSinglePosition != null)
11504 {
11505 handlerUpdatePrimSinglePosition(localId, pos6, this);
11506 }
11507 11660
11508 part.IgnoreUndoUpdate = false; 11661 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11509 } 11662 udata.position = new Vector3(block.Data, 0);
11510 break; 11663 udata.scale = new Vector3(block.Data, 12);
11511 11664
11512 default: 11665 udata.change = ObjectChangeType.groupPUS;
11513 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11666 updatehandler(localId, udata, this);
11514 break; 11667 break;
11668
11669 default:
11670 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11671 break;
11672 }
11515 } 11673 }
11516 11674
11517// for (int j = 0; j < parts.Length; j++)
11518// parts[j].IgnoreUndoUpdate = false;
11519 } 11675 }
11520 } 11676 }
11521 } 11677 }
11522
11523 return true; 11678 return true;
11524 } 11679 }
11525 11680
@@ -11975,7 +12130,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11975 12130
11976// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); 12131// m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID);
11977 12132
12133
12134 //Note, the bool returned from the below function is useless since it is always false.
11978 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12135 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12136
11979 } 12137 }
11980 12138
11981 /// <summary> 12139 /// <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,