aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs158
-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.cs1109
-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, 890 insertions, 481 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 6c28e78..d397893 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
@@ -199,6 +202,14 @@ namespace OpenSim.Region.ClientStack.Linden
199 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 202 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
200 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 203 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
201 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 204 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
205 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
206 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
207 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
208 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
209 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
210 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
211
212
202 213
203 m_HostCapsObj.RegisterHandler( 214 m_HostCapsObj.RegisterHandler(
204 "CopyInventoryFromNotecard", 215 "CopyInventoryFromNotecard",
@@ -849,6 +860,151 @@ namespace OpenSim.Region.ClientStack.Linden
849 response["int_response_code"] = 200; 860 response["int_response_code"] = 200;
850 return LLSDHelpers.SerialiseLLSDReply(response); 861 return LLSDHelpers.SerialiseLLSDReply(response);
851 } 862 }
863
864 public string GetObjectPhysicsData(string request, string path,
865 string param, IOSHttpRequest httpRequest,
866 IOSHttpResponse httpResponse)
867 {
868 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
869 OSDMap resp = new OSDMap();
870 OSDArray object_ids = (OSDArray)req["object_ids"];
871
872 for (int i = 0 ; i < object_ids.Count ; i++)
873 {
874 UUID uuid = object_ids[i].AsUUID();
875
876 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
877 if (obj != null)
878 {
879 OSDMap object_data = new OSDMap();
880
881 object_data["PhysicsShapeType"] = obj.PhysicsShapeType;
882 object_data["Density"] = obj.Density;
883 object_data["Friction"] = obj.Friction;
884 object_data["Restitution"] = obj.Bounciness;
885 object_data["GravityMultiplier"] = obj.GravityModifier;
886
887 resp[uuid.ToString()] = object_data;
888 }
889 }
890
891 string response = OSDParser.SerializeLLSDXmlString(resp);
892 return response;
893 }
894
895 public string GetObjectCost(string request, string path,
896 string param, IOSHttpRequest httpRequest,
897 IOSHttpResponse httpResponse)
898 {
899 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
900 OSDMap resp = new OSDMap();
901
902 OSDArray object_ids = (OSDArray)req["object_ids"];
903
904 for (int i = 0; i < object_ids.Count; i++)
905 {
906 UUID uuid = object_ids[i].AsUUID();
907
908 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
909
910 if (part != null)
911 {
912 SceneObjectGroup grp = part.ParentGroup;
913 if (grp != null)
914 {
915 float linksetCost;
916 float linksetPhysCost;
917 float partCost;
918 float partPhysCost;
919
920 grp.GetResourcesCosts(part, out linksetCost, out linksetPhysCost, out partCost, out partPhysCost);
921
922 OSDMap object_data = new OSDMap();
923 object_data["linked_set_resource_cost"] = linksetCost;
924 object_data["resource_cost"] = partCost;
925 object_data["physics_cost"] = partPhysCost;
926 object_data["linked_set_physics_cost"] = linksetPhysCost;
927
928 resp[uuid.ToString()] = object_data;
929 }
930 }
931 }
932
933 string response = OSDParser.SerializeLLSDXmlString(resp);
934 return response;
935 }
936
937 public string ResourceCostSelected(string request, string path,
938 string param, IOSHttpRequest httpRequest,
939 IOSHttpResponse httpResponse)
940 {
941 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
942 OSDMap resp = new OSDMap();
943
944
945 float phys=0;
946 float stream=0;
947 float simul=0;
948
949 if (req.ContainsKey("selected_roots"))
950 {
951 OSDArray object_ids = (OSDArray)req["selected_roots"];
952
953 // should go by SOG suming costs for all parts
954 // ll v3 works ok with several objects select we get the list and adds ok
955 // FS calls per object so results are wrong guess fs bug
956 for (int i = 0; i < object_ids.Count; i++)
957 {
958 UUID uuid = object_ids[i].AsUUID();
959 float Physc;
960 float simulc;
961 float streamc;
962
963 SceneObjectGroup grp = m_Scene.GetGroupByPrim(uuid);
964 if (grp != null)
965 {
966 grp.GetSelectedCosts(out Physc, out streamc, out simulc);
967 phys += Physc;
968 stream += streamc;
969 simul += simulc;
970 }
971 }
972 }
973 else if (req.ContainsKey("selected_prims"))
974 {
975 OSDArray object_ids = (OSDArray)req["selected_prims"];
976
977 // don't see in use in any of the 2 viewers
978 // guess it should be for edit linked but... nothing
979 // should go to SOP per part
980 for (int i = 0; i < object_ids.Count; i++)
981 {
982 UUID uuid = object_ids[i].AsUUID();
983
984 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
985 if (part != null)
986 {
987 phys += part.PhysicsCost;
988 stream += part.StreamingCost;
989 simul += part.SimulationCost;
990 }
991 }
992 }
993
994 if (simul != 0)
995 {
996 OSDMap object_data = new OSDMap();
997
998 object_data["physics"] = phys;
999 object_data["streaming"] = stream;
1000 object_data["simulation"] = simul;
1001
1002 resp["selected"] = object_data;
1003 }
1004
1005 string response = OSDParser.SerializeLLSDXmlString(resp);
1006 return response;
1007 }
852 } 1008 }
853 1009
854 public class AssetUploader 1010 public class AssetUploader
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index ae759ca..01ce194 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -831,5 +831,13 @@ namespace OpenSim.Region.ClientStack.Linden
831 { 831 {
832 return EventQueueHelper.BuildEvent(eventName, eventBody); 832 return EventQueueHelper.BuildEvent(eventName, eventBody);
833 } 833 }
834
835 public void partPhysicsProperties(uint localID, byte physhapetype,
836 float density, float friction, float bounce, float gravmod,UUID avatarID)
837 {
838 OSD item = EventQueueHelper.partPhysicsProperties(localID, physhapetype,
839 density, friction, bounce, gravmod);
840 Enqueue(item, avatarID);
841 }
834 } 842 }
835} 843}
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 4d6081c..258683d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -98,6 +98,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
98 public event AvatarPickerRequest OnAvatarPickerRequest; 98 public event AvatarPickerRequest OnAvatarPickerRequest;
99 public event StartAnim OnStartAnim; 99 public event StartAnim OnStartAnim;
100 public event StopAnim OnStopAnim; 100 public event StopAnim OnStopAnim;
101 public event ChangeAnim OnChangeAnim;
101 public event Action<IClientAPI> OnRequestAvatarsData; 102 public event Action<IClientAPI> OnRequestAvatarsData;
102 public event LinkObjects OnLinkObjects; 103 public event LinkObjects OnLinkObjects;
103 public event DelinkObjects OnDelinkObjects; 104 public event DelinkObjects OnDelinkObjects;
@@ -125,6 +126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily; 126 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
126 public event UpdatePrimFlags OnUpdatePrimFlags; 127 public event UpdatePrimFlags OnUpdatePrimFlags;
127 public event UpdatePrimTexture OnUpdatePrimTexture; 128 public event UpdatePrimTexture OnUpdatePrimTexture;
129 public event ClientChangeObject onClientChangeObject;
128 public event UpdateVector OnUpdatePrimGroupPosition; 130 public event UpdateVector OnUpdatePrimGroupPosition;
129 public event UpdateVector OnUpdatePrimSinglePosition; 131 public event UpdateVector OnUpdatePrimSinglePosition;
130 public event UpdatePrimRotation OnUpdatePrimGroupRotation; 132 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
@@ -158,6 +160,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
158 public event RequestTaskInventory OnRequestTaskInventory; 160 public event RequestTaskInventory OnRequestTaskInventory;
159 public event UpdateInventoryItem OnUpdateInventoryItem; 161 public event UpdateInventoryItem OnUpdateInventoryItem;
160 public event CopyInventoryItem OnCopyInventoryItem; 162 public event CopyInventoryItem OnCopyInventoryItem;
163 public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy;
161 public event MoveInventoryItem OnMoveInventoryItem; 164 public event MoveInventoryItem OnMoveInventoryItem;
162 public event RemoveInventoryItem OnRemoveInventoryItem; 165 public event RemoveInventoryItem OnRemoveInventoryItem;
163 public event RemoveInventoryFolder OnRemoveInventoryFolder; 166 public event RemoveInventoryFolder OnRemoveInventoryFolder;
@@ -256,7 +259,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
256 public event ClassifiedInfoRequest OnClassifiedInfoRequest; 259 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
257 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate; 260 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
258 public event ClassifiedDelete OnClassifiedDelete; 261 public event ClassifiedDelete OnClassifiedDelete;
259 public event ClassifiedDelete OnClassifiedGodDelete; 262 public event ClassifiedGodDelete OnClassifiedGodDelete;
260 public event EventNotificationAddRequest OnEventNotificationAddRequest; 263 public event EventNotificationAddRequest OnEventNotificationAddRequest;
261 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest; 264 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
262 public event EventGodDelete OnEventGodDelete; 265 public event EventGodDelete OnEventGodDelete;
@@ -287,6 +290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
287 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest; 290 public event GroupVoteHistoryRequest OnGroupVoteHistoryRequest;
288 public event SimWideDeletesDelegate OnSimWideDeletes; 291 public event SimWideDeletesDelegate OnSimWideDeletes;
289 public event SendPostcard OnSendPostcard; 292 public event SendPostcard OnSendPostcard;
293 public event ChangeInventoryItemFlags OnChangeInventoryItemFlags;
290 public event MuteListEntryUpdate OnUpdateMuteListEntry; 294 public event MuteListEntryUpdate OnUpdateMuteListEntry;
291 public event MuteListEntryRemove OnRemoveMuteListEntry; 295 public event MuteListEntryRemove OnRemoveMuteListEntry;
292 public event GodlikeMessage onGodlikeMessage; 296 public event GodlikeMessage onGodlikeMessage;
@@ -325,6 +329,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
325 private Prioritizer m_prioritizer; 329 private Prioritizer m_prioritizer;
326 private bool m_disableFacelights = false; 330 private bool m_disableFacelights = false;
327 331
332 private const uint MaxTransferBytesPerPacket = 600;
333
334
328 /// <value> 335 /// <value>
329 /// List used in construction of data blocks for an object update packet. This is to stop us having to 336 /// List used in construction of data blocks for an object update packet. This is to stop us having to
330 /// continually recreate it. 337 /// continually recreate it.
@@ -336,7 +343,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
336 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 343 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
337 /// ownerless phantom. 344 /// ownerless phantom.
338 /// 345 ///
339 /// All manipulation of this set has to occur under a lock 346 /// All manipulation of this set has to occur under an m_entityUpdates.SyncRoot lock
340 /// 347 ///
341 /// </value> 348 /// </value>
342 protected HashSet<uint> m_killRecord; 349 protected HashSet<uint> m_killRecord;
@@ -344,6 +351,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
344// protected HashSet<uint> m_attachmentsSent; 351// protected HashSet<uint> m_attachmentsSent;
345 352
346 private int m_moneyBalance; 353 private int m_moneyBalance;
354 private bool m_deliverPackets = true;
347 private int m_animationSequenceNumber = 1; 355 private int m_animationSequenceNumber = 1;
348 private bool m_SendLogoutPacketWhenClosing = true; 356 private bool m_SendLogoutPacketWhenClosing = true;
349 private AgentUpdateArgs lastarg; 357 private AgentUpdateArgs lastarg;
@@ -383,6 +391,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
383 get { return m_startpos; } 391 get { return m_startpos; }
384 set { m_startpos = value; } 392 set { m_startpos = value; }
385 } 393 }
394 public bool DeliverPackets
395 {
396 get { return m_deliverPackets; }
397 set {
398 m_deliverPackets = value;
399 m_udpClient.m_deliverPackets = value;
400 }
401 }
386 public UUID AgentId { get { return m_agentId; } } 402 public UUID AgentId { get { return m_agentId; } }
387 public ISceneAgent SceneAgent { get; set; } 403 public ISceneAgent SceneAgent { get; set; }
388 public UUID ActiveGroupId { get { return m_activeGroupID; } } 404 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -485,18 +501,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
485 501
486 #region Client Methods 502 #region Client Methods
487 503
504
488 /// <summary> 505 /// <summary>
489 /// Shut down the client view 506 /// Shut down the client view
490 /// </summary> 507 /// </summary>
491 public void Close() 508 public void Close()
492 { 509 {
510 Close(true);
511 }
512
513 /// <summary>
514 /// Shut down the client view
515 /// </summary>
516 public void Close(bool sendStop)
517 {
493 m_log.DebugFormat( 518 m_log.DebugFormat(
494 "[CLIENT]: Close has been called for {0} attached to scene {1}", 519 "[CLIENT]: Close has been called for {0} attached to scene {1}",
495 Name, m_scene.RegionInfo.RegionName); 520 Name, m_scene.RegionInfo.RegionName);
496 521
497 // Send the STOP packet 522 if (sendStop)
498 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); 523 {
499 OutPacket(disable, ThrottleOutPacketType.Unknown); 524 // Send the STOP packet
525 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
526 OutPacket(disable, ThrottleOutPacketType.Unknown);
527 }
500 528
501 IsActive = false; 529 IsActive = false;
502 530
@@ -796,7 +824,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
796 reply.ChatData.OwnerID = fromAgentID; 824 reply.ChatData.OwnerID = fromAgentID;
797 reply.ChatData.SourceID = fromAgentID; 825 reply.ChatData.SourceID = fromAgentID;
798 826
799 OutPacket(reply, ThrottleOutPacketType.Task); 827 OutPacket(reply, ThrottleOutPacketType.Unknown);
800 } 828 }
801 829
802 /// <summary> 830 /// <summary>
@@ -1082,6 +1110,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1082 public virtual void SendLayerData(float[] map) 1110 public virtual void SendLayerData(float[] map)
1083 { 1111 {
1084 Util.FireAndForget(DoSendLayerData, map); 1112 Util.FireAndForget(DoSendLayerData, map);
1113
1114 // Send it sync, and async. It's not that much data
1115 // and it improves user experience just so much!
1116 DoSendLayerData(map);
1085 } 1117 }
1086 1118
1087 /// <summary> 1119 /// <summary>
@@ -1094,16 +1126,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1094 1126
1095 try 1127 try
1096 { 1128 {
1097 //for (int y = 0; y < 16; y++) 1129 for (int y = 0; y < 16; y++)
1098 //{ 1130 {
1099 // for (int x = 0; x < 16; x++) 1131 for (int x = 0; x < 16; x+=4)
1100 // { 1132 {
1101 // SendLayerData(x, y, map); 1133 SendLayerPacket(x, y, map);
1102 // } 1134 }
1103 //} 1135 }
1104
1105 // Send LayerData in a spiral pattern. Fun!
1106 SendLayerTopRight(map, 0, 0, 15, 15);
1107 } 1136 }
1108 catch (Exception e) 1137 catch (Exception e)
1109 { 1138 {
@@ -1111,51 +1140,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1111 } 1140 }
1112 } 1141 }
1113 1142
1114 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1115 {
1116 // Row
1117 for (int i = x1; i <= x2; i++)
1118 SendLayerData(i, y1, map);
1119
1120 // Column
1121 for (int j = y1 + 1; j <= y2; j++)
1122 SendLayerData(x2, j, map);
1123
1124 if (x2 - x1 > 0)
1125 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1126 }
1127
1128 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1129 {
1130 // Row in reverse
1131 for (int i = x2; i >= x1; i--)
1132 SendLayerData(i, y2, map);
1133
1134 // Column in reverse
1135 for (int j = y2 - 1; j >= y1; j--)
1136 SendLayerData(x1, j, map);
1137
1138 if (x2 - x1 > 0)
1139 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1140 }
1141
1142 /// <summary> 1143 /// <summary>
1143 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1144 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1144 /// </summary> 1145 /// </summary>
1145 /// <param name="map">heightmap</param> 1146 /// <param name="map">heightmap</param>
1146 /// <param name="px">X coordinate for patches 0..12</param> 1147 /// <param name="px">X coordinate for patches 0..12</param>
1147 /// <param name="py">Y coordinate for patches 0..15</param> 1148 /// <param name="py">Y coordinate for patches 0..15</param>
1148 // private void SendLayerPacket(float[] map, int y, int x) 1149 private void SendLayerPacket(int x, int y, float[] map)
1149 // { 1150 {
1150 // int[] patches = new int[4]; 1151 int[] patches = new int[4];
1151 // patches[0] = x + 0 + y * 16; 1152 patches[0] = x + 0 + y * 16;
1152 // patches[1] = x + 1 + y * 16; 1153 patches[1] = x + 1 + y * 16;
1153 // patches[2] = x + 2 + y * 16; 1154 patches[2] = x + 2 + y * 16;
1154 // patches[3] = x + 3 + y * 16; 1155 patches[3] = x + 3 + y * 16;
1155 1156
1156 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1157 float[] heightmap = (map.Length == 65536) ?
1157 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1158 map :
1158 // } 1159 LLHeightFieldMoronize(map);
1160
1161 try
1162 {
1163 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1164 OutPacket(layerpack, ThrottleOutPacketType.Land);
1165 }
1166 catch
1167 {
1168 for (int px = x ; px < x + 4 ; px++)
1169 SendLayerData(px, y, map);
1170 }
1171 }
1159 1172
1160 /// <summary> 1173 /// <summary>
1161 /// Sends a specified patch to a client 1174 /// Sends a specified patch to a client
@@ -1175,7 +1188,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1175 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1188 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1176 layerpack.Header.Reliable = true; 1189 layerpack.Header.Reliable = true;
1177 1190
1178 OutPacket(layerpack, ThrottleOutPacketType.Land); 1191 OutPacket(layerpack, ThrottleOutPacketType.Task);
1179 } 1192 }
1180 catch (Exception e) 1193 catch (Exception e)
1181 { 1194 {
@@ -1538,7 +1551,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1538 1551
1539 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1552 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1540 { 1553 {
1541// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1554// foreach (uint id in localIDs)
1555// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1542 1556
1543 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1557 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1544 // TODO: don't create new blocks if recycling an old packet 1558 // TODO: don't create new blocks if recycling an old packet
@@ -2300,6 +2314,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2300 OutPacket(sound, ThrottleOutPacketType.Task); 2314 OutPacket(sound, ThrottleOutPacketType.Task);
2301 } 2315 }
2302 2316
2317 public void SendTransferAbort(TransferRequestPacket transferRequest)
2318 {
2319 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2320 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2321 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2322 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2323 OutPacket(abort, ThrottleOutPacketType.Task);
2324 }
2325
2303 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2326 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2304 { 2327 {
2305 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2328 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2592,6 +2615,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2592 } 2615 }
2593 } 2616 }
2594 2617
2618 public void SendPartPhysicsProprieties(ISceneEntity entity)
2619 {
2620 SceneObjectPart part = (SceneObjectPart)entity;
2621 if (part != null && AgentId != UUID.Zero)
2622 {
2623 try
2624 {
2625 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2626 if (eq != null)
2627 {
2628 uint localid = part.LocalId;
2629 byte physshapetype = part.PhysicsShapeType;
2630 float density = part.Density;
2631 float friction = part.Friction;
2632 float bounce = part.Bounciness;
2633 float gravmod = part.GravityModifier;
2634
2635 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2636 }
2637 }
2638 catch (Exception ex)
2639 {
2640 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2641 }
2642 part.UpdatePhysRequired = false;
2643 }
2644 }
2645
2646
2595 2647
2596 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2648 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2597 { 2649 {
@@ -2689,7 +2741,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2689 else 2741 else
2690 { 2742 {
2691 int processedLength = 0; 2743 int processedLength = 0;
2692 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2744// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2745
2746 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2693 int packetNumber = 0; 2747 int packetNumber = 0;
2694 2748
2695 while (processedLength < req.AssetInf.Data.Length) 2749 while (processedLength < req.AssetInf.Data.Length)
@@ -2747,7 +2801,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2747 reply.Data.ParcelID = parcelID; 2801 reply.Data.ParcelID = parcelID;
2748 reply.Data.OwnerID = land.OwnerID; 2802 reply.Data.OwnerID = land.OwnerID;
2749 reply.Data.Name = Utils.StringToBytes(land.Name); 2803 reply.Data.Name = Utils.StringToBytes(land.Name);
2750 reply.Data.Desc = Utils.StringToBytes(land.Description); 2804 if (land != null && land.Description != null && land.Description != String.Empty)
2805 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2806 else
2807 reply.Data.Desc = new Byte[0];
2751 reply.Data.ActualArea = land.Area; 2808 reply.Data.ActualArea = land.Area;
2752 reply.Data.BillableArea = land.Area; // TODO: what is this? 2809 reply.Data.BillableArea = land.Area; // TODO: what is this?
2753 2810
@@ -3482,7 +3539,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3482 3539
3483 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3540 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3484 // TODO: don't create new blocks if recycling an old packet 3541 // TODO: don't create new blocks if recycling an old packet
3485 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3542 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3486 avp.ObjectData.TextureEntry = textureEntry; 3543 avp.ObjectData.TextureEntry = textureEntry;
3487 3544
3488 AvatarAppearancePacket.VisualParamBlock avblock = null; 3545 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3610,7 +3667,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3610 /// </summary> 3667 /// </summary>
3611 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3668 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3612 { 3669 {
3613 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3670 if (entity is SceneObjectPart)
3671 {
3672 SceneObjectPart e = (SceneObjectPart)entity;
3673 SceneObjectGroup g = e.ParentGroup;
3674 if (g.RootPart.Shape.State > 30) // HUD
3675 if (g.OwnerID != AgentId)
3676 return; // Don't send updates for other people's HUDs
3677 }
3678
3614 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3679 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3615 3680
3616 lock (m_entityUpdates.SyncRoot) 3681 lock (m_entityUpdates.SyncRoot)
@@ -3677,27 +3742,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3677 3742
3678 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3743 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3679 // condition where a kill can be processed before an out-of-date update for the same object. 3744 // condition where a kill can be processed before an out-of-date update for the same object.
3680 lock (m_killRecord) 3745 float avgTimeDilation = 1.0f;
3746 IEntityUpdate iupdate;
3747 Int32 timeinqueue; // this is just debugging code & can be dropped later
3748
3749 while (updatesThisCall < maxUpdates)
3681 { 3750 {
3682 float avgTimeDilation = 1.0f; 3751 lock (m_entityUpdates.SyncRoot)
3683 IEntityUpdate iupdate; 3752 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3684 Int32 timeinqueue; // this is just debugging code & can be dropped later 3753 break;
3754
3755 EntityUpdate update = (EntityUpdate)iupdate;
3756
3757 avgTimeDilation += update.TimeDilation;
3758 avgTimeDilation *= 0.5f;
3685 3759
3686 while (updatesThisCall < maxUpdates) 3760 if (update.Entity is SceneObjectPart)
3687 { 3761 {
3688 lock (m_entityUpdates.SyncRoot) 3762 SceneObjectPart part = (SceneObjectPart)update.Entity;
3689 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3690 break;
3691 3763
3692 EntityUpdate update = (EntityUpdate)iupdate; 3764 if (part.ParentGroup.IsDeleted)
3693 3765 continue;
3694 avgTimeDilation += update.TimeDilation;
3695 avgTimeDilation *= 0.5f;
3696 3766
3697 if (update.Entity is SceneObjectPart) 3767 if (part.ParentGroup.IsAttachment)
3768 { // Someone else's HUD, why are we getting these?
3769 if (part.ParentGroup.OwnerID != AgentId &&
3770 part.ParentGroup.RootPart.Shape.State >= 30)
3771 continue;
3772 ScenePresence sp;
3773 // Owner is not in the sim, don't update it to
3774 // anyone
3775 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3776 continue;
3777
3778 List<SceneObjectGroup> atts = sp.GetAttachments();
3779 bool found = false;
3780 foreach (SceneObjectGroup att in atts)
3781 {
3782 if (att == part.ParentGroup)
3783 {
3784 found = true;
3785 break;
3786 }
3787 }
3788
3789 // It's an attachment of a valid avatar, but
3790 // doesn't seem to be attached, skip
3791 if (!found)
3792 continue;
3793
3794 // On vehicle crossing, the attachments are received
3795 // while the avatar is still a child. Don't send
3796 // updates here because the LocalId has not yet
3797 // been updated and the viewer will derender the
3798 // attachments until the avatar becomes root.
3799 if (sp.IsChildAgent)
3800 continue;
3801
3802 // If the object is an attachment we don't want it to be in the kill
3803 // record. Else attaching from inworld and subsequently dropping
3804 // it will no longer work.
3805 lock (m_killRecord)
3806 {
3807 m_killRecord.Remove(part.LocalId);
3808 m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3809 }
3810 }
3811 else
3698 { 3812 {
3699 SceneObjectPart part = (SceneObjectPart)update.Entity;
3700
3701 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3813 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3702 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3814 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3703 // safety measure. 3815 // safety measure.
@@ -3708,180 +3820,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3708 // 3820 //
3709 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3821 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3710 // after the root prim has been deleted. 3822 // after the root prim has been deleted.
3711 if (m_killRecord.Contains(part.LocalId)) 3823 //
3712 { 3824 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3713 // m_log.WarnFormat( 3825 lock (m_killRecord)
3714 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted",
3715 // part.LocalId, Name);
3716 continue;
3717 }
3718
3719 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3720 { 3826 {
3721 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3827 if (m_killRecord.Contains(part.LocalId))
3722 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand) 3828 continue;
3723 { 3829 if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3724 part.Shape.LightEntry = false; 3830 continue;
3725 }
3726 } 3831 }
3727 } 3832 }
3728 3833
3729 ++updatesThisCall; 3834 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3730
3731 #region UpdateFlags to packet type conversion
3732
3733 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3734
3735 bool canUseCompressed = true;
3736 bool canUseImproved = true;
3737
3738 // Compressed object updates only make sense for LL primitives
3739 if (!(update.Entity is SceneObjectPart))
3740 {
3741 canUseCompressed = false;
3742 }
3743
3744 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3745 {
3746 canUseCompressed = false;
3747 canUseImproved = false;
3748 }
3749 else
3750 { 3835 {
3751 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || 3836 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3752 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || 3837 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3753 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3754 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3755 {
3756 canUseCompressed = false;
3757 }
3758
3759 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3762 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3763 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3773 { 3838 {
3774 canUseImproved = false; 3839 part.Shape.LightEntry = false;
3775 } 3840 }
3776 } 3841 }
3777 3842 }
3778 #endregion UpdateFlags to packet type conversion 3843
3779 3844 ++updatesThisCall;
3780 #region Block Construction 3845
3781 3846 #region UpdateFlags to packet type conversion
3782 // TODO: Remove this once we can build compressed updates 3847
3848 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3849
3850 bool canUseCompressed = true;
3851 bool canUseImproved = true;
3852
3853 // Compressed object updates only make sense for LL primitives
3854 if (!(update.Entity is SceneObjectPart))
3855 {
3783 canUseCompressed = false; 3856 canUseCompressed = false;
3784 3857 }
3785 if (!canUseImproved && !canUseCompressed) 3858
3786 { 3859 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3787 if (update.Entity is ScenePresence) 3860 {
3788 { 3861 canUseCompressed = false;
3789 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); 3862 canUseImproved = false;
3790 objectUpdates.Value.Add(update); 3863 }
3791 } 3864 else
3792 else 3865 {
3793 { 3866 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3794 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); 3867 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3795 objectUpdates.Value.Add(update); 3868 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3796 } 3869 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3797 }
3798 else if (!canUseImproved)
3799 { 3870 {
3800 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); 3871 canUseCompressed = false;
3801 compressedUpdates.Value.Add(update);
3802 } 3872 }
3803 else 3873
3874 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3875 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3876 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3877 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3878 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3879 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3880 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3881 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3882 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3883 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3884 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3885 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3886 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3887 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3804 { 3888 {
3805 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3889 canUseImproved = false;
3806 {
3807 // Self updates go into a special list
3808 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3809 terseAgentUpdates.Value.Add(update);
3810 }
3811 else
3812 {
3813 // Everything else goes here
3814 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3815 terseUpdates.Value.Add(update);
3816 }
3817 } 3890 }
3818
3819 #endregion Block Construction
3820 } 3891 }
3821
3822
3823 #region Packet Sending
3824 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3825 3892
3826 if (terseAgentUpdateBlocks.IsValueCreated) 3893 #endregion UpdateFlags to packet type conversion
3827 {
3828 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3829 3894
3830 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3895 #region Block Construction
3831 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3832 packet.RegionData.TimeDilation = timeDilation;
3833 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3834 3896
3835 for (int i = 0; i < blocks.Count; i++) 3897 // TODO: Remove this once we can build compressed updates
3836 packet.ObjectData[i] = blocks[i]; 3898 canUseCompressed = false;
3837 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3838 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3839 }
3840 3899
3841 if (objectUpdateBlocks.IsValueCreated) 3900 if (!canUseImproved && !canUseCompressed)
3842 { 3901 {
3843 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3902 if (update.Entity is ScenePresence)
3844 3903 {
3845 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3904 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3846 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3905 }
3847 packet.RegionData.TimeDilation = timeDilation; 3906 else
3848 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3907 {
3849 3908 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3850 for (int i = 0; i < blocks.Count; i++) 3909 }
3851 packet.ObjectData[i] = blocks[i];
3852 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3853 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
3854 } 3910 }
3855 3911 else if (!canUseImproved)
3856 if (compressedUpdateBlocks.IsValueCreated)
3857 { 3912 {
3858 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3913 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3859
3860 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3861 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3862 packet.RegionData.TimeDilation = timeDilation;
3863 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3864
3865 for (int i = 0; i < blocks.Count; i++)
3866 packet.ObjectData[i] = blocks[i];
3867 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3868 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3869 } 3914 }
3870 3915 else
3871 if (terseUpdateBlocks.IsValueCreated)
3872 { 3916 {
3873 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3917 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3874 3918 // Self updates go into a special list
3875 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3919 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3876 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3920 else
3877 packet.RegionData.TimeDilation = timeDilation; 3921 // Everything else goes here
3878 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3922 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3879
3880 for (int i = 0; i < blocks.Count; i++)
3881 packet.ObjectData[i] = blocks[i];
3882 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3883 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
3884 } 3923 }
3924
3925 #endregion Block Construction
3926 }
3927
3928 #region Packet Sending
3929
3930 const float TIME_DILATION = 1.0f;
3931 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3932
3933 if (terseAgentUpdateBlocks.IsValueCreated)
3934 {
3935 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3936
3937 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3938 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3939 packet.RegionData.TimeDilation = timeDilation;
3940 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3941
3942 for (int i = 0; i < blocks.Count; i++)
3943 packet.ObjectData[i] = blocks[i];
3944
3945 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3946 }
3947
3948 if (objectUpdateBlocks.IsValueCreated)
3949 {
3950 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3951
3952 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3953 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3954 packet.RegionData.TimeDilation = timeDilation;
3955 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3956
3957 for (int i = 0; i < blocks.Count; i++)
3958 packet.ObjectData[i] = blocks[i];
3959
3960 OutPacket(packet, ThrottleOutPacketType.Task, true);
3961 }
3962
3963 if (compressedUpdateBlocks.IsValueCreated)
3964 {
3965 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3966
3967 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3968 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3969 packet.RegionData.TimeDilation = timeDilation;
3970 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3971
3972 for (int i = 0; i < blocks.Count; i++)
3973 packet.ObjectData[i] = blocks[i];
3974
3975 OutPacket(packet, ThrottleOutPacketType.Task, true);
3976 }
3977
3978 if (terseUpdateBlocks.IsValueCreated)
3979 {
3980 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3981
3982 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3983 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3984 packet.RegionData.TimeDilation = timeDilation;
3985 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3986
3987 for (int i = 0; i < blocks.Count; i++)
3988 packet.ObjectData[i] = blocks[i];
3989
3990 OutPacket(packet, ThrottleOutPacketType.Task, true);
3885 } 3991 }
3886 3992
3887 #endregion Packet Sending 3993 #endregion Packet Sending
@@ -4174,11 +4280,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4174 4280
4175 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4281 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4176 // of the object rather than the properties when the packet was created 4282 // of the object rather than the properties when the packet was created
4177 OutPacket(packet, ThrottleOutPacketType.Task, true, 4283 // HACK : Remove intelligent resending until it's fixed in core
4178 delegate(OutgoingPacket oPacket) 4284 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4179 { 4285 // delegate(OutgoingPacket oPacket)
4180 ResendPropertyUpdates(updates, oPacket); 4286 // {
4181 }); 4287 // ResendPropertyUpdates(updates, oPacket);
4288 // });
4289 OutPacket(packet, ThrottleOutPacketType.Task, true);
4182 4290
4183 // pbcnt += blocks.Count; 4291 // pbcnt += blocks.Count;
4184 // ppcnt++; 4292 // ppcnt++;
@@ -4204,11 +4312,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4204 // of the object rather than the properties when the packet was created 4312 // of the object rather than the properties when the packet was created
4205 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4313 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4206 updates.Add(familyUpdates.Value[i]); 4314 updates.Add(familyUpdates.Value[i]);
4207 OutPacket(packet, ThrottleOutPacketType.Task, true, 4315 // HACK : Remove intelligent resending until it's fixed in core
4208 delegate(OutgoingPacket oPacket) 4316 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4209 { 4317 // delegate(OutgoingPacket oPacket)
4210 ResendPropertyUpdates(updates, oPacket); 4318 // {
4211 }); 4319 // ResendPropertyUpdates(updates, oPacket);
4320 // });
4321 OutPacket(packet, ThrottleOutPacketType.Task, true);
4212 4322
4213 // fpcnt++; 4323 // fpcnt++;
4214 // fbcnt++; 4324 // fbcnt++;
@@ -4357,37 +4467,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4357 if (bl[i].BannedUserID == UUID.Zero) 4467 if (bl[i].BannedUserID == UUID.Zero)
4358 continue; 4468 continue;
4359 BannedUsers.Add(bl[i].BannedUserID); 4469 BannedUsers.Add(bl[i].BannedUserID);
4360 }
4361 4470
4362 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4471 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4363 packet.AgentData.TransactionID = UUID.Random(); 4472 {
4364 packet.AgentData.AgentID = AgentId; 4473 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4365 packet.AgentData.SessionID = SessionId; 4474 packet.AgentData.TransactionID = UUID.Random();
4366 packet.MethodData.Invoice = invoice; 4475 packet.AgentData.AgentID = AgentId;
4367 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4476 packet.AgentData.SessionID = SessionId;
4477 packet.MethodData.Invoice = invoice;
4478 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4368 4479
4369 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4480 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4370 4481
4371 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4482 int j;
4372 { 4483 for (j = 0; j < (6 + BannedUsers.Count); j++)
4373 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4484 {
4374 } 4485 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4375 int j = 0; 4486 }
4487 j = 0;
4376 4488
4377 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4489 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4378 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4490 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4379 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4491 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4380 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4492 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4381 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4493 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4382 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4494 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4383 4495
4384 foreach (UUID banned in BannedUsers) 4496 foreach (UUID banned in BannedUsers)
4385 { 4497 {
4386 returnblock[j].Parameter = banned.GetBytes(); j++; 4498 returnblock[j].Parameter = banned.GetBytes(); j++;
4499 }
4500 packet.ParamList = returnblock;
4501 packet.Header.Reliable = true;
4502 OutPacket(packet, ThrottleOutPacketType.Task);
4503
4504 BannedUsers.Clear();
4505 }
4387 } 4506 }
4388 packet.ParamList = returnblock; 4507
4389 packet.Header.Reliable = false;
4390 OutPacket(packet, ThrottleOutPacketType.Task);
4391 } 4508 }
4392 4509
4393 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4510 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4573,7 +4690,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4573 4690
4574 if (landData.SimwideArea > 0) 4691 if (landData.SimwideArea > 0)
4575 { 4692 {
4576 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4693 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4694 // Never report more than sim total capacity
4695 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4696 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4577 updateMessage.SimWideMaxPrims = simulatorCapacity; 4697 updateMessage.SimWideMaxPrims = simulatorCapacity;
4578 } 4698 }
4579 else 4699 else
@@ -4702,14 +4822,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4702 4822
4703 if (notifyCount > 0) 4823 if (notifyCount > 0)
4704 { 4824 {
4705 if (notifyCount > 32) 4825// if (notifyCount > 32)
4706 { 4826// {
4707 m_log.InfoFormat( 4827// m_log.InfoFormat(
4708 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4828// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4709 + " - a developer might want to investigate whether this is a hard limit", 32); 4829// + " - a developer might want to investigate whether this is a hard limit", 32);
4710 4830//
4711 notifyCount = 32; 4831// notifyCount = 32;
4712 } 4832// }
4713 4833
4714 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4834 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4715 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4835 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4764,9 +4884,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4764 { 4884 {
4765 ScenePresence presence = (ScenePresence)entity; 4885 ScenePresence presence = (ScenePresence)entity;
4766 4886
4887 position = presence.OffsetPosition;
4888 rotation = presence.Rotation;
4889
4890 if (presence.ParentID != 0)
4891 {
4892 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4893 if (part != null && part != part.ParentGroup.RootPart)
4894 {
4895 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4896 rotation = part.RotationOffset * presence.Rotation;
4897 }
4898 }
4899
4767 attachPoint = 0; 4900 attachPoint = 0;
4768 collisionPlane = presence.CollisionPlane; 4901 collisionPlane = presence.CollisionPlane;
4769 position = presence.OffsetPosition;
4770 velocity = presence.Velocity; 4902 velocity = presence.Velocity;
4771 acceleration = Vector3.Zero; 4903 acceleration = Vector3.Zero;
4772 4904
@@ -4776,7 +4908,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4776// acceleration = new Vector3(1, 0, 0); 4908// acceleration = new Vector3(1, 0, 0);
4777 4909
4778 angularVelocity = Vector3.Zero; 4910 angularVelocity = Vector3.Zero;
4779 rotation = presence.Rotation;
4780 4911
4781 if (sendTexture) 4912 if (sendTexture)
4782 textureEntry = presence.Appearance.Texture.GetBytes(); 4913 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4881,13 +5012,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4881 5012
4882 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5013 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4883 { 5014 {
5015 Vector3 offsetPosition = data.OffsetPosition;
5016 Quaternion rotation = data.Rotation;
5017 uint parentID = data.ParentID;
5018
5019 if (parentID != 0)
5020 {
5021 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5022 if (part != null && part != part.ParentGroup.RootPart)
5023 {
5024 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5025 rotation = part.RotationOffset * data.Rotation;
5026 parentID = part.ParentGroup.RootPart.LocalId;
5027 }
5028 }
5029
4884 byte[] objectData = new byte[76]; 5030 byte[] objectData = new byte[76];
4885 5031
4886 data.CollisionPlane.ToBytes(objectData, 0); 5032 data.CollisionPlane.ToBytes(objectData, 0);
4887 data.OffsetPosition.ToBytes(objectData, 16); 5033 offsetPosition.ToBytes(objectData, 16);
4888// data.Velocity.ToBytes(objectData, 28); 5034// data.Velocity.ToBytes(objectData, 28);
4889// data.Acceleration.ToBytes(objectData, 40); 5035// data.Acceleration.ToBytes(objectData, 40);
4890 data.Rotation.ToBytes(objectData, 52); 5036 rotation.ToBytes(objectData, 52);
4891 //data.AngularVelocity.ToBytes(objectData, 64); 5037 //data.AngularVelocity.ToBytes(objectData, 64);
4892 5038
4893 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5039 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4901,7 +5047,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4901 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5047 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4902 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5048 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4903 update.ObjectData = objectData; 5049 update.ObjectData = objectData;
4904 update.ParentID = data.ParentID; 5050 update.ParentID = parentID;
4905 update.PathCurve = 16; 5051 update.PathCurve = 16;
4906 update.PathScaleX = 100; 5052 update.PathScaleX = 100;
4907 update.PathScaleY = 100; 5053 update.PathScaleY = 100;
@@ -5242,6 +5388,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5242 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5388 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5243 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5389 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5244 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5390 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5391 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5245 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5392 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5246 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5393 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5247 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5394 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5308,6 +5455,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5308 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5455 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5309 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5456 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5310 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5457 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5458 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5311 5459
5312 AddGenericPacketHandler("autopilot", HandleAutopilot); 5460 AddGenericPacketHandler("autopilot", HandleAutopilot);
5313 } 5461 }
@@ -5343,6 +5491,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5343 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5491 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5344 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5492 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5345 (x.ControlFlags != lastarg.ControlFlags) || 5493 (x.ControlFlags != lastarg.ControlFlags) ||
5494 (x.ControlFlags != 0) ||
5346 (x.Far != lastarg.Far) || 5495 (x.Far != lastarg.Far) ||
5347 (x.Flags != lastarg.Flags) || 5496 (x.Flags != lastarg.Flags) ||
5348 (x.State != lastarg.State) || 5497 (x.State != lastarg.State) ||
@@ -5720,7 +5869,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5720 args.Channel = ch; 5869 args.Channel = ch;
5721 args.From = String.Empty; 5870 args.From = String.Empty;
5722 args.Message = Utils.BytesToString(msg); 5871 args.Message = Utils.BytesToString(msg);
5723 args.Type = ChatTypeEnum.Shout; 5872 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5724 args.Position = new Vector3(); 5873 args.Position = new Vector3();
5725 args.Scene = Scene; 5874 args.Scene = Scene;
5726 args.Sender = this; 5875 args.Sender = this;
@@ -6257,7 +6406,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6257 return true; 6406 return true;
6258 } 6407 }
6259 #endregion 6408 #endregion
6260 6409/*
6261 StartAnim handlerStartAnim = null; 6410 StartAnim handlerStartAnim = null;
6262 StopAnim handlerStopAnim = null; 6411 StopAnim handlerStopAnim = null;
6263 6412
@@ -6281,6 +6430,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6281 } 6430 }
6282 } 6431 }
6283 return true; 6432 return true;
6433*/
6434 ChangeAnim handlerChangeAnim = null;
6435
6436 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6437 {
6438 handlerChangeAnim = OnChangeAnim;
6439 if (handlerChangeAnim != null)
6440 {
6441 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6442 }
6443 }
6444
6445 handlerChangeAnim = OnChangeAnim;
6446 if (handlerChangeAnim != null)
6447 {
6448 handlerChangeAnim(UUID.Zero, false, true);
6449 }
6450
6451 return true;
6284 } 6452 }
6285 6453
6286 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6454 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6906,10 +7074,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6906 // 46,47,48 are special positions within the packet 7074 // 46,47,48 are special positions within the packet
6907 // This may change so perhaps we need a better way 7075 // This may change so perhaps we need a better way
6908 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7076 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6909 bool UsePhysics = (data[46] != 0) ? true : false; 7077 /*
6910 bool IsTemporary = (data[47] != 0) ? true : false; 7078 bool UsePhysics = (data[46] != 0) ? true : false;
6911 bool IsPhantom = (data[48] != 0) ? true : false; 7079 bool IsTemporary = (data[47] != 0) ? true : false;
6912 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7080 bool IsPhantom = (data[48] != 0) ? true : false;
7081 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7082 */
7083 bool UsePhysics = flags.AgentData.UsePhysics;
7084 bool IsPhantom = flags.AgentData.IsPhantom;
7085 bool IsTemporary = flags.AgentData.IsTemporary;
7086 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7087 ExtraPhysicsData physdata = new ExtraPhysicsData();
7088
7089 if (blocks == null || blocks.Length == 0)
7090 {
7091 physdata.PhysShapeType = PhysShapeType.invalid;
7092 }
7093 else
7094 {
7095 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7096 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7097 physdata.Bounce = phsblock.Restitution;
7098 physdata.Density = phsblock.Density;
7099 physdata.Friction = phsblock.Friction;
7100 physdata.GravitationModifier = phsblock.GravityMultiplier;
7101 }
7102
7103 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
6913 } 7104 }
6914 return true; 7105 return true;
6915 } 7106 }
@@ -9763,7 +9954,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9763 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9954 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9764 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9955 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9765 UpdateMuteListEntry.MuteData.MuteType, 9956 UpdateMuteListEntry.MuteData.MuteType,
9766 UpdateMuteListEntry.AgentData.AgentID); 9957 UpdateMuteListEntry.MuteData.MuteFlags);
9767 return true; 9958 return true;
9768 } 9959 }
9769 return false; 9960 return false;
@@ -9778,8 +9969,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9778 { 9969 {
9779 handlerRemoveMuteListEntry(this, 9970 handlerRemoveMuteListEntry(this,
9780 RemoveMuteListEntry.MuteData.MuteID, 9971 RemoveMuteListEntry.MuteData.MuteID,
9781 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9972 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9782 RemoveMuteListEntry.AgentData.AgentID);
9783 return true; 9973 return true;
9784 } 9974 }
9785 return false; 9975 return false;
@@ -9823,10 +10013,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9823 return false; 10013 return false;
9824 } 10014 }
9825 10015
10016 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10017 {
10018 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10019 (ChangeInventoryItemFlagsPacket)packet;
10020 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10021 if (handlerChangeInventoryItemFlags != null)
10022 {
10023 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10024 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10025 return true;
10026 }
10027 return false;
10028 }
10029
9826 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10030 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9827 { 10031 {
9828 return true; 10032 return true;
9829 } 10033 }
10034
10035 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10036 {
10037 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10038
10039 #region Packet Session and User Check
10040 if (m_checkPackets)
10041 {
10042 if (packet.AgentData.SessionID != SessionId ||
10043 packet.AgentData.AgentID != AgentId)
10044 return true;
10045 }
10046 #endregion
10047 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10048 List<InventoryItemBase> items = new List<InventoryItemBase>();
10049 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10050 {
10051 InventoryItemBase b = new InventoryItemBase();
10052 b.ID = n.OldItemID;
10053 b.Folder = n.OldFolderID;
10054 items.Add(b);
10055 }
10056
10057 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10058 if (handlerMoveItemsAndLeaveCopy != null)
10059 {
10060 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10061 }
10062
10063 return true;
10064 }
9830 10065
9831 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10066 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9832 { 10067 {
@@ -10253,6 +10488,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10253 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10488 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10254 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10489 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10255 10490
10491 Scene scene = (Scene)m_scene;
10492 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10493 {
10494 ScenePresence p;
10495 if (scene.TryGetScenePresence(sender.AgentId, out p))
10496 {
10497 if (p.GodLevel >= 200)
10498 {
10499 groupProfileReply.GroupData.OpenEnrollment = true;
10500 groupProfileReply.GroupData.MembershipFee = 0;
10501 }
10502 }
10503 }
10504
10256 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10505 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10257 } 10506 }
10258 return true; 10507 return true;
@@ -10826,11 +11075,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10826 11075
10827 StartLure handlerStartLure = OnStartLure; 11076 StartLure handlerStartLure = OnStartLure;
10828 if (handlerStartLure != null) 11077 if (handlerStartLure != null)
10829 handlerStartLure(startLureRequest.Info.LureType, 11078 {
10830 Utils.BytesToString( 11079 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10831 startLureRequest.Info.Message), 11080 {
10832 startLureRequest.TargetData[0].TargetID, 11081 handlerStartLure(startLureRequest.Info.LureType,
10833 this); 11082 Utils.BytesToString(
11083 startLureRequest.Info.Message),
11084 startLureRequest.TargetData[i].TargetID,
11085 this);
11086 }
11087 }
10834 return true; 11088 return true;
10835 } 11089 }
10836 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11090 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -10944,10 +11198,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10944 } 11198 }
10945 #endregion 11199 #endregion
10946 11200
10947 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11201 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
10948 if (handlerClassifiedGodDelete != null) 11202 if (handlerClassifiedGodDelete != null)
10949 handlerClassifiedGodDelete( 11203 handlerClassifiedGodDelete(
10950 classifiedGodDelete.Data.ClassifiedID, 11204 classifiedGodDelete.Data.ClassifiedID,
11205 classifiedGodDelete.Data.QueryID,
10951 this); 11206 this);
10952 return true; 11207 return true;
10953 } 11208 }
@@ -11313,209 +11568,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11313 } 11568 }
11314 else 11569 else
11315 { 11570 {
11316// m_log.DebugFormat( 11571 ClientChangeObject updatehandler = onClientChangeObject;
11317// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11318// i, block.Type, part.Name, part.LocalId);
11319 11572
11320// // Do this once since fetch parts creates a new array. 11573 if (updatehandler != null)
11321// SceneObjectPart[] parts = part.ParentGroup.Parts; 11574 {
11322// for (int j = 0; j < parts.Length; j++) 11575 ObjectChangeData udata = new ObjectChangeData();
11323// {
11324// part.StoreUndoState();
11325// parts[j].IgnoreUndoUpdate = true;
11326// }
11327 11576
11328 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11577 /*ubit from ll JIRA:
11578 * 0x01 position
11579 * 0x02 rotation
11580 * 0x04 scale
11581
11582 * 0x08 LINK_SET
11583 * 0x10 UNIFORM for scale
11584 */
11329 11585
11330 switch (block.Type) 11586 // translate to internal changes
11331 { 11587 // not all cases .. just the ones older code did
11332 case 1:
11333 Vector3 pos1 = new Vector3(block.Data, 0);
11334 11588
11335 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11589 switch (block.Type)
11336 if (handlerUpdatePrimSinglePosition != null) 11590 {
11337 { 11591 case 1: //change position sp
11338 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11592 udata.position = new Vector3(block.Data, 0);
11339 handlerUpdatePrimSinglePosition(localId, pos1, this);
11340 }
11341 break;
11342 11593
11343 case 2: 11594 udata.change = ObjectChangeType.primP;
11344 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11595 updatehandler(localId, udata, this);
11596 break;
11345 11597
11346 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11598 case 2: // rotation sp
11347 if (handlerUpdatePrimSingleRotation != null) 11599 udata.rotation = new Quaternion(block.Data, 0, true);
11348 {
11349 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11350 handlerUpdatePrimSingleRotation(localId, rot1, this);
11351 }
11352 break;
11353 11600
11354 case 3: 11601 udata.change = ObjectChangeType.primR;
11355 Vector3 rotPos = new Vector3(block.Data, 0); 11602 updatehandler(localId, udata, this);
11356 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11603 break;
11357 11604
11358 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11605 case 3: // position plus rotation
11359 if (handlerUpdatePrimSingleRotationPosition != null) 11606 udata.position = new Vector3(block.Data, 0);
11360 { 11607 udata.rotation = new Quaternion(block.Data, 12, true);
11361 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11362 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11363 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11364 }
11365 break;
11366 11608
11367 case 4: 11609 udata.change = ObjectChangeType.primPR;
11368 case 20: 11610 updatehandler(localId, udata, this);
11369 Vector3 scale4 = new Vector3(block.Data, 0); 11611 break;
11370 11612
11371 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11613 case 4: // scale sp
11372 if (handlerUpdatePrimScale != null) 11614 udata.scale = new Vector3(block.Data, 0);
11373 { 11615 udata.change = ObjectChangeType.primS;
11374 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11375 handlerUpdatePrimScale(localId, scale4, this);
11376 }
11377 break;
11378 11616
11379 case 5: 11617 updatehandler(localId, udata, this);
11380 Vector3 scale1 = new Vector3(block.Data, 12); 11618 break;
11381 Vector3 pos11 = new Vector3(block.Data, 0);
11382 11619
11383 handlerUpdatePrimScale = OnUpdatePrimScale; 11620 case 0x14: // uniform scale sp
11384 if (handlerUpdatePrimScale != null) 11621 udata.scale = new Vector3(block.Data, 0);
11385 {
11386 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11387 handlerUpdatePrimScale(localId, scale1, this);
11388 11622
11389 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11623 udata.change = ObjectChangeType.primUS;
11390 if (handlerUpdatePrimSinglePosition != null) 11624 updatehandler(localId, udata, this);
11391 { 11625 break;
11392 handlerUpdatePrimSinglePosition(localId, pos11, this);
11393 }
11394 }
11395 break;
11396 11626
11397 case 9: 11627 case 5: // scale and position sp
11398 Vector3 pos2 = new Vector3(block.Data, 0); 11628 udata.position = new Vector3(block.Data, 0);
11629 udata.scale = new Vector3(block.Data, 12);
11399 11630
11400 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11631 udata.change = ObjectChangeType.primPS;
11632 updatehandler(localId, udata, this);
11633 break;
11401 11634
11402 if (handlerUpdateVector != null) 11635 case 0x15: //uniform scale and position
11403 { 11636 udata.position = new Vector3(block.Data, 0);
11404 handlerUpdateVector(localId, pos2, this); 11637 udata.scale = new Vector3(block.Data, 12);
11405 }
11406 break;
11407 11638
11408 case 10: 11639 udata.change = ObjectChangeType.primPUS;
11409 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11640 updatehandler(localId, udata, this);
11641 break;
11410 11642
11411 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11643 // now group related (bit 4)
11412 if (handlerUpdatePrimRotation != null) 11644 case 9: //( 8 + 1 )group position
11413 { 11645 udata.position = new Vector3(block.Data, 0);
11414 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11415 handlerUpdatePrimRotation(localId, rot3, this);
11416 }
11417 break;
11418 11646
11419 case 11: 11647 udata.change = ObjectChangeType.groupP;
11420 Vector3 pos3 = new Vector3(block.Data, 0); 11648 updatehandler(localId, udata, this);
11421 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11649 break;
11422 11650
11423 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11651 case 0x0A: // (8 + 2) group rotation
11424 if (handlerUpdatePrimGroupRotation != null) 11652 udata.rotation = new Quaternion(block.Data, 0, true);
11425 {
11426 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11427 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11428 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11429 }
11430 break;
11431 case 12:
11432 case 28:
11433 Vector3 scale7 = new Vector3(block.Data, 0);
11434 11653
11435 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11654 udata.change = ObjectChangeType.groupR;
11436 if (handlerUpdatePrimGroupScale != null) 11655 updatehandler(localId, udata, this);
11437 { 11656 break;
11438 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11439 handlerUpdatePrimGroupScale(localId, scale7, this);
11440 }
11441 break;
11442 11657
11443 case 13: 11658 case 0x0B: //( 8 + 2 + 1) group rotation and position
11444 Vector3 scale2 = new Vector3(block.Data, 12); 11659 udata.position = new Vector3(block.Data, 0);
11445 Vector3 pos4 = new Vector3(block.Data, 0); 11660 udata.rotation = new Quaternion(block.Data, 12, true);
11446 11661
11447 handlerUpdatePrimScale = OnUpdatePrimScale; 11662 udata.change = ObjectChangeType.groupPR;
11448 if (handlerUpdatePrimScale != null) 11663 updatehandler(localId, udata, this);
11449 { 11664 break;
11450 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11451 handlerUpdatePrimScale(localId, scale2, this);
11452 11665
11453 // Change the position based on scale (for bug number 246) 11666 case 0x0C: // (8 + 4) group scale
11454 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11667 // only afects root prim and only sent by viewer editor object tab scaling
11455 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11668 // mouse edition only allows uniform scaling
11456 if (handlerUpdatePrimSinglePosition != null) 11669 // SL MAY CHANGE THIS in viewers
11457 {
11458 handlerUpdatePrimSinglePosition(localId, pos4, this);
11459 }
11460 }
11461 break;
11462 11670
11463 case 29: 11671 udata.scale = new Vector3(block.Data, 0);
11464 Vector3 scale5 = new Vector3(block.Data, 12);
11465 Vector3 pos5 = new Vector3(block.Data, 0);
11466 11672
11467 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11673 udata.change = ObjectChangeType.groupS;
11468 if (handlerUpdatePrimGroupScale != null) 11674 updatehandler(localId, udata, this);
11469 {
11470 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11471 part.StoreUndoState(true);
11472 part.IgnoreUndoUpdate = true;
11473 handlerUpdatePrimGroupScale(localId, scale5, this);
11474 handlerUpdateVector = OnUpdatePrimGroupPosition;
11475 11675
11476 if (handlerUpdateVector != null) 11676 break;
11477 {
11478 handlerUpdateVector(localId, pos5, this);
11479 }
11480 11677
11481 part.IgnoreUndoUpdate = false; 11678 case 0x0D: //(8 + 4 + 1) group scale and position
11482 } 11679 // exception as above
11483 11680
11484 break; 11681 udata.position = new Vector3(block.Data, 0);
11682 udata.scale = new Vector3(block.Data, 12);
11485 11683
11486 case 21: 11684 udata.change = ObjectChangeType.groupPS;
11487 Vector3 scale6 = new Vector3(block.Data, 12); 11685 updatehandler(localId, udata, this);
11488 Vector3 pos6 = new Vector3(block.Data, 0); 11686 break;
11489 11687
11490 handlerUpdatePrimScale = OnUpdatePrimScale; 11688 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11491 if (handlerUpdatePrimScale != null) 11689 udata.scale = new Vector3(block.Data, 0);
11492 {
11493 part.StoreUndoState(false);
11494 part.IgnoreUndoUpdate = true;
11495 11690
11496 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11691 udata.change = ObjectChangeType.groupUS;
11497 handlerUpdatePrimScale(localId, scale6, this); 11692 updatehandler(localId, udata, this);
11498 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11693 break;
11499 if (handlerUpdatePrimSinglePosition != null)
11500 {
11501 handlerUpdatePrimSinglePosition(localId, pos6, this);
11502 }
11503 11694
11504 part.IgnoreUndoUpdate = false; 11695 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11505 } 11696 udata.position = new Vector3(block.Data, 0);
11506 break; 11697 udata.scale = new Vector3(block.Data, 12);
11507 11698
11508 default: 11699 udata.change = ObjectChangeType.groupPUS;
11509 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11700 updatehandler(localId, udata, this);
11510 break; 11701 break;
11702
11703 default:
11704 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11705 break;
11706 }
11511 } 11707 }
11512 11708
11513// for (int j = 0; j < parts.Length; j++)
11514// parts[j].IgnoreUndoUpdate = false;
11515 } 11709 }
11516 } 11710 }
11517 } 11711 }
11518
11519 return true; 11712 return true;
11520 } 11713 }
11521 11714
@@ -11974,7 +12167,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11974// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12167// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
11975// requestID, taskID, (SourceType)sourceType, Name); 12168// requestID, taskID, (SourceType)sourceType, Name);
11976 12169
12170
12171 //Note, the bool returned from the below function is useless since it is always false.
11977 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12172 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12173
11978 } 12174 }
11979 12175
11980 /// <summary> 12176 /// <summary>
@@ -12028,7 +12224,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12028 /// <returns></returns> 12224 /// <returns></returns>
12029 private static int CalculateNumPackets(byte[] data) 12225 private static int CalculateNumPackets(byte[] data)
12030 { 12226 {
12031 const uint m_maxPacketSize = 600; 12227// const uint m_maxPacketSize = 600;
12228 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12032 int numPackets = 1; 12229 int numPackets = 1;
12033 12230
12034 if (data == null) 12231 if (data == null)
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 edf91cb..dda4444 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1053,7 +1053,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1053 if (m_scene.TryGetClient(udpClient.AgentID, out client)) 1053 if (m_scene.TryGetClient(udpClient.AgentID, out client))
1054 { 1054 {
1055 client.IsLoggingOut = true; 1055 client.IsLoggingOut = true;
1056 client.Close(); 1056 client.Close(false);
1057 } 1057 }
1058 } 1058 }
1059 1059
@@ -1065,6 +1065,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1065 1065
1066 while (base.IsRunning) 1066 while (base.IsRunning)
1067 { 1067 {
1068 m_scene.ThreadAlive(1);
1068 try 1069 try
1069 { 1070 {
1070 IncomingPacket incomingPacket = null; 1071 IncomingPacket incomingPacket = null;
@@ -1107,6 +1108,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1107 1108
1108 while (base.IsRunning) 1109 while (base.IsRunning)
1109 { 1110 {
1111 m_scene.ThreadAlive(2);
1110 try 1112 try
1111 { 1113 {
1112 m_packetSent = false; 1114 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,