aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs158
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs10
-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.cs1181
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs11
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
8 files changed, 910 insertions, 542 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 594b229..ebfe687 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -377,7 +377,7 @@ namespace OpenSim.Region.ClientStack.Linden
377 // TODO: Add EventQueueGet name/description for diagnostics 377 // TODO: Add EventQueueGet name/description for diagnostics
378 MainServer.Instance.AddPollServiceHTTPHandler( 378 MainServer.Instance.AddPollServiceHTTPHandler(
379 eventQueueGetPath, 379 eventQueueGetPath,
380 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID)); 380 new PollServiceEventArgs(null, HasEvents, GetEvents, NoEvents, agentID, 1000));
381 381
382// m_log.DebugFormat( 382// m_log.DebugFormat(
383// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}", 383// "[EVENT QUEUE GET MODULE]: Registered EQG handler {0} for {1} in {2}",
@@ -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 8874585..3461971 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,14 +343,15 @@ 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;
343 350
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; } }
@@ -456,7 +472,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
456 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 472 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
457 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 473 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
458 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 474 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
459 m_killRecord = new HashSet<uint>(); 475// m_killRecord = new HashSet<uint>();
460// m_attachmentsSent = new HashSet<uint>(); 476// m_attachmentsSent = new HashSet<uint>();
461 477
462 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 478 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -485,17 +501,35 @@ 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 IsActive = false; 518 IsActive = false;
494 519
495 m_log.DebugFormat( 520 m_log.DebugFormat(
496 "[CLIENT]: Close has been called for {0} attached to scene {1}", 521 "[CLIENT]: Close has been called for {0} attached to scene {1}",
497 Name, m_scene.RegionInfo.RegionName); 522 Name, m_scene.RegionInfo.RegionName);
498 523
524 if (sendStop)
525 {
526 // Send the STOP packet
527 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
528 OutPacket(disable, ThrottleOutPacketType.Unknown);
529 }
530
531 IsActive = false;
532
499 // Shutdown the image manager 533 // Shutdown the image manager
500 ImageManager.Close(); 534 ImageManager.Close();
501 535
@@ -792,7 +826,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
792 reply.ChatData.OwnerID = fromAgentID; 826 reply.ChatData.OwnerID = fromAgentID;
793 reply.ChatData.SourceID = fromAgentID; 827 reply.ChatData.SourceID = fromAgentID;
794 828
795 OutPacket(reply, ThrottleOutPacketType.Task); 829 OutPacket(reply, ThrottleOutPacketType.Unknown);
796 } 830 }
797 831
798 /// <summary> 832 /// <summary>
@@ -1078,6 +1112,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1078 public virtual void SendLayerData(float[] map) 1112 public virtual void SendLayerData(float[] map)
1079 { 1113 {
1080 Util.FireAndForget(DoSendLayerData, map); 1114 Util.FireAndForget(DoSendLayerData, map);
1115
1116 // Send it sync, and async. It's not that much data
1117 // and it improves user experience just so much!
1118 DoSendLayerData(map);
1081 } 1119 }
1082 1120
1083 /// <summary> 1121 /// <summary>
@@ -1090,16 +1128,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1090 1128
1091 try 1129 try
1092 { 1130 {
1093 //for (int y = 0; y < 16; y++) 1131 for (int y = 0; y < 16; y++)
1094 //{ 1132 {
1095 // for (int x = 0; x < 16; x++) 1133 for (int x = 0; x < 16; x+=4)
1096 // { 1134 {
1097 // SendLayerData(x, y, map); 1135 SendLayerPacket(x, y, map);
1098 // } 1136 }
1099 //} 1137 }
1100
1101 // Send LayerData in a spiral pattern. Fun!
1102 SendLayerTopRight(map, 0, 0, 15, 15);
1103 } 1138 }
1104 catch (Exception e) 1139 catch (Exception e)
1105 { 1140 {
@@ -1107,51 +1142,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1107 } 1142 }
1108 } 1143 }
1109 1144
1110 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1111 {
1112 // Row
1113 for (int i = x1; i <= x2; i++)
1114 SendLayerData(i, y1, map);
1115
1116 // Column
1117 for (int j = y1 + 1; j <= y2; j++)
1118 SendLayerData(x2, j, map);
1119
1120 if (x2 - x1 > 0)
1121 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1122 }
1123
1124 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1125 {
1126 // Row in reverse
1127 for (int i = x2; i >= x1; i--)
1128 SendLayerData(i, y2, map);
1129
1130 // Column in reverse
1131 for (int j = y2 - 1; j >= y1; j--)
1132 SendLayerData(x1, j, map);
1133
1134 if (x2 - x1 > 0)
1135 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1136 }
1137
1138 /// <summary> 1145 /// <summary>
1139 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1146 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1140 /// </summary> 1147 /// </summary>
1141 /// <param name="map">heightmap</param> 1148 /// <param name="map">heightmap</param>
1142 /// <param name="px">X coordinate for patches 0..12</param> 1149 /// <param name="px">X coordinate for patches 0..12</param>
1143 /// <param name="py">Y coordinate for patches 0..15</param> 1150 /// <param name="py">Y coordinate for patches 0..15</param>
1144 // private void SendLayerPacket(float[] map, int y, int x) 1151 private void SendLayerPacket(int x, int y, float[] map)
1145 // { 1152 {
1146 // int[] patches = new int[4]; 1153 int[] patches = new int[4];
1147 // patches[0] = x + 0 + y * 16; 1154 patches[0] = x + 0 + y * 16;
1148 // patches[1] = x + 1 + y * 16; 1155 patches[1] = x + 1 + y * 16;
1149 // patches[2] = x + 2 + y * 16; 1156 patches[2] = x + 2 + y * 16;
1150 // patches[3] = x + 3 + y * 16; 1157 patches[3] = x + 3 + y * 16;
1151 1158
1152 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1159 float[] heightmap = (map.Length == 65536) ?
1153 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1160 map :
1154 // } 1161 LLHeightFieldMoronize(map);
1162
1163 try
1164 {
1165 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1166 OutPacket(layerpack, ThrottleOutPacketType.Land);
1167 }
1168 catch
1169 {
1170 for (int px = x ; px < x + 4 ; px++)
1171 SendLayerData(px, y, map);
1172 }
1173 }
1155 1174
1156 /// <summary> 1175 /// <summary>
1157 /// Sends a specified patch to a client 1176 /// Sends a specified patch to a client
@@ -1171,7 +1190,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1171 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1190 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1172 layerpack.Header.Reliable = true; 1191 layerpack.Header.Reliable = true;
1173 1192
1174 OutPacket(layerpack, ThrottleOutPacketType.Land); 1193 OutPacket(layerpack, ThrottleOutPacketType.Task);
1175 } 1194 }
1176 catch (Exception e) 1195 catch (Exception e)
1177 { 1196 {
@@ -1534,7 +1553,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1534 1553
1535 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1554 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1536 { 1555 {
1537// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1556// foreach (uint id in localIDs)
1557// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1538 1558
1539 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1559 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1540 // TODO: don't create new blocks if recycling an old packet 1560 // TODO: don't create new blocks if recycling an old packet
@@ -1556,17 +1576,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1556 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1576 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1557 // condition where a kill can be processed before an out-of-date update for the same object. 1577 // condition where a kill can be processed before an out-of-date update for the same object.
1558 // ProcessEntityUpdates() also takes the m_killRecord lock. 1578 // ProcessEntityUpdates() also takes the m_killRecord lock.
1559 lock (m_killRecord) 1579// lock (m_killRecord)
1560 { 1580// {
1561 foreach (uint localID in localIDs) 1581// foreach (uint localID in localIDs)
1562 m_killRecord.Add(localID); 1582// m_killRecord.Add(localID);
1563 1583
1564 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1584 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1565 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1585 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1566 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1586 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1567 // scene objects in a viewer until that viewer is relogged in. 1587 // scene objects in a viewer until that viewer is relogged in.
1568 OutPacket(kill, ThrottleOutPacketType.Task); 1588 OutPacket(kill, ThrottleOutPacketType.Task);
1569 } 1589// }
1570 } 1590 }
1571 } 1591 }
1572 1592
@@ -2296,6 +2316,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2296 OutPacket(sound, ThrottleOutPacketType.Task); 2316 OutPacket(sound, ThrottleOutPacketType.Task);
2297 } 2317 }
2298 2318
2319 public void SendTransferAbort(TransferRequestPacket transferRequest)
2320 {
2321 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2322 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2323 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2324 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2325 OutPacket(abort, ThrottleOutPacketType.Task);
2326 }
2327
2299 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2328 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2300 { 2329 {
2301 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2330 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2588,6 +2617,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2588 } 2617 }
2589 } 2618 }
2590 2619
2620 public void SendPartPhysicsProprieties(ISceneEntity entity)
2621 {
2622 SceneObjectPart part = (SceneObjectPart)entity;
2623 if (part != null && AgentId != UUID.Zero)
2624 {
2625 try
2626 {
2627 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2628 if (eq != null)
2629 {
2630 uint localid = part.LocalId;
2631 byte physshapetype = part.PhysicsShapeType;
2632 float density = part.Density;
2633 float friction = part.Friction;
2634 float bounce = part.Bounciness;
2635 float gravmod = part.GravityModifier;
2636
2637 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2638 }
2639 }
2640 catch (Exception ex)
2641 {
2642 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2643 }
2644 part.UpdatePhysRequired = false;
2645 }
2646 }
2647
2648
2591 2649
2592 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2650 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2593 { 2651 {
@@ -2685,7 +2743,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2685 else 2743 else
2686 { 2744 {
2687 int processedLength = 0; 2745 int processedLength = 0;
2688 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2746// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2747
2748 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2689 int packetNumber = 0; 2749 int packetNumber = 0;
2690 2750
2691 while (processedLength < req.AssetInf.Data.Length) 2751 while (processedLength < req.AssetInf.Data.Length)
@@ -2756,7 +2816,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2756 reply.Data.ParcelID = parcelID; 2816 reply.Data.ParcelID = parcelID;
2757 reply.Data.OwnerID = land.OwnerID; 2817 reply.Data.OwnerID = land.OwnerID;
2758 reply.Data.Name = Utils.StringToBytes(land.Name); 2818 reply.Data.Name = Utils.StringToBytes(land.Name);
2759 reply.Data.Desc = Utils.StringToBytes(land.Description); 2819 if (land != null && land.Description != null && land.Description != String.Empty)
2820 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2821 else
2822 reply.Data.Desc = new Byte[0];
2760 reply.Data.ActualArea = land.Area; 2823 reply.Data.ActualArea = land.Area;
2761 reply.Data.BillableArea = land.Area; // TODO: what is this? 2824 reply.Data.BillableArea = land.Area; // TODO: what is this?
2762 2825
@@ -3491,7 +3554,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3491 3554
3492 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3555 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3493 // TODO: don't create new blocks if recycling an old packet 3556 // TODO: don't create new blocks if recycling an old packet
3494 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3557 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3495 avp.ObjectData.TextureEntry = textureEntry; 3558 avp.ObjectData.TextureEntry = textureEntry;
3496 3559
3497 AvatarAppearancePacket.VisualParamBlock avblock = null; 3560 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3619,7 +3682,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3619 /// </summary> 3682 /// </summary>
3620 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3683 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3621 { 3684 {
3622 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3685 if (entity is SceneObjectPart)
3686 {
3687 SceneObjectPart e = (SceneObjectPart)entity;
3688 SceneObjectGroup g = e.ParentGroup;
3689 if (g.RootPart.Shape.State > 30) // HUD
3690 if (g.OwnerID != AgentId)
3691 return; // Don't send updates for other people's HUDs
3692 }
3693
3623 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3694 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3624 3695
3625 lock (m_entityUpdates.SyncRoot) 3696 lock (m_entityUpdates.SyncRoot)
@@ -3686,27 +3757,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3686 3757
3687 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3758 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3688 // condition where a kill can be processed before an out-of-date update for the same object. 3759 // condition where a kill can be processed before an out-of-date update for the same object.
3689 lock (m_killRecord) 3760 float avgTimeDilation = 1.0f;
3761 IEntityUpdate iupdate;
3762 Int32 timeinqueue; // this is just debugging code & can be dropped later
3763
3764 while (updatesThisCall < maxUpdates)
3690 { 3765 {
3691 float avgTimeDilation = 1.0f; 3766 lock (m_entityUpdates.SyncRoot)
3692 IEntityUpdate iupdate; 3767 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3693 Int32 timeinqueue; // this is just debugging code & can be dropped later 3768 break;
3769
3770 EntityUpdate update = (EntityUpdate)iupdate;
3771
3772 avgTimeDilation += update.TimeDilation;
3773 avgTimeDilation *= 0.5f;
3694 3774
3695 while (updatesThisCall < maxUpdates) 3775 if (update.Entity is SceneObjectPart)
3696 { 3776 {
3697 lock (m_entityUpdates.SyncRoot) 3777 SceneObjectPart part = (SceneObjectPart)update.Entity;
3698 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3699 break;
3700 3778
3701 EntityUpdate update = (EntityUpdate)iupdate; 3779 if (part.ParentGroup.IsDeleted)
3702 3780 continue;
3703 avgTimeDilation += update.TimeDilation;
3704 avgTimeDilation *= 0.5f;
3705 3781
3706 if (update.Entity is SceneObjectPart) 3782 if (part.ParentGroup.IsAttachment)
3783 { // Someone else's HUD, why are we getting these?
3784 if (part.ParentGroup.OwnerID != AgentId &&
3785 part.ParentGroup.RootPart.Shape.State >= 30)
3786 continue;
3787 ScenePresence sp;
3788 // Owner is not in the sim, don't update it to
3789 // anyone
3790 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3791 continue;
3792
3793 List<SceneObjectGroup> atts = sp.GetAttachments();
3794 bool found = false;
3795 foreach (SceneObjectGroup att in atts)
3796 {
3797 if (att == part.ParentGroup)
3798 {
3799 found = true;
3800 break;
3801 }
3802 }
3803
3804 // It's an attachment of a valid avatar, but
3805 // doesn't seem to be attached, skip
3806 if (!found)
3807 continue;
3808
3809 // On vehicle crossing, the attachments are received
3810 // while the avatar is still a child. Don't send
3811 // updates here because the LocalId has not yet
3812 // been updated and the viewer will derender the
3813 // attachments until the avatar becomes root.
3814 if (sp.IsChildAgent)
3815 continue;
3816
3817 // If the object is an attachment we don't want it to be in the kill
3818 // record. Else attaching from inworld and subsequently dropping
3819 // it will no longer work.
3820// lock (m_killRecord)
3821// {
3822// m_killRecord.Remove(part.LocalId);
3823// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3824// }
3825 }
3826 else
3707 { 3827 {
3708 SceneObjectPart part = (SceneObjectPart)update.Entity;
3709
3710 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3828 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3711 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3829 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3712 // safety measure. 3830 // safety measure.
@@ -3717,236 +3835,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3717 // 3835 //
3718 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3836 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3719 // after the root prim has been deleted. 3837 // after the root prim has been deleted.
3720 if (m_killRecord.Contains(part.LocalId)) 3838 //
3721 { 3839 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3722 // m_log.WarnFormat( 3840// lock (m_killRecord)
3723 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3841// {
3724 // part.LocalId, Name); 3842// if (m_killRecord.Contains(part.LocalId))
3725 continue; 3843// continue;
3726 } 3844// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3727 3845// continue;
3728 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3846// }
3847 }
3848
3849 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3850 {
3851 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3852 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3729 { 3853 {
3730 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3854 part.Shape.LightEntry = false;
3731 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3732 {
3733 part.Shape.LightEntry = false;
3734 }
3735 } 3855 }
3736 } 3856 }
3737 3857 }
3738 #region UpdateFlags to packet type conversion 3858
3739 3859 ++updatesThisCall;
3740 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3860
3741 3861 #region UpdateFlags to packet type conversion
3742 bool canUseCompressed = true; 3862
3743 bool canUseImproved = true; 3863 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3744 3864
3745 // Compressed object updates only make sense for LL primitives 3865 bool canUseCompressed = true;
3746 if (!(update.Entity is SceneObjectPart)) 3866 bool canUseImproved = true;
3867
3868 // Compressed object updates only make sense for LL primitives
3869 if (!(update.Entity is SceneObjectPart))
3870 {
3871 canUseCompressed = false;
3872 }
3873
3874 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3875 {
3876 canUseCompressed = false;
3877 canUseImproved = false;
3878 }
3879 else
3880 {
3881 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3882 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3883 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3884 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3747 { 3885 {
3748 canUseCompressed = false; 3886 canUseCompressed = false;
3749 } 3887 }
3750 3888
3751 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3889 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3890 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3891 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3892 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3893 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3894 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3895 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3896 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3897 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3898 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3899 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3900 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3901 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3902 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3752 { 3903 {
3753 canUseCompressed = false;
3754 canUseImproved = false; 3904 canUseImproved = false;
3755 } 3905 }
3756 else 3906 }
3757 {
3758 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3759 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3760 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3761 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3762 {
3763 canUseCompressed = false;
3764 }
3765
3766 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3773 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3774 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3775 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3776 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3777 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3778 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3779 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3780 {
3781 canUseImproved = false;
3782 }
3783 }
3784
3785 #endregion UpdateFlags to packet type conversion
3786
3787 #region Block Construction
3788
3789 // TODO: Remove this once we can build compressed updates
3790 canUseCompressed = false;
3791 3907
3792 if (!canUseImproved && !canUseCompressed) 3908 #endregion UpdateFlags to packet type conversion
3793 {
3794 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3795 3909
3796 if (update.Entity is ScenePresence) 3910 #region Block Construction
3797 {
3798 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3799 }
3800 else
3801 {
3802 SceneObjectPart part = (SceneObjectPart)update.Entity;
3803 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3804
3805 // If the part has become a private hud since the update was scheduled then we do not
3806 // want to send it to other avatars.
3807 if (part.ParentGroup.IsAttachment
3808 && part.ParentGroup.HasPrivateAttachmentPoint
3809 && part.ParentGroup.AttachedAvatar != AgentId)
3810 continue;
3811
3812 // If the part has since been deleted, then drop the update. In the case of attachments,
3813 // this is to avoid spurious updates to other viewers since post-processing of attachments
3814 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3815 // of the test above).
3816 //
3817 // Actual deletions (kills) happen in another method.
3818 if (part.ParentGroup.IsDeleted)
3819 continue;
3820 }
3821 3911
3822 objectUpdateBlocks.Value.Add(updateBlock); 3912 // TODO: Remove this once we can build compressed updates
3823 objectUpdates.Value.Add(update); 3913 canUseCompressed = false;
3824 }
3825 else if (!canUseImproved)
3826 {
3827 SceneObjectPart part = (SceneObjectPart)update.Entity;
3828 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3829 = CreateCompressedUpdateBlock(part, updateFlags);
3830
3831 // If the part has since been deleted, then drop the update. In the case of attachments,
3832 // this is to avoid spurious updates to other viewers since post-processing of attachments
3833 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3834 // of the test above).
3835 //
3836 // Actual deletions (kills) happen in another method.
3837 if (part.ParentGroup.IsDeleted)
3838 continue;
3839 3914
3840 compressedUpdateBlocks.Value.Add(compressedBlock); 3915 if (!canUseImproved && !canUseCompressed)
3841 compressedUpdates.Value.Add(update); 3916 {
3917 if (update.Entity is ScenePresence)
3918 {
3919 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3842 } 3920 }
3843 else 3921 else
3844 { 3922 {
3845 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3923 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3846 {
3847 // Self updates go into a special list
3848 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3849 terseAgentUpdates.Value.Add(update);
3850 }
3851 else
3852 {
3853 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3854 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3855
3856 // Everything else goes here
3857 if (update.Entity is SceneObjectPart)
3858 {
3859 SceneObjectPart part = (SceneObjectPart)update.Entity;
3860
3861 // If the part has become a private hud since the update was scheduled then we do not
3862 // want to send it to other avatars.
3863 if (part.ParentGroup.IsAttachment
3864 && part.ParentGroup.HasPrivateAttachmentPoint
3865 && part.ParentGroup.AttachedAvatar != AgentId)
3866 continue;
3867
3868 // If the part has since been deleted, then drop the update. In the case of attachments,
3869 // this is to avoid spurious updates to other viewers since post-processing of attachments
3870 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3871 // of the test above).
3872 //
3873 // Actual deletions (kills) happen in another method.
3874 if (part.ParentGroup.IsDeleted)
3875 continue;
3876 }
3877
3878 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3879 terseUpdates.Value.Add(update);
3880 }
3881 } 3924 }
3925 }
3926 else if (!canUseImproved)
3927 {
3928 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3929 }
3930 else
3931 {
3932 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3933 // Self updates go into a special list
3934 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3935 else
3936 // Everything else goes here
3937 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3938 }
3882 3939
3883 ++updatesThisCall; 3940 #endregion Block Construction
3941 }
3942
3943 #region Packet Sending
3884 3944
3885 #endregion Block Construction 3945 const float TIME_DILATION = 1.0f;
3886 } 3946 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3887 3947
3888 #region Packet Sending 3948 if (terseAgentUpdateBlocks.IsValueCreated)
3889 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3949 {
3950 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3890 3951
3891 if (terseAgentUpdateBlocks.IsValueCreated) 3952 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3892 { 3953 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3893 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3954 packet.RegionData.TimeDilation = timeDilation;
3955 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3894 3956
3895 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3957 for (int i = 0; i < blocks.Count; i++)
3896 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3958 packet.ObjectData[i] = blocks[i];
3897 packet.RegionData.TimeDilation = timeDilation;
3898 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3899 3959
3900 for (int i = 0; i < blocks.Count; i++) 3960 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3901 packet.ObjectData[i] = blocks[i]; 3961 }
3902 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3903 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3904 }
3905 3962
3906 if (objectUpdateBlocks.IsValueCreated) 3963 if (objectUpdateBlocks.IsValueCreated)
3907 { 3964 {
3908 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3965 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3909 3966
3910 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3967 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3911 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3968 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3912 packet.RegionData.TimeDilation = timeDilation; 3969 packet.RegionData.TimeDilation = timeDilation;
3913 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3970 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3914 3971
3915 for (int i = 0; i < blocks.Count; i++) 3972 for (int i = 0; i < blocks.Count; i++)
3916 packet.ObjectData[i] = blocks[i]; 3973 packet.ObjectData[i] = blocks[i];
3917 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 3974
3918 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 3975 OutPacket(packet, ThrottleOutPacketType.Task, true);
3919 } 3976 }
3920 3977
3921 if (compressedUpdateBlocks.IsValueCreated) 3978 if (compressedUpdateBlocks.IsValueCreated)
3922 { 3979 {
3923 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3980 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3924 3981
3925 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 3982 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3926 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3983 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3927 packet.RegionData.TimeDilation = timeDilation; 3984 packet.RegionData.TimeDilation = timeDilation;
3928 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 3985 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3929
3930 for (int i = 0; i < blocks.Count; i++)
3931 packet.ObjectData[i] = blocks[i];
3932 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3933 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3934 }
3935 3986
3936 if (terseUpdateBlocks.IsValueCreated) 3987 for (int i = 0; i < blocks.Count; i++)
3937 { 3988 packet.ObjectData[i] = blocks[i];
3938 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3989
3939 3990 OutPacket(packet, ThrottleOutPacketType.Task, true);
3940 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3991 }
3941 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3992
3942 packet.RegionData.TimeDilation = timeDilation; 3993 if (terseUpdateBlocks.IsValueCreated)
3943 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3994 {
3944 3995 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3945 for (int i = 0; i < blocks.Count; i++) 3996
3946 packet.ObjectData[i] = blocks[i]; 3997 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3947 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 3998 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3948 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 3999 packet.RegionData.TimeDilation = timeDilation;
3949 } 4000 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4001
4002 for (int i = 0; i < blocks.Count; i++)
4003 packet.ObjectData[i] = blocks[i];
4004
4005 OutPacket(packet, ThrottleOutPacketType.Task, true);
3950 } 4006 }
3951 4007
3952 #endregion Packet Sending 4008 #endregion Packet Sending
@@ -4239,11 +4295,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4239 4295
4240 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4296 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4241 // of the object rather than the properties when the packet was created 4297 // of the object rather than the properties when the packet was created
4242 OutPacket(packet, ThrottleOutPacketType.Task, true, 4298 // HACK : Remove intelligent resending until it's fixed in core
4243 delegate(OutgoingPacket oPacket) 4299 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4244 { 4300 // delegate(OutgoingPacket oPacket)
4245 ResendPropertyUpdates(updates, oPacket); 4301 // {
4246 }); 4302 // ResendPropertyUpdates(updates, oPacket);
4303 // });
4304 OutPacket(packet, ThrottleOutPacketType.Task, true);
4247 4305
4248 // pbcnt += blocks.Count; 4306 // pbcnt += blocks.Count;
4249 // ppcnt++; 4307 // ppcnt++;
@@ -4269,11 +4327,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4269 // of the object rather than the properties when the packet was created 4327 // of the object rather than the properties when the packet was created
4270 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4328 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4271 updates.Add(familyUpdates.Value[i]); 4329 updates.Add(familyUpdates.Value[i]);
4272 OutPacket(packet, ThrottleOutPacketType.Task, true, 4330 // HACK : Remove intelligent resending until it's fixed in core
4273 delegate(OutgoingPacket oPacket) 4331 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4274 { 4332 // delegate(OutgoingPacket oPacket)
4275 ResendPropertyUpdates(updates, oPacket); 4333 // {
4276 }); 4334 // ResendPropertyUpdates(updates, oPacket);
4335 // });
4336 OutPacket(packet, ThrottleOutPacketType.Task, true);
4277 4337
4278 // fpcnt++; 4338 // fpcnt++;
4279 // fbcnt++; 4339 // fbcnt++;
@@ -4422,37 +4482,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4422 if (bl[i].BannedUserID == UUID.Zero) 4482 if (bl[i].BannedUserID == UUID.Zero)
4423 continue; 4483 continue;
4424 BannedUsers.Add(bl[i].BannedUserID); 4484 BannedUsers.Add(bl[i].BannedUserID);
4425 }
4426 4485
4427 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4486 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4428 packet.AgentData.TransactionID = UUID.Random(); 4487 {
4429 packet.AgentData.AgentID = AgentId; 4488 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4430 packet.AgentData.SessionID = SessionId; 4489 packet.AgentData.TransactionID = UUID.Random();
4431 packet.MethodData.Invoice = invoice; 4490 packet.AgentData.AgentID = AgentId;
4432 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4491 packet.AgentData.SessionID = SessionId;
4492 packet.MethodData.Invoice = invoice;
4493 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4433 4494
4434 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4495 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4435 4496
4436 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4497 int j;
4437 { 4498 for (j = 0; j < (6 + BannedUsers.Count); j++)
4438 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4499 {
4439 } 4500 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4440 int j = 0; 4501 }
4502 j = 0;
4441 4503
4442 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4504 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4443 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4505 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4444 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4506 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4445 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4507 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4446 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4508 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4447 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4509 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4448 4510
4449 foreach (UUID banned in BannedUsers) 4511 foreach (UUID banned in BannedUsers)
4450 { 4512 {
4451 returnblock[j].Parameter = banned.GetBytes(); j++; 4513 returnblock[j].Parameter = banned.GetBytes(); j++;
4514 }
4515 packet.ParamList = returnblock;
4516 packet.Header.Reliable = true;
4517 OutPacket(packet, ThrottleOutPacketType.Task);
4518
4519 BannedUsers.Clear();
4520 }
4452 } 4521 }
4453 packet.ParamList = returnblock; 4522
4454 packet.Header.Reliable = false;
4455 OutPacket(packet, ThrottleOutPacketType.Task);
4456 } 4523 }
4457 4524
4458 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4525 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4638,7 +4705,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4638 4705
4639 if (landData.SimwideArea > 0) 4706 if (landData.SimwideArea > 0)
4640 { 4707 {
4641 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4708 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4709 // Never report more than sim total capacity
4710 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4711 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4642 updateMessage.SimWideMaxPrims = simulatorCapacity; 4712 updateMessage.SimWideMaxPrims = simulatorCapacity;
4643 } 4713 }
4644 else 4714 else
@@ -4767,14 +4837,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4767 4837
4768 if (notifyCount > 0) 4838 if (notifyCount > 0)
4769 { 4839 {
4770 if (notifyCount > 32) 4840// if (notifyCount > 32)
4771 { 4841// {
4772 m_log.InfoFormat( 4842// m_log.InfoFormat(
4773 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4843// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4774 + " - a developer might want to investigate whether this is a hard limit", 32); 4844// + " - a developer might want to investigate whether this is a hard limit", 32);
4775 4845//
4776 notifyCount = 32; 4846// notifyCount = 32;
4777 } 4847// }
4778 4848
4779 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4849 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4780 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4850 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4829,9 +4899,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4829 { 4899 {
4830 ScenePresence presence = (ScenePresence)entity; 4900 ScenePresence presence = (ScenePresence)entity;
4831 4901
4902 position = presence.OffsetPosition;
4903 rotation = presence.Rotation;
4904
4905 if (presence.ParentID != 0)
4906 {
4907 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4908 if (part != null && part != part.ParentGroup.RootPart)
4909 {
4910 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4911 rotation = part.RotationOffset * presence.Rotation;
4912 }
4913 }
4914
4832 attachPoint = 0; 4915 attachPoint = 0;
4833 collisionPlane = presence.CollisionPlane; 4916 collisionPlane = presence.CollisionPlane;
4834 position = presence.OffsetPosition;
4835 velocity = presence.Velocity; 4917 velocity = presence.Velocity;
4836 acceleration = Vector3.Zero; 4918 acceleration = Vector3.Zero;
4837 4919
@@ -4841,7 +4923,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4841// acceleration = new Vector3(1, 0, 0); 4923// acceleration = new Vector3(1, 0, 0);
4842 4924
4843 angularVelocity = Vector3.Zero; 4925 angularVelocity = Vector3.Zero;
4844 rotation = presence.Rotation;
4845 4926
4846 if (sendTexture) 4927 if (sendTexture)
4847 textureEntry = presence.Appearance.Texture.GetBytes(); 4928 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4946,13 +5027,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4946 5027
4947 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5028 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4948 { 5029 {
5030 Vector3 offsetPosition = data.OffsetPosition;
5031 Quaternion rotation = data.Rotation;
5032 uint parentID = data.ParentID;
5033
5034 if (parentID != 0)
5035 {
5036 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5037 if (part != null && part != part.ParentGroup.RootPart)
5038 {
5039 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5040 rotation = part.RotationOffset * data.Rotation;
5041 parentID = part.ParentGroup.RootPart.LocalId;
5042 }
5043 }
5044
4949 byte[] objectData = new byte[76]; 5045 byte[] objectData = new byte[76];
4950 5046
4951 data.CollisionPlane.ToBytes(objectData, 0); 5047 data.CollisionPlane.ToBytes(objectData, 0);
4952 data.OffsetPosition.ToBytes(objectData, 16); 5048 offsetPosition.ToBytes(objectData, 16);
4953// data.Velocity.ToBytes(objectData, 28); 5049// data.Velocity.ToBytes(objectData, 28);
4954// data.Acceleration.ToBytes(objectData, 40); 5050// data.Acceleration.ToBytes(objectData, 40);
4955 data.Rotation.ToBytes(objectData, 52); 5051 rotation.ToBytes(objectData, 52);
4956 //data.AngularVelocity.ToBytes(objectData, 64); 5052 //data.AngularVelocity.ToBytes(objectData, 64);
4957 5053
4958 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5054 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4966,7 +5062,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4966 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5062 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4967 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5063 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4968 update.ObjectData = objectData; 5064 update.ObjectData = objectData;
4969 update.ParentID = data.ParentID; 5065 update.ParentID = parentID;
4970 update.PathCurve = 16; 5066 update.PathCurve = 16;
4971 update.PathScaleX = 100; 5067 update.PathScaleX = 100;
4972 update.PathScaleY = 100; 5068 update.PathScaleY = 100;
@@ -4984,10 +5080,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4984 update.TextureEntry = Utils.EmptyBytes; 5080 update.TextureEntry = Utils.EmptyBytes;
4985// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5081// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
4986 5082
5083/* all this flags seem related to prims and not avatars. This allow for wrong viewer side move of a avatar in prim edition mode (anv mantis 854)
4987 update.UpdateFlags = (uint)( 5084 update.UpdateFlags = (uint)(
4988 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5085 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
4989 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5086 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
4990 PrimFlags.ObjectOwnerModify); 5087 PrimFlags.ObjectOwnerModify);
5088*/
5089 update.UpdateFlags = 0;
4991 5090
4992 return update; 5091 return update;
4993 } 5092 }
@@ -5307,6 +5406,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5307 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5406 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5308 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5407 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5309 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5408 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5409 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5310 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5410 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5311 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5411 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5312 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5412 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5373,6 +5473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5373 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5473 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5374 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5474 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5375 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5475 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5476 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5376 5477
5377 AddGenericPacketHandler("autopilot", HandleAutopilot); 5478 AddGenericPacketHandler("autopilot", HandleAutopilot);
5378 } 5479 }
@@ -5408,6 +5509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5408 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5509 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5409 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5510 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5410 (x.ControlFlags != lastarg.ControlFlags) || 5511 (x.ControlFlags != lastarg.ControlFlags) ||
5512 (x.ControlFlags != 0) ||
5411 (x.Far != lastarg.Far) || 5513 (x.Far != lastarg.Far) ||
5412 (x.Flags != lastarg.Flags) || 5514 (x.Flags != lastarg.Flags) ||
5413 (x.State != lastarg.State) || 5515 (x.State != lastarg.State) ||
@@ -5785,7 +5887,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5785 args.Channel = ch; 5887 args.Channel = ch;
5786 args.From = String.Empty; 5888 args.From = String.Empty;
5787 args.Message = Utils.BytesToString(msg); 5889 args.Message = Utils.BytesToString(msg);
5788 args.Type = ChatTypeEnum.Shout; 5890 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5789 args.Position = new Vector3(); 5891 args.Position = new Vector3();
5790 args.Scene = Scene; 5892 args.Scene = Scene;
5791 args.Sender = this; 5893 args.Sender = this;
@@ -6305,6 +6407,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6305 { 6407 {
6306 handlerCompleteMovementToRegion(sender, true); 6408 handlerCompleteMovementToRegion(sender, true);
6307 } 6409 }
6410 else
6411 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6412
6308 handlerCompleteMovementToRegion = null; 6413 handlerCompleteMovementToRegion = null;
6309 6414
6310 return true; 6415 return true;
@@ -6322,7 +6427,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6322 return true; 6427 return true;
6323 } 6428 }
6324 #endregion 6429 #endregion
6325 6430/*
6326 StartAnim handlerStartAnim = null; 6431 StartAnim handlerStartAnim = null;
6327 StopAnim handlerStopAnim = null; 6432 StopAnim handlerStopAnim = null;
6328 6433
@@ -6346,6 +6451,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6346 } 6451 }
6347 } 6452 }
6348 return true; 6453 return true;
6454*/
6455 ChangeAnim handlerChangeAnim = null;
6456
6457 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6458 {
6459 handlerChangeAnim = OnChangeAnim;
6460 if (handlerChangeAnim != null)
6461 {
6462 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6463 }
6464 }
6465
6466 handlerChangeAnim = OnChangeAnim;
6467 if (handlerChangeAnim != null)
6468 {
6469 handlerChangeAnim(UUID.Zero, false, true);
6470 }
6471
6472 return true;
6349 } 6473 }
6350 6474
6351 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6475 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6971,10 +7095,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6971 // 46,47,48 are special positions within the packet 7095 // 46,47,48 are special positions within the packet
6972 // This may change so perhaps we need a better way 7096 // This may change so perhaps we need a better way
6973 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7097 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6974 bool UsePhysics = (data[46] != 0) ? true : false; 7098 /*
6975 bool IsTemporary = (data[47] != 0) ? true : false; 7099 bool UsePhysics = (data[46] != 0) ? true : false;
6976 bool IsPhantom = (data[48] != 0) ? true : false; 7100 bool IsTemporary = (data[47] != 0) ? true : false;
6977 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7101 bool IsPhantom = (data[48] != 0) ? true : false;
7102 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7103 */
7104 bool UsePhysics = flags.AgentData.UsePhysics;
7105 bool IsPhantom = flags.AgentData.IsPhantom;
7106 bool IsTemporary = flags.AgentData.IsTemporary;
7107 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7108 ExtraPhysicsData physdata = new ExtraPhysicsData();
7109
7110 if (blocks == null || blocks.Length == 0)
7111 {
7112 physdata.PhysShapeType = PhysShapeType.invalid;
7113 }
7114 else
7115 {
7116 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7117 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7118 physdata.Bounce = phsblock.Restitution;
7119 physdata.Density = phsblock.Density;
7120 physdata.Friction = phsblock.Friction;
7121 physdata.GravitationModifier = phsblock.GravityMultiplier;
7122 }
7123
7124 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
6978 } 7125 }
6979 return true; 7126 return true;
6980 } 7127 }
@@ -9828,7 +9975,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9828 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9975 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9829 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9976 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9830 UpdateMuteListEntry.MuteData.MuteType, 9977 UpdateMuteListEntry.MuteData.MuteType,
9831 UpdateMuteListEntry.AgentData.AgentID); 9978 UpdateMuteListEntry.MuteData.MuteFlags);
9832 return true; 9979 return true;
9833 } 9980 }
9834 return false; 9981 return false;
@@ -9843,8 +9990,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9843 { 9990 {
9844 handlerRemoveMuteListEntry(this, 9991 handlerRemoveMuteListEntry(this,
9845 RemoveMuteListEntry.MuteData.MuteID, 9992 RemoveMuteListEntry.MuteData.MuteID,
9846 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9993 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9847 RemoveMuteListEntry.AgentData.AgentID);
9848 return true; 9994 return true;
9849 } 9995 }
9850 return false; 9996 return false;
@@ -9888,10 +10034,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9888 return false; 10034 return false;
9889 } 10035 }
9890 10036
10037 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10038 {
10039 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10040 (ChangeInventoryItemFlagsPacket)packet;
10041 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10042 if (handlerChangeInventoryItemFlags != null)
10043 {
10044 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10045 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10046 return true;
10047 }
10048 return false;
10049 }
10050
9891 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10051 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9892 { 10052 {
9893 return true; 10053 return true;
9894 } 10054 }
10055
10056 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10057 {
10058 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10059
10060 #region Packet Session and User Check
10061 if (m_checkPackets)
10062 {
10063 if (packet.AgentData.SessionID != SessionId ||
10064 packet.AgentData.AgentID != AgentId)
10065 return true;
10066 }
10067 #endregion
10068 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10069 List<InventoryItemBase> items = new List<InventoryItemBase>();
10070 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10071 {
10072 InventoryItemBase b = new InventoryItemBase();
10073 b.ID = n.OldItemID;
10074 b.Folder = n.OldFolderID;
10075 items.Add(b);
10076 }
10077
10078 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10079 if (handlerMoveItemsAndLeaveCopy != null)
10080 {
10081 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10082 }
10083
10084 return true;
10085 }
9895 10086
9896 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10087 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9897 { 10088 {
@@ -10318,6 +10509,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10318 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10509 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10319 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10510 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10320 10511
10512 Scene scene = (Scene)m_scene;
10513 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10514 {
10515 ScenePresence p;
10516 if (scene.TryGetScenePresence(sender.AgentId, out p))
10517 {
10518 if (p.GodLevel >= 200)
10519 {
10520 groupProfileReply.GroupData.OpenEnrollment = true;
10521 groupProfileReply.GroupData.MembershipFee = 0;
10522 }
10523 }
10524 }
10525
10321 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10526 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10322 } 10527 }
10323 return true; 10528 return true;
@@ -10891,11 +11096,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10891 11096
10892 StartLure handlerStartLure = OnStartLure; 11097 StartLure handlerStartLure = OnStartLure;
10893 if (handlerStartLure != null) 11098 if (handlerStartLure != null)
10894 handlerStartLure(startLureRequest.Info.LureType, 11099 {
10895 Utils.BytesToString( 11100 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10896 startLureRequest.Info.Message), 11101 {
10897 startLureRequest.TargetData[0].TargetID, 11102 handlerStartLure(startLureRequest.Info.LureType,
10898 this); 11103 Utils.BytesToString(
11104 startLureRequest.Info.Message),
11105 startLureRequest.TargetData[i].TargetID,
11106 this);
11107 }
11108 }
10899 return true; 11109 return true;
10900 } 11110 }
10901 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11111 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11009,10 +11219,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11009 } 11219 }
11010 #endregion 11220 #endregion
11011 11221
11012 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11222 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11013 if (handlerClassifiedGodDelete != null) 11223 if (handlerClassifiedGodDelete != null)
11014 handlerClassifiedGodDelete( 11224 handlerClassifiedGodDelete(
11015 classifiedGodDelete.Data.ClassifiedID, 11225 classifiedGodDelete.Data.ClassifiedID,
11226 classifiedGodDelete.Data.QueryID,
11016 this); 11227 this);
11017 return true; 11228 return true;
11018 } 11229 }
@@ -11378,209 +11589,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11378 } 11589 }
11379 else 11590 else
11380 { 11591 {
11381// m_log.DebugFormat( 11592 ClientChangeObject updatehandler = onClientChangeObject;
11382// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11383// i, block.Type, part.Name, part.LocalId);
11384 11593
11385// // Do this once since fetch parts creates a new array. 11594 if (updatehandler != null)
11386// SceneObjectPart[] parts = part.ParentGroup.Parts; 11595 {
11387// for (int j = 0; j < parts.Length; j++) 11596 ObjectChangeData udata = new ObjectChangeData();
11388// {
11389// part.StoreUndoState();
11390// parts[j].IgnoreUndoUpdate = true;
11391// }
11392 11597
11393 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11598 /*ubit from ll JIRA:
11599 * 0x01 position
11600 * 0x02 rotation
11601 * 0x04 scale
11602
11603 * 0x08 LINK_SET
11604 * 0x10 UNIFORM for scale
11605 */
11394 11606
11395 switch (block.Type) 11607 // translate to internal changes
11396 { 11608 // not all cases .. just the ones older code did
11397 case 1:
11398 Vector3 pos1 = new Vector3(block.Data, 0);
11399 11609
11400 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11610 switch (block.Type)
11401 if (handlerUpdatePrimSinglePosition != null) 11611 {
11402 { 11612 case 1: //change position sp
11403 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11613 udata.position = new Vector3(block.Data, 0);
11404 handlerUpdatePrimSinglePosition(localId, pos1, this);
11405 }
11406 break;
11407 11614
11408 case 2: 11615 udata.change = ObjectChangeType.primP;
11409 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11616 updatehandler(localId, udata, this);
11617 break;
11410 11618
11411 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11619 case 2: // rotation sp
11412 if (handlerUpdatePrimSingleRotation != null) 11620 udata.rotation = new Quaternion(block.Data, 0, true);
11413 {
11414 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11415 handlerUpdatePrimSingleRotation(localId, rot1, this);
11416 }
11417 break;
11418 11621
11419 case 3: 11622 udata.change = ObjectChangeType.primR;
11420 Vector3 rotPos = new Vector3(block.Data, 0); 11623 updatehandler(localId, udata, this);
11421 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11624 break;
11422 11625
11423 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11626 case 3: // position plus rotation
11424 if (handlerUpdatePrimSingleRotationPosition != null) 11627 udata.position = new Vector3(block.Data, 0);
11425 { 11628 udata.rotation = new Quaternion(block.Data, 12, true);
11426 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11427 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11428 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11429 }
11430 break;
11431 11629
11432 case 4: 11630 udata.change = ObjectChangeType.primPR;
11433 case 20: 11631 updatehandler(localId, udata, this);
11434 Vector3 scale4 = new Vector3(block.Data, 0); 11632 break;
11435 11633
11436 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11634 case 4: // scale sp
11437 if (handlerUpdatePrimScale != null) 11635 udata.scale = new Vector3(block.Data, 0);
11438 { 11636 udata.change = ObjectChangeType.primS;
11439 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11440 handlerUpdatePrimScale(localId, scale4, this);
11441 }
11442 break;
11443 11637
11444 case 5: 11638 updatehandler(localId, udata, this);
11445 Vector3 scale1 = new Vector3(block.Data, 12); 11639 break;
11446 Vector3 pos11 = new Vector3(block.Data, 0);
11447 11640
11448 handlerUpdatePrimScale = OnUpdatePrimScale; 11641 case 0x14: // uniform scale sp
11449 if (handlerUpdatePrimScale != null) 11642 udata.scale = new Vector3(block.Data, 0);
11450 {
11451 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11452 handlerUpdatePrimScale(localId, scale1, this);
11453 11643
11454 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11644 udata.change = ObjectChangeType.primUS;
11455 if (handlerUpdatePrimSinglePosition != null) 11645 updatehandler(localId, udata, this);
11456 { 11646 break;
11457 handlerUpdatePrimSinglePosition(localId, pos11, this);
11458 }
11459 }
11460 break;
11461 11647
11462 case 9: 11648 case 5: // scale and position sp
11463 Vector3 pos2 = new Vector3(block.Data, 0); 11649 udata.position = new Vector3(block.Data, 0);
11650 udata.scale = new Vector3(block.Data, 12);
11464 11651
11465 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11652 udata.change = ObjectChangeType.primPS;
11653 updatehandler(localId, udata, this);
11654 break;
11466 11655
11467 if (handlerUpdateVector != null) 11656 case 0x15: //uniform scale and position
11468 { 11657 udata.position = new Vector3(block.Data, 0);
11469 handlerUpdateVector(localId, pos2, this); 11658 udata.scale = new Vector3(block.Data, 12);
11470 }
11471 break;
11472 11659
11473 case 10: 11660 udata.change = ObjectChangeType.primPUS;
11474 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11661 updatehandler(localId, udata, this);
11662 break;
11475 11663
11476 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11664 // now group related (bit 4)
11477 if (handlerUpdatePrimRotation != null) 11665 case 9: //( 8 + 1 )group position
11478 { 11666 udata.position = new Vector3(block.Data, 0);
11479 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11480 handlerUpdatePrimRotation(localId, rot3, this);
11481 }
11482 break;
11483 11667
11484 case 11: 11668 udata.change = ObjectChangeType.groupP;
11485 Vector3 pos3 = new Vector3(block.Data, 0); 11669 updatehandler(localId, udata, this);
11486 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11670 break;
11487 11671
11488 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11672 case 0x0A: // (8 + 2) group rotation
11489 if (handlerUpdatePrimGroupRotation != null) 11673 udata.rotation = new Quaternion(block.Data, 0, true);
11490 {
11491 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11492 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11493 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11494 }
11495 break;
11496 case 12:
11497 case 28:
11498 Vector3 scale7 = new Vector3(block.Data, 0);
11499 11674
11500 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11675 udata.change = ObjectChangeType.groupR;
11501 if (handlerUpdatePrimGroupScale != null) 11676 updatehandler(localId, udata, this);
11502 { 11677 break;
11503 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11504 handlerUpdatePrimGroupScale(localId, scale7, this);
11505 }
11506 break;
11507 11678
11508 case 13: 11679 case 0x0B: //( 8 + 2 + 1) group rotation and position
11509 Vector3 scale2 = new Vector3(block.Data, 12); 11680 udata.position = new Vector3(block.Data, 0);
11510 Vector3 pos4 = new Vector3(block.Data, 0); 11681 udata.rotation = new Quaternion(block.Data, 12, true);
11511 11682
11512 handlerUpdatePrimScale = OnUpdatePrimScale; 11683 udata.change = ObjectChangeType.groupPR;
11513 if (handlerUpdatePrimScale != null) 11684 updatehandler(localId, udata, this);
11514 { 11685 break;
11515 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11516 handlerUpdatePrimScale(localId, scale2, this);
11517 11686
11518 // Change the position based on scale (for bug number 246) 11687 case 0x0C: // (8 + 4) group scale
11519 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11688 // only afects root prim and only sent by viewer editor object tab scaling
11520 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11689 // mouse edition only allows uniform scaling
11521 if (handlerUpdatePrimSinglePosition != null) 11690 // SL MAY CHANGE THIS in viewers
11522 {
11523 handlerUpdatePrimSinglePosition(localId, pos4, this);
11524 }
11525 }
11526 break;
11527 11691
11528 case 29: 11692 udata.scale = new Vector3(block.Data, 0);
11529 Vector3 scale5 = new Vector3(block.Data, 12);
11530 Vector3 pos5 = new Vector3(block.Data, 0);
11531 11693
11532 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11694 udata.change = ObjectChangeType.groupS;
11533 if (handlerUpdatePrimGroupScale != null) 11695 updatehandler(localId, udata, this);
11534 {
11535 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11536 part.StoreUndoState(true);
11537 part.IgnoreUndoUpdate = true;
11538 handlerUpdatePrimGroupScale(localId, scale5, this);
11539 handlerUpdateVector = OnUpdatePrimGroupPosition;
11540 11696
11541 if (handlerUpdateVector != null) 11697 break;
11542 {
11543 handlerUpdateVector(localId, pos5, this);
11544 }
11545 11698
11546 part.IgnoreUndoUpdate = false; 11699 case 0x0D: //(8 + 4 + 1) group scale and position
11547 } 11700 // exception as above
11548 11701
11549 break; 11702 udata.position = new Vector3(block.Data, 0);
11703 udata.scale = new Vector3(block.Data, 12);
11550 11704
11551 case 21: 11705 udata.change = ObjectChangeType.groupPS;
11552 Vector3 scale6 = new Vector3(block.Data, 12); 11706 updatehandler(localId, udata, this);
11553 Vector3 pos6 = new Vector3(block.Data, 0); 11707 break;
11554 11708
11555 handlerUpdatePrimScale = OnUpdatePrimScale; 11709 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11556 if (handlerUpdatePrimScale != null) 11710 udata.scale = new Vector3(block.Data, 0);
11557 {
11558 part.StoreUndoState(false);
11559 part.IgnoreUndoUpdate = true;
11560 11711
11561 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11712 udata.change = ObjectChangeType.groupUS;
11562 handlerUpdatePrimScale(localId, scale6, this); 11713 updatehandler(localId, udata, this);
11563 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11714 break;
11564 if (handlerUpdatePrimSinglePosition != null)
11565 {
11566 handlerUpdatePrimSinglePosition(localId, pos6, this);
11567 }
11568 11715
11569 part.IgnoreUndoUpdate = false; 11716 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11570 } 11717 udata.position = new Vector3(block.Data, 0);
11571 break; 11718 udata.scale = new Vector3(block.Data, 12);
11572 11719
11573 default: 11720 udata.change = ObjectChangeType.groupPUS;
11574 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11721 updatehandler(localId, udata, this);
11575 break; 11722 break;
11723
11724 default:
11725 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11726 break;
11727 }
11576 } 11728 }
11577 11729
11578// for (int j = 0; j < parts.Length; j++)
11579// parts[j].IgnoreUndoUpdate = false;
11580 } 11730 }
11581 } 11731 }
11582 } 11732 }
11583
11584 return true; 11733 return true;
11585 } 11734 }
11586 11735
@@ -12036,7 +12185,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12036// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12185// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12037// requestID, taskID, (SourceType)sourceType, Name); 12186// requestID, taskID, (SourceType)sourceType, Name);
12038 12187
12188
12189 //Note, the bool returned from the below function is useless since it is always false.
12039 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12190 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12191
12040 } 12192 }
12041 12193
12042 /// <summary> 12194 /// <summary>
@@ -12102,7 +12254,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12102 /// <returns></returns> 12254 /// <returns></returns>
12103 private static int CalculateNumPackets(byte[] data) 12255 private static int CalculateNumPackets(byte[] data)
12104 { 12256 {
12105 const uint m_maxPacketSize = 600; 12257// const uint m_maxPacketSize = 600;
12258 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12106 int numPackets = 1; 12259 int numPackets = 1;
12107 12260
12108 if (data == null) 12261 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 468d524..754d9d2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -779,14 +779,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
779 IClientAPI client; 779 IClientAPI client;
780 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView)) 780 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
781 { 781 {
782 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 782// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
783 return; 783 return;
784 } 784 }
785 785
786 udpClient = ((LLClientView)client).UDPClient; 786 udpClient = ((LLClientView)client).UDPClient;
787 787
788 if (!udpClient.IsConnected) 788 if (!udpClient.IsConnected)
789 {
790// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
789 return; 791 return;
792 }
790 793
791 #endregion Packet to Client Mapping 794 #endregion Packet to Client Mapping
792 795
@@ -1138,7 +1141,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1138 if (!client.SceneAgent.IsChildAgent) 1141 if (!client.SceneAgent.IsChildAgent)
1139 client.Kick("Simulator logged you out due to connection timeout"); 1142 client.Kick("Simulator logged you out due to connection timeout");
1140 1143
1141 client.Close(); 1144 Util.FireAndForget(o => client.Close());
1142 } 1145 }
1143 1146
1144 private void IncomingPacketHandler() 1147 private void IncomingPacketHandler()
@@ -1149,6 +1152,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1149 1152
1150 while (base.IsRunning) 1153 while (base.IsRunning)
1151 { 1154 {
1155 m_scene.ThreadAlive(1);
1152 try 1156 try
1153 { 1157 {
1154 IncomingPacket incomingPacket = null; 1158 IncomingPacket incomingPacket = null;
@@ -1191,6 +1195,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1191 1195
1192 while (base.IsRunning) 1196 while (base.IsRunning)
1193 { 1197 {
1198 m_scene.ThreadAlive(2);
1194 try 1199 try
1195 { 1200 {
1196 m_packetSent = false; 1201 m_packetSent = false;
@@ -1460,4 +1465,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1460 } 1465 }
1461 } 1466 }
1462 } 1467 }
1463} \ No newline at end of file 1468}
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,