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 73cdec3..e6289bd 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;
@@ -382,6 +390,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
382 get { return m_startpos; } 390 get { return m_startpos; }
383 set { m_startpos = value; } 391 set { m_startpos = value; }
384 } 392 }
393 public bool DeliverPackets
394 {
395 get { return m_deliverPackets; }
396 set {
397 m_deliverPackets = value;
398 m_udpClient.m_deliverPackets = value;
399 }
400 }
385 public UUID AgentId { get { return m_agentId; } } 401 public UUID AgentId { get { return m_agentId; } }
386 public ISceneAgent SceneAgent { get; set; } 402 public ISceneAgent SceneAgent { get; set; }
387 public UUID ActiveGroupId { get { return m_activeGroupID; } } 403 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -454,7 +470,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
454 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 470 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
455 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 471 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
456 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 472 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
457 m_killRecord = new HashSet<uint>(); 473// m_killRecord = new HashSet<uint>();
458// m_attachmentsSent = new HashSet<uint>(); 474// m_attachmentsSent = new HashSet<uint>();
459 475
460 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 476 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -482,17 +498,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
482 498
483 #region Client Methods 499 #region Client Methods
484 500
501
485 /// <summary> 502 /// <summary>
486 /// Shut down the client view 503 /// Shut down the client view
487 /// </summary> 504 /// </summary>
488 public void Close() 505 public void Close()
489 { 506 {
507 Close(true);
508 }
509
510 /// <summary>
511 /// Shut down the client view
512 /// </summary>
513 public void Close(bool sendStop)
514 {
490 IsActive = false; 515 IsActive = false;
491 516
492 m_log.DebugFormat( 517 m_log.DebugFormat(
493 "[CLIENT]: Close has been called for {0} attached to scene {1}", 518 "[CLIENT]: Close has been called for {0} attached to scene {1}",
494 Name, m_scene.RegionInfo.RegionName); 519 Name, m_scene.RegionInfo.RegionName);
495 520
521 if (sendStop)
522 {
523 // Send the STOP packet
524 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
525 OutPacket(disable, ThrottleOutPacketType.Unknown);
526 }
527
528 IsActive = false;
529
496 // Shutdown the image manager 530 // Shutdown the image manager
497 ImageManager.Close(); 531 ImageManager.Close();
498 532
@@ -789,7 +823,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
789 reply.ChatData.OwnerID = fromAgentID; 823 reply.ChatData.OwnerID = fromAgentID;
790 reply.ChatData.SourceID = fromAgentID; 824 reply.ChatData.SourceID = fromAgentID;
791 825
792 OutPacket(reply, ThrottleOutPacketType.Task); 826 OutPacket(reply, ThrottleOutPacketType.Unknown);
793 } 827 }
794 828
795 /// <summary> 829 /// <summary>
@@ -1075,6 +1109,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1075 public virtual void SendLayerData(float[] map) 1109 public virtual void SendLayerData(float[] map)
1076 { 1110 {
1077 Util.FireAndForget(DoSendLayerData, map); 1111 Util.FireAndForget(DoSendLayerData, map);
1112
1113 // Send it sync, and async. It's not that much data
1114 // and it improves user experience just so much!
1115 DoSendLayerData(map);
1078 } 1116 }
1079 1117
1080 /// <summary> 1118 /// <summary>
@@ -1087,16 +1125,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1087 1125
1088 try 1126 try
1089 { 1127 {
1090 //for (int y = 0; y < 16; y++) 1128 for (int y = 0; y < 16; y++)
1091 //{ 1129 {
1092 // for (int x = 0; x < 16; x++) 1130 for (int x = 0; x < 16; x+=4)
1093 // { 1131 {
1094 // SendLayerData(x, y, map); 1132 SendLayerPacket(x, y, map);
1095 // } 1133 }
1096 //} 1134 }
1097
1098 // Send LayerData in a spiral pattern. Fun!
1099 SendLayerTopRight(map, 0, 0, 15, 15);
1100 } 1135 }
1101 catch (Exception e) 1136 catch (Exception e)
1102 { 1137 {
@@ -1104,51 +1139,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1104 } 1139 }
1105 } 1140 }
1106 1141
1107 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1108 {
1109 // Row
1110 for (int i = x1; i <= x2; i++)
1111 SendLayerData(i, y1, map);
1112
1113 // Column
1114 for (int j = y1 + 1; j <= y2; j++)
1115 SendLayerData(x2, j, map);
1116
1117 if (x2 - x1 > 0)
1118 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1119 }
1120
1121 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1122 {
1123 // Row in reverse
1124 for (int i = x2; i >= x1; i--)
1125 SendLayerData(i, y2, map);
1126
1127 // Column in reverse
1128 for (int j = y2 - 1; j >= y1; j--)
1129 SendLayerData(x1, j, map);
1130
1131 if (x2 - x1 > 0)
1132 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1133 }
1134
1135 /// <summary> 1142 /// <summary>
1136 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1143 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1137 /// </summary> 1144 /// </summary>
1138 /// <param name="map">heightmap</param> 1145 /// <param name="map">heightmap</param>
1139 /// <param name="px">X coordinate for patches 0..12</param> 1146 /// <param name="px">X coordinate for patches 0..12</param>
1140 /// <param name="py">Y coordinate for patches 0..15</param> 1147 /// <param name="py">Y coordinate for patches 0..15</param>
1141 // private void SendLayerPacket(float[] map, int y, int x) 1148 private void SendLayerPacket(int x, int y, float[] map)
1142 // { 1149 {
1143 // int[] patches = new int[4]; 1150 int[] patches = new int[4];
1144 // patches[0] = x + 0 + y * 16; 1151 patches[0] = x + 0 + y * 16;
1145 // patches[1] = x + 1 + y * 16; 1152 patches[1] = x + 1 + y * 16;
1146 // patches[2] = x + 2 + y * 16; 1153 patches[2] = x + 2 + y * 16;
1147 // patches[3] = x + 3 + y * 16; 1154 patches[3] = x + 3 + y * 16;
1148 1155
1149 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1156 float[] heightmap = (map.Length == 65536) ?
1150 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1157 map :
1151 // } 1158 LLHeightFieldMoronize(map);
1159
1160 try
1161 {
1162 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1163 OutPacket(layerpack, ThrottleOutPacketType.Land);
1164 }
1165 catch
1166 {
1167 for (int px = x ; px < x + 4 ; px++)
1168 SendLayerData(px, y, map);
1169 }
1170 }
1152 1171
1153 /// <summary> 1172 /// <summary>
1154 /// Sends a specified patch to a client 1173 /// Sends a specified patch to a client
@@ -1168,7 +1187,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1168 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1187 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1169 layerpack.Header.Reliable = true; 1188 layerpack.Header.Reliable = true;
1170 1189
1171 OutPacket(layerpack, ThrottleOutPacketType.Land); 1190 OutPacket(layerpack, ThrottleOutPacketType.Task);
1172 } 1191 }
1173 catch (Exception e) 1192 catch (Exception e)
1174 { 1193 {
@@ -1531,7 +1550,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1531 1550
1532 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1551 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1533 { 1552 {
1534// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1553// foreach (uint id in localIDs)
1554// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1535 1555
1536 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1556 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1537 // TODO: don't create new blocks if recycling an old packet 1557 // TODO: don't create new blocks if recycling an old packet
@@ -1553,17 +1573,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1553 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1573 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1554 // condition where a kill can be processed before an out-of-date update for the same object. 1574 // condition where a kill can be processed before an out-of-date update for the same object.
1555 // ProcessEntityUpdates() also takes the m_killRecord lock. 1575 // ProcessEntityUpdates() also takes the m_killRecord lock.
1556 lock (m_killRecord) 1576// lock (m_killRecord)
1557 { 1577// {
1558 foreach (uint localID in localIDs) 1578// foreach (uint localID in localIDs)
1559 m_killRecord.Add(localID); 1579// m_killRecord.Add(localID);
1560 1580
1561 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1581 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1562 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1582 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1563 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1583 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1564 // scene objects in a viewer until that viewer is relogged in. 1584 // scene objects in a viewer until that viewer is relogged in.
1565 OutPacket(kill, ThrottleOutPacketType.Task); 1585 OutPacket(kill, ThrottleOutPacketType.Task);
1566 } 1586// }
1567 } 1587 }
1568 } 1588 }
1569 1589
@@ -2293,6 +2313,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2293 OutPacket(sound, ThrottleOutPacketType.Task); 2313 OutPacket(sound, ThrottleOutPacketType.Task);
2294 } 2314 }
2295 2315
2316 public void SendTransferAbort(TransferRequestPacket transferRequest)
2317 {
2318 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2319 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2320 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2321 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2322 OutPacket(abort, ThrottleOutPacketType.Task);
2323 }
2324
2296 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2325 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2297 { 2326 {
2298 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2327 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2585,6 +2614,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2585 } 2614 }
2586 } 2615 }
2587 2616
2617 public void SendPartPhysicsProprieties(ISceneEntity entity)
2618 {
2619 SceneObjectPart part = (SceneObjectPart)entity;
2620 if (part != null && AgentId != UUID.Zero)
2621 {
2622 try
2623 {
2624 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2625 if (eq != null)
2626 {
2627 uint localid = part.LocalId;
2628 byte physshapetype = part.PhysicsShapeType;
2629 float density = part.Density;
2630 float friction = part.Friction;
2631 float bounce = part.Bounciness;
2632 float gravmod = part.GravityModifier;
2633
2634 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2635 }
2636 }
2637 catch (Exception ex)
2638 {
2639 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2640 }
2641 part.UpdatePhysRequired = false;
2642 }
2643 }
2644
2645
2588 2646
2589 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2647 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2590 { 2648 {
@@ -2682,7 +2740,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2682 else 2740 else
2683 { 2741 {
2684 int processedLength = 0; 2742 int processedLength = 0;
2685 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2743// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2744
2745 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2686 int packetNumber = 0; 2746 int packetNumber = 0;
2687 2747
2688 while (processedLength < req.AssetInf.Data.Length) 2748 while (processedLength < req.AssetInf.Data.Length)
@@ -2753,7 +2813,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2753 reply.Data.ParcelID = parcelID; 2813 reply.Data.ParcelID = parcelID;
2754 reply.Data.OwnerID = land.OwnerID; 2814 reply.Data.OwnerID = land.OwnerID;
2755 reply.Data.Name = Utils.StringToBytes(land.Name); 2815 reply.Data.Name = Utils.StringToBytes(land.Name);
2756 reply.Data.Desc = Utils.StringToBytes(land.Description); 2816 if (land != null && land.Description != null && land.Description != String.Empty)
2817 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2818 else
2819 reply.Data.Desc = new Byte[0];
2757 reply.Data.ActualArea = land.Area; 2820 reply.Data.ActualArea = land.Area;
2758 reply.Data.BillableArea = land.Area; // TODO: what is this? 2821 reply.Data.BillableArea = land.Area; // TODO: what is this?
2759 2822
@@ -3488,7 +3551,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3488 3551
3489 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3552 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3490 // TODO: don't create new blocks if recycling an old packet 3553 // TODO: don't create new blocks if recycling an old packet
3491 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3554 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3492 avp.ObjectData.TextureEntry = textureEntry; 3555 avp.ObjectData.TextureEntry = textureEntry;
3493 3556
3494 AvatarAppearancePacket.VisualParamBlock avblock = null; 3557 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3616,7 +3679,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3616 /// </summary> 3679 /// </summary>
3617 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3680 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3618 { 3681 {
3619 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3682 if (entity is SceneObjectPart)
3683 {
3684 SceneObjectPart e = (SceneObjectPart)entity;
3685 SceneObjectGroup g = e.ParentGroup;
3686 if (g.RootPart.Shape.State > 30) // HUD
3687 if (g.OwnerID != AgentId)
3688 return; // Don't send updates for other people's HUDs
3689 }
3690
3620 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3691 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3621 3692
3622 lock (m_entityUpdates.SyncRoot) 3693 lock (m_entityUpdates.SyncRoot)
@@ -3683,27 +3754,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3683 3754
3684 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3755 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3685 // condition where a kill can be processed before an out-of-date update for the same object. 3756 // condition where a kill can be processed before an out-of-date update for the same object.
3686 lock (m_killRecord) 3757 float avgTimeDilation = 1.0f;
3758 IEntityUpdate iupdate;
3759 Int32 timeinqueue; // this is just debugging code & can be dropped later
3760
3761 while (updatesThisCall < maxUpdates)
3687 { 3762 {
3688 float avgTimeDilation = 1.0f; 3763 lock (m_entityUpdates.SyncRoot)
3689 IEntityUpdate iupdate; 3764 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3690 Int32 timeinqueue; // this is just debugging code & can be dropped later 3765 break;
3766
3767 EntityUpdate update = (EntityUpdate)iupdate;
3768
3769 avgTimeDilation += update.TimeDilation;
3770 avgTimeDilation *= 0.5f;
3691 3771
3692 while (updatesThisCall < maxUpdates) 3772 if (update.Entity is SceneObjectPart)
3693 { 3773 {
3694 lock (m_entityUpdates.SyncRoot) 3774 SceneObjectPart part = (SceneObjectPart)update.Entity;
3695 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3696 break;
3697 3775
3698 EntityUpdate update = (EntityUpdate)iupdate; 3776 if (part.ParentGroup.IsDeleted)
3699 3777 continue;
3700 avgTimeDilation += update.TimeDilation;
3701 avgTimeDilation *= 0.5f;
3702 3778
3703 if (update.Entity is SceneObjectPart) 3779 if (part.ParentGroup.IsAttachment)
3780 { // Someone else's HUD, why are we getting these?
3781 if (part.ParentGroup.OwnerID != AgentId &&
3782 part.ParentGroup.RootPart.Shape.State >= 30)
3783 continue;
3784 ScenePresence sp;
3785 // Owner is not in the sim, don't update it to
3786 // anyone
3787 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3788 continue;
3789
3790 List<SceneObjectGroup> atts = sp.GetAttachments();
3791 bool found = false;
3792 foreach (SceneObjectGroup att in atts)
3793 {
3794 if (att == part.ParentGroup)
3795 {
3796 found = true;
3797 break;
3798 }
3799 }
3800
3801 // It's an attachment of a valid avatar, but
3802 // doesn't seem to be attached, skip
3803 if (!found)
3804 continue;
3805
3806 // On vehicle crossing, the attachments are received
3807 // while the avatar is still a child. Don't send
3808 // updates here because the LocalId has not yet
3809 // been updated and the viewer will derender the
3810 // attachments until the avatar becomes root.
3811 if (sp.IsChildAgent)
3812 continue;
3813
3814 // If the object is an attachment we don't want it to be in the kill
3815 // record. Else attaching from inworld and subsequently dropping
3816 // it will no longer work.
3817// lock (m_killRecord)
3818// {
3819// m_killRecord.Remove(part.LocalId);
3820// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3821// }
3822 }
3823 else
3704 { 3824 {
3705 SceneObjectPart part = (SceneObjectPart)update.Entity;
3706
3707 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3825 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3708 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3826 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3709 // safety measure. 3827 // safety measure.
@@ -3714,236 +3832,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3714 // 3832 //
3715 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3833 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3716 // after the root prim has been deleted. 3834 // after the root prim has been deleted.
3717 if (m_killRecord.Contains(part.LocalId)) 3835 //
3718 { 3836 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3719 // m_log.WarnFormat( 3837// lock (m_killRecord)
3720 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3838// {
3721 // part.LocalId, Name); 3839// if (m_killRecord.Contains(part.LocalId))
3722 continue; 3840// continue;
3723 } 3841// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3724 3842// continue;
3725 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3843// }
3844 }
3845
3846 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3847 {
3848 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3849 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3726 { 3850 {
3727 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3851 part.Shape.LightEntry = false;
3728 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3729 {
3730 part.Shape.LightEntry = false;
3731 }
3732 } 3852 }
3733 } 3853 }
3734 3854 }
3735 #region UpdateFlags to packet type conversion 3855
3736 3856 ++updatesThisCall;
3737 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3857
3738 3858 #region UpdateFlags to packet type conversion
3739 bool canUseCompressed = true; 3859
3740 bool canUseImproved = true; 3860 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3741 3861
3742 // Compressed object updates only make sense for LL primitives 3862 bool canUseCompressed = true;
3743 if (!(update.Entity is SceneObjectPart)) 3863 bool canUseImproved = true;
3864
3865 // Compressed object updates only make sense for LL primitives
3866 if (!(update.Entity is SceneObjectPart))
3867 {
3868 canUseCompressed = false;
3869 }
3870
3871 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3872 {
3873 canUseCompressed = false;
3874 canUseImproved = false;
3875 }
3876 else
3877 {
3878 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3879 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3880 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3881 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3744 { 3882 {
3745 canUseCompressed = false; 3883 canUseCompressed = false;
3746 } 3884 }
3747 3885
3748 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3886 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3887 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3888 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3889 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3890 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3891 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3892 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3893 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3894 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3895 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3896 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3897 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3898 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3899 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3749 { 3900 {
3750 canUseCompressed = false;
3751 canUseImproved = false; 3901 canUseImproved = false;
3752 } 3902 }
3753 else 3903 }
3754 {
3755 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3756 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3757 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3758 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3759 {
3760 canUseCompressed = false;
3761 }
3762
3763 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3764 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3765 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3766 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3767 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3768 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3769 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3770 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3771 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3772 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3773 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3774 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3775 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3776 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3777 {
3778 canUseImproved = false;
3779 }
3780 }
3781
3782 #endregion UpdateFlags to packet type conversion
3783
3784 #region Block Construction
3785
3786 // TODO: Remove this once we can build compressed updates
3787 canUseCompressed = false;
3788 3904
3789 if (!canUseImproved && !canUseCompressed) 3905 #endregion UpdateFlags to packet type conversion
3790 {
3791 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3792 3906
3793 if (update.Entity is ScenePresence) 3907 #region Block Construction
3794 {
3795 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3796 }
3797 else
3798 {
3799 SceneObjectPart part = (SceneObjectPart)update.Entity;
3800 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3801
3802 // If the part has become a private hud since the update was scheduled then we do not
3803 // want to send it to other avatars.
3804 if (part.ParentGroup.IsAttachment
3805 && part.ParentGroup.HasPrivateAttachmentPoint
3806 && part.ParentGroup.AttachedAvatar != AgentId)
3807 continue;
3808
3809 // If the part has since been deleted, then drop the update. In the case of attachments,
3810 // this is to avoid spurious updates to other viewers since post-processing of attachments
3811 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3812 // of the test above).
3813 //
3814 // Actual deletions (kills) happen in another method.
3815 if (part.ParentGroup.IsDeleted)
3816 continue;
3817 }
3818 3908
3819 objectUpdateBlocks.Value.Add(updateBlock); 3909 // TODO: Remove this once we can build compressed updates
3820 objectUpdates.Value.Add(update); 3910 canUseCompressed = false;
3821 }
3822 else if (!canUseImproved)
3823 {
3824 SceneObjectPart part = (SceneObjectPart)update.Entity;
3825 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3826 = CreateCompressedUpdateBlock(part, updateFlags);
3827
3828 // If the part has since been deleted, then drop the update. In the case of attachments,
3829 // this is to avoid spurious updates to other viewers since post-processing of attachments
3830 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3831 // of the test above).
3832 //
3833 // Actual deletions (kills) happen in another method.
3834 if (part.ParentGroup.IsDeleted)
3835 continue;
3836 3911
3837 compressedUpdateBlocks.Value.Add(compressedBlock); 3912 if (!canUseImproved && !canUseCompressed)
3838 compressedUpdates.Value.Add(update); 3913 {
3914 if (update.Entity is ScenePresence)
3915 {
3916 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3839 } 3917 }
3840 else 3918 else
3841 { 3919 {
3842 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3920 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3843 {
3844 // Self updates go into a special list
3845 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3846 terseAgentUpdates.Value.Add(update);
3847 }
3848 else
3849 {
3850 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3851 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3852
3853 // Everything else goes here
3854 if (update.Entity is SceneObjectPart)
3855 {
3856 SceneObjectPart part = (SceneObjectPart)update.Entity;
3857
3858 // If the part has become a private hud since the update was scheduled then we do not
3859 // want to send it to other avatars.
3860 if (part.ParentGroup.IsAttachment
3861 && part.ParentGroup.HasPrivateAttachmentPoint
3862 && part.ParentGroup.AttachedAvatar != AgentId)
3863 continue;
3864
3865 // If the part has since been deleted, then drop the update. In the case of attachments,
3866 // this is to avoid spurious updates to other viewers since post-processing of attachments
3867 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3868 // of the test above).
3869 //
3870 // Actual deletions (kills) happen in another method.
3871 if (part.ParentGroup.IsDeleted)
3872 continue;
3873 }
3874
3875 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3876 terseUpdates.Value.Add(update);
3877 }
3878 } 3921 }
3922 }
3923 else if (!canUseImproved)
3924 {
3925 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3926 }
3927 else
3928 {
3929 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3930 // Self updates go into a special list
3931 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3932 else
3933 // Everything else goes here
3934 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3935 }
3879 3936
3880 ++updatesThisCall; 3937 #endregion Block Construction
3938 }
3939
3940 #region Packet Sending
3881 3941
3882 #endregion Block Construction 3942 const float TIME_DILATION = 1.0f;
3883 } 3943 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3884 3944
3885 #region Packet Sending 3945 if (terseAgentUpdateBlocks.IsValueCreated)
3886 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3946 {
3947 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3887 3948
3888 if (terseAgentUpdateBlocks.IsValueCreated) 3949 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3889 { 3950 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3890 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3951 packet.RegionData.TimeDilation = timeDilation;
3952 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3891 3953
3892 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3954 for (int i = 0; i < blocks.Count; i++)
3893 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3955 packet.ObjectData[i] = blocks[i];
3894 packet.RegionData.TimeDilation = timeDilation;
3895 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3896 3956
3897 for (int i = 0; i < blocks.Count; i++) 3957 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3898 packet.ObjectData[i] = blocks[i]; 3958 }
3899 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3900 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3901 }
3902 3959
3903 if (objectUpdateBlocks.IsValueCreated) 3960 if (objectUpdateBlocks.IsValueCreated)
3904 { 3961 {
3905 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3962 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3906 3963
3907 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3964 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3908 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3965 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3909 packet.RegionData.TimeDilation = timeDilation; 3966 packet.RegionData.TimeDilation = timeDilation;
3910 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3967 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3911 3968
3912 for (int i = 0; i < blocks.Count; i++) 3969 for (int i = 0; i < blocks.Count; i++)
3913 packet.ObjectData[i] = blocks[i]; 3970 packet.ObjectData[i] = blocks[i];
3914 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 3971
3915 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 3972 OutPacket(packet, ThrottleOutPacketType.Task, true);
3916 } 3973 }
3917 3974
3918 if (compressedUpdateBlocks.IsValueCreated) 3975 if (compressedUpdateBlocks.IsValueCreated)
3919 { 3976 {
3920 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 3977 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3921 3978
3922 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 3979 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3923 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3980 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3924 packet.RegionData.TimeDilation = timeDilation; 3981 packet.RegionData.TimeDilation = timeDilation;
3925 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 3982 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3926
3927 for (int i = 0; i < blocks.Count; i++)
3928 packet.ObjectData[i] = blocks[i];
3929 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3930 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3931 }
3932 3983
3933 if (terseUpdateBlocks.IsValueCreated) 3984 for (int i = 0; i < blocks.Count; i++)
3934 { 3985 packet.ObjectData[i] = blocks[i];
3935 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3986
3936 3987 OutPacket(packet, ThrottleOutPacketType.Task, true);
3937 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3988 }
3938 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3989
3939 packet.RegionData.TimeDilation = timeDilation; 3990 if (terseUpdateBlocks.IsValueCreated)
3940 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3991 {
3941 3992 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3942 for (int i = 0; i < blocks.Count; i++) 3993
3943 packet.ObjectData[i] = blocks[i]; 3994 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3944 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 3995 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3945 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 3996 packet.RegionData.TimeDilation = timeDilation;
3946 } 3997 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3998
3999 for (int i = 0; i < blocks.Count; i++)
4000 packet.ObjectData[i] = blocks[i];
4001
4002 OutPacket(packet, ThrottleOutPacketType.Task, true);
3947 } 4003 }
3948 4004
3949 #endregion Packet Sending 4005 #endregion Packet Sending
@@ -4236,11 +4292,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4236 4292
4237 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4293 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4238 // of the object rather than the properties when the packet was created 4294 // of the object rather than the properties when the packet was created
4239 OutPacket(packet, ThrottleOutPacketType.Task, true, 4295 // HACK : Remove intelligent resending until it's fixed in core
4240 delegate(OutgoingPacket oPacket) 4296 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4241 { 4297 // delegate(OutgoingPacket oPacket)
4242 ResendPropertyUpdates(updates, oPacket); 4298 // {
4243 }); 4299 // ResendPropertyUpdates(updates, oPacket);
4300 // });
4301 OutPacket(packet, ThrottleOutPacketType.Task, true);
4244 4302
4245 // pbcnt += blocks.Count; 4303 // pbcnt += blocks.Count;
4246 // ppcnt++; 4304 // ppcnt++;
@@ -4266,11 +4324,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4266 // of the object rather than the properties when the packet was created 4324 // of the object rather than the properties when the packet was created
4267 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4325 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4268 updates.Add(familyUpdates.Value[i]); 4326 updates.Add(familyUpdates.Value[i]);
4269 OutPacket(packet, ThrottleOutPacketType.Task, true, 4327 // HACK : Remove intelligent resending until it's fixed in core
4270 delegate(OutgoingPacket oPacket) 4328 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4271 { 4329 // delegate(OutgoingPacket oPacket)
4272 ResendPropertyUpdates(updates, oPacket); 4330 // {
4273 }); 4331 // ResendPropertyUpdates(updates, oPacket);
4332 // });
4333 OutPacket(packet, ThrottleOutPacketType.Task, true);
4274 4334
4275 // fpcnt++; 4335 // fpcnt++;
4276 // fbcnt++; 4336 // fbcnt++;
@@ -4419,37 +4479,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4419 if (bl[i].BannedUserID == UUID.Zero) 4479 if (bl[i].BannedUserID == UUID.Zero)
4420 continue; 4480 continue;
4421 BannedUsers.Add(bl[i].BannedUserID); 4481 BannedUsers.Add(bl[i].BannedUserID);
4422 }
4423 4482
4424 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4483 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4425 packet.AgentData.TransactionID = UUID.Random(); 4484 {
4426 packet.AgentData.AgentID = AgentId; 4485 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4427 packet.AgentData.SessionID = SessionId; 4486 packet.AgentData.TransactionID = UUID.Random();
4428 packet.MethodData.Invoice = invoice; 4487 packet.AgentData.AgentID = AgentId;
4429 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4488 packet.AgentData.SessionID = SessionId;
4489 packet.MethodData.Invoice = invoice;
4490 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4430 4491
4431 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4492 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4432 4493
4433 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4494 int j;
4434 { 4495 for (j = 0; j < (6 + BannedUsers.Count); j++)
4435 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4496 {
4436 } 4497 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4437 int j = 0; 4498 }
4499 j = 0;
4438 4500
4439 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4501 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4440 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4502 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4441 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4503 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4442 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4504 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4443 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4505 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4444 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4506 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4445 4507
4446 foreach (UUID banned in BannedUsers) 4508 foreach (UUID banned in BannedUsers)
4447 { 4509 {
4448 returnblock[j].Parameter = banned.GetBytes(); j++; 4510 returnblock[j].Parameter = banned.GetBytes(); j++;
4511 }
4512 packet.ParamList = returnblock;
4513 packet.Header.Reliable = true;
4514 OutPacket(packet, ThrottleOutPacketType.Task);
4515
4516 BannedUsers.Clear();
4517 }
4449 } 4518 }
4450 packet.ParamList = returnblock; 4519
4451 packet.Header.Reliable = false;
4452 OutPacket(packet, ThrottleOutPacketType.Task);
4453 } 4520 }
4454 4521
4455 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4522 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4635,7 +4702,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4635 4702
4636 if (landData.SimwideArea > 0) 4703 if (landData.SimwideArea > 0)
4637 { 4704 {
4638 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4705 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4706 // Never report more than sim total capacity
4707 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4708 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4639 updateMessage.SimWideMaxPrims = simulatorCapacity; 4709 updateMessage.SimWideMaxPrims = simulatorCapacity;
4640 } 4710 }
4641 else 4711 else
@@ -4764,14 +4834,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4764 4834
4765 if (notifyCount > 0) 4835 if (notifyCount > 0)
4766 { 4836 {
4767 if (notifyCount > 32) 4837// if (notifyCount > 32)
4768 { 4838// {
4769 m_log.InfoFormat( 4839// m_log.InfoFormat(
4770 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4840// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4771 + " - a developer might want to investigate whether this is a hard limit", 32); 4841// + " - a developer might want to investigate whether this is a hard limit", 32);
4772 4842//
4773 notifyCount = 32; 4843// notifyCount = 32;
4774 } 4844// }
4775 4845
4776 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4846 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4777 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4847 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4826,9 +4896,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4826 { 4896 {
4827 ScenePresence presence = (ScenePresence)entity; 4897 ScenePresence presence = (ScenePresence)entity;
4828 4898
4899 position = presence.OffsetPosition;
4900 rotation = presence.Rotation;
4901
4902 if (presence.ParentID != 0)
4903 {
4904 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4905 if (part != null && part != part.ParentGroup.RootPart)
4906 {
4907 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4908 rotation = part.RotationOffset * presence.Rotation;
4909 }
4910 }
4911
4829 attachPoint = 0; 4912 attachPoint = 0;
4830 collisionPlane = presence.CollisionPlane; 4913 collisionPlane = presence.CollisionPlane;
4831 position = presence.OffsetPosition;
4832 velocity = presence.Velocity; 4914 velocity = presence.Velocity;
4833 acceleration = Vector3.Zero; 4915 acceleration = Vector3.Zero;
4834 4916
@@ -4838,7 +4920,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4838// acceleration = new Vector3(1, 0, 0); 4920// acceleration = new Vector3(1, 0, 0);
4839 4921
4840 angularVelocity = Vector3.Zero; 4922 angularVelocity = Vector3.Zero;
4841 rotation = presence.Rotation;
4842 4923
4843 if (sendTexture) 4924 if (sendTexture)
4844 textureEntry = presence.Appearance.Texture.GetBytes(); 4925 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4943,13 +5024,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4943 5024
4944 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5025 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4945 { 5026 {
5027 Vector3 offsetPosition = data.OffsetPosition;
5028 Quaternion rotation = data.Rotation;
5029 uint parentID = data.ParentID;
5030
5031 if (parentID != 0)
5032 {
5033 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5034 if (part != null && part != part.ParentGroup.RootPart)
5035 {
5036 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5037 rotation = part.RotationOffset * data.Rotation;
5038 parentID = part.ParentGroup.RootPart.LocalId;
5039 }
5040 }
5041
4946 byte[] objectData = new byte[76]; 5042 byte[] objectData = new byte[76];
4947 5043
4948 data.CollisionPlane.ToBytes(objectData, 0); 5044 data.CollisionPlane.ToBytes(objectData, 0);
4949 data.OffsetPosition.ToBytes(objectData, 16); 5045 offsetPosition.ToBytes(objectData, 16);
4950// data.Velocity.ToBytes(objectData, 28); 5046// data.Velocity.ToBytes(objectData, 28);
4951// data.Acceleration.ToBytes(objectData, 40); 5047// data.Acceleration.ToBytes(objectData, 40);
4952 data.Rotation.ToBytes(objectData, 52); 5048 rotation.ToBytes(objectData, 52);
4953 //data.AngularVelocity.ToBytes(objectData, 64); 5049 //data.AngularVelocity.ToBytes(objectData, 64);
4954 5050
4955 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5051 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4963,7 +5059,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4963 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5059 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4964 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5060 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4965 update.ObjectData = objectData; 5061 update.ObjectData = objectData;
4966 update.ParentID = data.ParentID; 5062 update.ParentID = parentID;
4967 update.PathCurve = 16; 5063 update.PathCurve = 16;
4968 update.PathScaleX = 100; 5064 update.PathScaleX = 100;
4969 update.PathScaleY = 100; 5065 update.PathScaleY = 100;
@@ -4981,10 +5077,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4981 update.TextureEntry = Utils.EmptyBytes; 5077 update.TextureEntry = Utils.EmptyBytes;
4982// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5078// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
4983 5079
5080/* 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)
4984 update.UpdateFlags = (uint)( 5081 update.UpdateFlags = (uint)(
4985 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5082 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
4986 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5083 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
4987 PrimFlags.ObjectOwnerModify); 5084 PrimFlags.ObjectOwnerModify);
5085*/
5086 update.UpdateFlags = 0;
4988 5087
4989 return update; 5088 return update;
4990 } 5089 }
@@ -5304,6 +5403,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5304 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5403 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5305 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5404 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5306 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5405 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5406 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5307 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5407 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5308 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5408 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5309 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5409 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5370,6 +5470,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5370 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5470 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5371 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5471 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5372 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5472 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5473 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5373 5474
5374 AddGenericPacketHandler("autopilot", HandleAutopilot); 5475 AddGenericPacketHandler("autopilot", HandleAutopilot);
5375 } 5476 }
@@ -5405,6 +5506,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5405 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5506 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5406 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5507 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5407 (x.ControlFlags != lastarg.ControlFlags) || 5508 (x.ControlFlags != lastarg.ControlFlags) ||
5509 (x.ControlFlags != 0) ||
5408 (x.Far != lastarg.Far) || 5510 (x.Far != lastarg.Far) ||
5409 (x.Flags != lastarg.Flags) || 5511 (x.Flags != lastarg.Flags) ||
5410 (x.State != lastarg.State) || 5512 (x.State != lastarg.State) ||
@@ -5782,7 +5884,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5782 args.Channel = ch; 5884 args.Channel = ch;
5783 args.From = String.Empty; 5885 args.From = String.Empty;
5784 args.Message = Utils.BytesToString(msg); 5886 args.Message = Utils.BytesToString(msg);
5785 args.Type = ChatTypeEnum.Shout; 5887 args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
5786 args.Position = new Vector3(); 5888 args.Position = new Vector3();
5787 args.Scene = Scene; 5889 args.Scene = Scene;
5788 args.Sender = this; 5890 args.Sender = this;
@@ -6302,6 +6404,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6302 { 6404 {
6303 handlerCompleteMovementToRegion(sender, true); 6405 handlerCompleteMovementToRegion(sender, true);
6304 } 6406 }
6407 else
6408 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6409
6305 handlerCompleteMovementToRegion = null; 6410 handlerCompleteMovementToRegion = null;
6306 6411
6307 return true; 6412 return true;
@@ -6319,7 +6424,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6319 return true; 6424 return true;
6320 } 6425 }
6321 #endregion 6426 #endregion
6322 6427/*
6323 StartAnim handlerStartAnim = null; 6428 StartAnim handlerStartAnim = null;
6324 StopAnim handlerStopAnim = null; 6429 StopAnim handlerStopAnim = null;
6325 6430
@@ -6343,6 +6448,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6343 } 6448 }
6344 } 6449 }
6345 return true; 6450 return true;
6451*/
6452 ChangeAnim handlerChangeAnim = null;
6453
6454 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6455 {
6456 handlerChangeAnim = OnChangeAnim;
6457 if (handlerChangeAnim != null)
6458 {
6459 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6460 }
6461 }
6462
6463 handlerChangeAnim = OnChangeAnim;
6464 if (handlerChangeAnim != null)
6465 {
6466 handlerChangeAnim(UUID.Zero, false, true);
6467 }
6468
6469 return true;
6346 } 6470 }
6347 6471
6348 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6472 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -6968,10 +7092,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6968 // 46,47,48 are special positions within the packet 7092 // 46,47,48 are special positions within the packet
6969 // This may change so perhaps we need a better way 7093 // This may change so perhaps we need a better way
6970 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7094 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
6971 bool UsePhysics = (data[46] != 0) ? true : false; 7095 /*
6972 bool IsTemporary = (data[47] != 0) ? true : false; 7096 bool UsePhysics = (data[46] != 0) ? true : false;
6973 bool IsPhantom = (data[48] != 0) ? true : false; 7097 bool IsTemporary = (data[47] != 0) ? true : false;
6974 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7098 bool IsPhantom = (data[48] != 0) ? true : false;
7099 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7100 */
7101 bool UsePhysics = flags.AgentData.UsePhysics;
7102 bool IsPhantom = flags.AgentData.IsPhantom;
7103 bool IsTemporary = flags.AgentData.IsTemporary;
7104 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7105 ExtraPhysicsData physdata = new ExtraPhysicsData();
7106
7107 if (blocks == null || blocks.Length == 0)
7108 {
7109 physdata.PhysShapeType = PhysShapeType.invalid;
7110 }
7111 else
7112 {
7113 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7114 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7115 physdata.Bounce = phsblock.Restitution;
7116 physdata.Density = phsblock.Density;
7117 physdata.Friction = phsblock.Friction;
7118 physdata.GravitationModifier = phsblock.GravityMultiplier;
7119 }
7120
7121 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
6975 } 7122 }
6976 return true; 7123 return true;
6977 } 7124 }
@@ -9825,7 +9972,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9825 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 9972 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9826 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 9973 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9827 UpdateMuteListEntry.MuteData.MuteType, 9974 UpdateMuteListEntry.MuteData.MuteType,
9828 UpdateMuteListEntry.AgentData.AgentID); 9975 UpdateMuteListEntry.MuteData.MuteFlags);
9829 return true; 9976 return true;
9830 } 9977 }
9831 return false; 9978 return false;
@@ -9840,8 +9987,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9840 { 9987 {
9841 handlerRemoveMuteListEntry(this, 9988 handlerRemoveMuteListEntry(this,
9842 RemoveMuteListEntry.MuteData.MuteID, 9989 RemoveMuteListEntry.MuteData.MuteID,
9843 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 9990 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9844 RemoveMuteListEntry.AgentData.AgentID);
9845 return true; 9991 return true;
9846 } 9992 }
9847 return false; 9993 return false;
@@ -9885,10 +10031,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9885 return false; 10031 return false;
9886 } 10032 }
9887 10033
10034 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10035 {
10036 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10037 (ChangeInventoryItemFlagsPacket)packet;
10038 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10039 if (handlerChangeInventoryItemFlags != null)
10040 {
10041 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10042 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10043 return true;
10044 }
10045 return false;
10046 }
10047
9888 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10048 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9889 { 10049 {
9890 return true; 10050 return true;
9891 } 10051 }
10052
10053 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10054 {
10055 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10056
10057 #region Packet Session and User Check
10058 if (m_checkPackets)
10059 {
10060 if (packet.AgentData.SessionID != SessionId ||
10061 packet.AgentData.AgentID != AgentId)
10062 return true;
10063 }
10064 #endregion
10065 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10066 List<InventoryItemBase> items = new List<InventoryItemBase>();
10067 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10068 {
10069 InventoryItemBase b = new InventoryItemBase();
10070 b.ID = n.OldItemID;
10071 b.Folder = n.OldFolderID;
10072 items.Add(b);
10073 }
10074
10075 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10076 if (handlerMoveItemsAndLeaveCopy != null)
10077 {
10078 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10079 }
10080
10081 return true;
10082 }
9892 10083
9893 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10084 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9894 { 10085 {
@@ -10315,6 +10506,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10315 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10506 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10316 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10507 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10317 10508
10509 Scene scene = (Scene)m_scene;
10510 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10511 {
10512 ScenePresence p;
10513 if (scene.TryGetScenePresence(sender.AgentId, out p))
10514 {
10515 if (p.GodLevel >= 200)
10516 {
10517 groupProfileReply.GroupData.OpenEnrollment = true;
10518 groupProfileReply.GroupData.MembershipFee = 0;
10519 }
10520 }
10521 }
10522
10318 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10523 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10319 } 10524 }
10320 return true; 10525 return true;
@@ -10888,11 +11093,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10888 11093
10889 StartLure handlerStartLure = OnStartLure; 11094 StartLure handlerStartLure = OnStartLure;
10890 if (handlerStartLure != null) 11095 if (handlerStartLure != null)
10891 handlerStartLure(startLureRequest.Info.LureType, 11096 {
10892 Utils.BytesToString( 11097 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10893 startLureRequest.Info.Message), 11098 {
10894 startLureRequest.TargetData[0].TargetID, 11099 handlerStartLure(startLureRequest.Info.LureType,
10895 this); 11100 Utils.BytesToString(
11101 startLureRequest.Info.Message),
11102 startLureRequest.TargetData[i].TargetID,
11103 this);
11104 }
11105 }
10896 return true; 11106 return true;
10897 } 11107 }
10898 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11108 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11006,10 +11216,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11006 } 11216 }
11007 #endregion 11217 #endregion
11008 11218
11009 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11219 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11010 if (handlerClassifiedGodDelete != null) 11220 if (handlerClassifiedGodDelete != null)
11011 handlerClassifiedGodDelete( 11221 handlerClassifiedGodDelete(
11012 classifiedGodDelete.Data.ClassifiedID, 11222 classifiedGodDelete.Data.ClassifiedID,
11223 classifiedGodDelete.Data.QueryID,
11013 this); 11224 this);
11014 return true; 11225 return true;
11015 } 11226 }
@@ -11375,209 +11586,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11375 } 11586 }
11376 else 11587 else
11377 { 11588 {
11378// m_log.DebugFormat( 11589 ClientChangeObject updatehandler = onClientChangeObject;
11379// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11380// i, block.Type, part.Name, part.LocalId);
11381 11590
11382// // Do this once since fetch parts creates a new array. 11591 if (updatehandler != null)
11383// SceneObjectPart[] parts = part.ParentGroup.Parts; 11592 {
11384// for (int j = 0; j < parts.Length; j++) 11593 ObjectChangeData udata = new ObjectChangeData();
11385// {
11386// part.StoreUndoState();
11387// parts[j].IgnoreUndoUpdate = true;
11388// }
11389 11594
11390 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11595 /*ubit from ll JIRA:
11596 * 0x01 position
11597 * 0x02 rotation
11598 * 0x04 scale
11599
11600 * 0x08 LINK_SET
11601 * 0x10 UNIFORM for scale
11602 */
11391 11603
11392 switch (block.Type) 11604 // translate to internal changes
11393 { 11605 // not all cases .. just the ones older code did
11394 case 1:
11395 Vector3 pos1 = new Vector3(block.Data, 0);
11396 11606
11397 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11607 switch (block.Type)
11398 if (handlerUpdatePrimSinglePosition != null) 11608 {
11399 { 11609 case 1: //change position sp
11400 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11610 udata.position = new Vector3(block.Data, 0);
11401 handlerUpdatePrimSinglePosition(localId, pos1, this);
11402 }
11403 break;
11404 11611
11405 case 2: 11612 udata.change = ObjectChangeType.primP;
11406 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11613 updatehandler(localId, udata, this);
11614 break;
11407 11615
11408 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11616 case 2: // rotation sp
11409 if (handlerUpdatePrimSingleRotation != null) 11617 udata.rotation = new Quaternion(block.Data, 0, true);
11410 {
11411 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11412 handlerUpdatePrimSingleRotation(localId, rot1, this);
11413 }
11414 break;
11415 11618
11416 case 3: 11619 udata.change = ObjectChangeType.primR;
11417 Vector3 rotPos = new Vector3(block.Data, 0); 11620 updatehandler(localId, udata, this);
11418 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11621 break;
11419 11622
11420 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11623 case 3: // position plus rotation
11421 if (handlerUpdatePrimSingleRotationPosition != null) 11624 udata.position = new Vector3(block.Data, 0);
11422 { 11625 udata.rotation = new Quaternion(block.Data, 12, true);
11423 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11424 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11425 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11426 }
11427 break;
11428 11626
11429 case 4: 11627 udata.change = ObjectChangeType.primPR;
11430 case 20: 11628 updatehandler(localId, udata, this);
11431 Vector3 scale4 = new Vector3(block.Data, 0); 11629 break;
11432 11630
11433 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11631 case 4: // scale sp
11434 if (handlerUpdatePrimScale != null) 11632 udata.scale = new Vector3(block.Data, 0);
11435 { 11633 udata.change = ObjectChangeType.primS;
11436 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11437 handlerUpdatePrimScale(localId, scale4, this);
11438 }
11439 break;
11440 11634
11441 case 5: 11635 updatehandler(localId, udata, this);
11442 Vector3 scale1 = new Vector3(block.Data, 12); 11636 break;
11443 Vector3 pos11 = new Vector3(block.Data, 0);
11444 11637
11445 handlerUpdatePrimScale = OnUpdatePrimScale; 11638 case 0x14: // uniform scale sp
11446 if (handlerUpdatePrimScale != null) 11639 udata.scale = new Vector3(block.Data, 0);
11447 {
11448 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11449 handlerUpdatePrimScale(localId, scale1, this);
11450 11640
11451 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11641 udata.change = ObjectChangeType.primUS;
11452 if (handlerUpdatePrimSinglePosition != null) 11642 updatehandler(localId, udata, this);
11453 { 11643 break;
11454 handlerUpdatePrimSinglePosition(localId, pos11, this);
11455 }
11456 }
11457 break;
11458 11644
11459 case 9: 11645 case 5: // scale and position sp
11460 Vector3 pos2 = new Vector3(block.Data, 0); 11646 udata.position = new Vector3(block.Data, 0);
11647 udata.scale = new Vector3(block.Data, 12);
11461 11648
11462 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11649 udata.change = ObjectChangeType.primPS;
11650 updatehandler(localId, udata, this);
11651 break;
11463 11652
11464 if (handlerUpdateVector != null) 11653 case 0x15: //uniform scale and position
11465 { 11654 udata.position = new Vector3(block.Data, 0);
11466 handlerUpdateVector(localId, pos2, this); 11655 udata.scale = new Vector3(block.Data, 12);
11467 }
11468 break;
11469 11656
11470 case 10: 11657 udata.change = ObjectChangeType.primPUS;
11471 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11658 updatehandler(localId, udata, this);
11659 break;
11472 11660
11473 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11661 // now group related (bit 4)
11474 if (handlerUpdatePrimRotation != null) 11662 case 9: //( 8 + 1 )group position
11475 { 11663 udata.position = new Vector3(block.Data, 0);
11476 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11477 handlerUpdatePrimRotation(localId, rot3, this);
11478 }
11479 break;
11480 11664
11481 case 11: 11665 udata.change = ObjectChangeType.groupP;
11482 Vector3 pos3 = new Vector3(block.Data, 0); 11666 updatehandler(localId, udata, this);
11483 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11667 break;
11484 11668
11485 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11669 case 0x0A: // (8 + 2) group rotation
11486 if (handlerUpdatePrimGroupRotation != null) 11670 udata.rotation = new Quaternion(block.Data, 0, true);
11487 {
11488 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11489 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11490 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11491 }
11492 break;
11493 case 12:
11494 case 28:
11495 Vector3 scale7 = new Vector3(block.Data, 0);
11496 11671
11497 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11672 udata.change = ObjectChangeType.groupR;
11498 if (handlerUpdatePrimGroupScale != null) 11673 updatehandler(localId, udata, this);
11499 { 11674 break;
11500 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11501 handlerUpdatePrimGroupScale(localId, scale7, this);
11502 }
11503 break;
11504 11675
11505 case 13: 11676 case 0x0B: //( 8 + 2 + 1) group rotation and position
11506 Vector3 scale2 = new Vector3(block.Data, 12); 11677 udata.position = new Vector3(block.Data, 0);
11507 Vector3 pos4 = new Vector3(block.Data, 0); 11678 udata.rotation = new Quaternion(block.Data, 12, true);
11508 11679
11509 handlerUpdatePrimScale = OnUpdatePrimScale; 11680 udata.change = ObjectChangeType.groupPR;
11510 if (handlerUpdatePrimScale != null) 11681 updatehandler(localId, udata, this);
11511 { 11682 break;
11512 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11513 handlerUpdatePrimScale(localId, scale2, this);
11514 11683
11515 // Change the position based on scale (for bug number 246) 11684 case 0x0C: // (8 + 4) group scale
11516 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11685 // only afects root prim and only sent by viewer editor object tab scaling
11517 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11686 // mouse edition only allows uniform scaling
11518 if (handlerUpdatePrimSinglePosition != null) 11687 // SL MAY CHANGE THIS in viewers
11519 {
11520 handlerUpdatePrimSinglePosition(localId, pos4, this);
11521 }
11522 }
11523 break;
11524 11688
11525 case 29: 11689 udata.scale = new Vector3(block.Data, 0);
11526 Vector3 scale5 = new Vector3(block.Data, 12);
11527 Vector3 pos5 = new Vector3(block.Data, 0);
11528 11690
11529 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11691 udata.change = ObjectChangeType.groupS;
11530 if (handlerUpdatePrimGroupScale != null) 11692 updatehandler(localId, udata, this);
11531 {
11532 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11533 part.StoreUndoState(true);
11534 part.IgnoreUndoUpdate = true;
11535 handlerUpdatePrimGroupScale(localId, scale5, this);
11536 handlerUpdateVector = OnUpdatePrimGroupPosition;
11537 11693
11538 if (handlerUpdateVector != null) 11694 break;
11539 {
11540 handlerUpdateVector(localId, pos5, this);
11541 }
11542 11695
11543 part.IgnoreUndoUpdate = false; 11696 case 0x0D: //(8 + 4 + 1) group scale and position
11544 } 11697 // exception as above
11545 11698
11546 break; 11699 udata.position = new Vector3(block.Data, 0);
11700 udata.scale = new Vector3(block.Data, 12);
11547 11701
11548 case 21: 11702 udata.change = ObjectChangeType.groupPS;
11549 Vector3 scale6 = new Vector3(block.Data, 12); 11703 updatehandler(localId, udata, this);
11550 Vector3 pos6 = new Vector3(block.Data, 0); 11704 break;
11551 11705
11552 handlerUpdatePrimScale = OnUpdatePrimScale; 11706 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11553 if (handlerUpdatePrimScale != null) 11707 udata.scale = new Vector3(block.Data, 0);
11554 {
11555 part.StoreUndoState(false);
11556 part.IgnoreUndoUpdate = true;
11557 11708
11558 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11709 udata.change = ObjectChangeType.groupUS;
11559 handlerUpdatePrimScale(localId, scale6, this); 11710 updatehandler(localId, udata, this);
11560 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11711 break;
11561 if (handlerUpdatePrimSinglePosition != null)
11562 {
11563 handlerUpdatePrimSinglePosition(localId, pos6, this);
11564 }
11565 11712
11566 part.IgnoreUndoUpdate = false; 11713 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11567 } 11714 udata.position = new Vector3(block.Data, 0);
11568 break; 11715 udata.scale = new Vector3(block.Data, 12);
11569 11716
11570 default: 11717 udata.change = ObjectChangeType.groupPUS;
11571 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11718 updatehandler(localId, udata, this);
11572 break; 11719 break;
11720
11721 default:
11722 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11723 break;
11724 }
11573 } 11725 }
11574 11726
11575// for (int j = 0; j < parts.Length; j++)
11576// parts[j].IgnoreUndoUpdate = false;
11577 } 11727 }
11578 } 11728 }
11579 } 11729 }
11580
11581 return true; 11730 return true;
11582 } 11731 }
11583 11732
@@ -12027,7 +12176,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12027// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12176// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12028// requestID, taskID, (SourceType)sourceType, Name); 12177// requestID, taskID, (SourceType)sourceType, Name);
12029 12178
12179
12180 //Note, the bool returned from the below function is useless since it is always false.
12030 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12181 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12182
12031 } 12183 }
12032 12184
12033 /// <summary> 12185 /// <summary>
@@ -12093,7 +12245,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12093 /// <returns></returns> 12245 /// <returns></returns>
12094 private static int CalculateNumPackets(byte[] data) 12246 private static int CalculateNumPackets(byte[] data)
12095 { 12247 {
12096 const uint m_maxPacketSize = 600; 12248// const uint m_maxPacketSize = 600;
12249 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12097 int numPackets = 1; 12250 int numPackets = 1;
12098 12251
12099 if (data == null) 12252 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 097f109..bcb45cf 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,