aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.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/Caps/RegionConsoleModule.cs7
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/J2KImage.cs3
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs1190
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs80
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs4
9 files changed, 982 insertions, 555 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 185f9ce..88c4d7f 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
@@ -204,6 +207,14 @@ namespace OpenSim.Region.ClientStack.Linden
204 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req); 207 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
205 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req); 208 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
206 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req); 209 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
210 IRequestHandler getObjectPhysicsDataHandler = new RestStreamHandler("POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData);
211 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
212 IRequestHandler getObjectCostHandler = new RestStreamHandler("POST", capsBase + m_getObjectCostPath, GetObjectCost);
213 m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
214 IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
215 m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
216
217
207 218
208 m_HostCapsObj.RegisterHandler( 219 m_HostCapsObj.RegisterHandler(
209 "CopyInventoryFromNotecard", 220 "CopyInventoryFromNotecard",
@@ -854,6 +865,151 @@ namespace OpenSim.Region.ClientStack.Linden
854 response["int_response_code"] = 200; 865 response["int_response_code"] = 200;
855 return LLSDHelpers.SerialiseLLSDReply(response); 866 return LLSDHelpers.SerialiseLLSDReply(response);
856 } 867 }
868
869 public string GetObjectPhysicsData(string request, string path,
870 string param, IOSHttpRequest httpRequest,
871 IOSHttpResponse httpResponse)
872 {
873 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
874 OSDMap resp = new OSDMap();
875 OSDArray object_ids = (OSDArray)req["object_ids"];
876
877 for (int i = 0 ; i < object_ids.Count ; i++)
878 {
879 UUID uuid = object_ids[i].AsUUID();
880
881 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
882 if (obj != null)
883 {
884 OSDMap object_data = new OSDMap();
885
886 object_data["PhysicsShapeType"] = obj.PhysicsShapeType;
887 object_data["Density"] = obj.Density;
888 object_data["Friction"] = obj.Friction;
889 object_data["Restitution"] = obj.Bounciness;
890 object_data["GravityMultiplier"] = obj.GravityModifier;
891
892 resp[uuid.ToString()] = object_data;
893 }
894 }
895
896 string response = OSDParser.SerializeLLSDXmlString(resp);
897 return response;
898 }
899
900 public string GetObjectCost(string request, string path,
901 string param, IOSHttpRequest httpRequest,
902 IOSHttpResponse httpResponse)
903 {
904 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
905 OSDMap resp = new OSDMap();
906
907 OSDArray object_ids = (OSDArray)req["object_ids"];
908
909 for (int i = 0; i < object_ids.Count; i++)
910 {
911 UUID uuid = object_ids[i].AsUUID();
912
913 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
914
915 if (part != null)
916 {
917 SceneObjectGroup grp = part.ParentGroup;
918 if (grp != null)
919 {
920 float linksetCost;
921 float linksetPhysCost;
922 float partCost;
923 float partPhysCost;
924
925 grp.GetResourcesCosts(part, out linksetCost, out linksetPhysCost, out partCost, out partPhysCost);
926
927 OSDMap object_data = new OSDMap();
928 object_data["linked_set_resource_cost"] = linksetCost;
929 object_data["resource_cost"] = partCost;
930 object_data["physics_cost"] = partPhysCost;
931 object_data["linked_set_physics_cost"] = linksetPhysCost;
932
933 resp[uuid.ToString()] = object_data;
934 }
935 }
936 }
937
938 string response = OSDParser.SerializeLLSDXmlString(resp);
939 return response;
940 }
941
942 public string ResourceCostSelected(string request, string path,
943 string param, IOSHttpRequest httpRequest,
944 IOSHttpResponse httpResponse)
945 {
946 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
947 OSDMap resp = new OSDMap();
948
949
950 float phys=0;
951 float stream=0;
952 float simul=0;
953
954 if (req.ContainsKey("selected_roots"))
955 {
956 OSDArray object_ids = (OSDArray)req["selected_roots"];
957
958 // should go by SOG suming costs for all parts
959 // ll v3 works ok with several objects select we get the list and adds ok
960 // FS calls per object so results are wrong guess fs bug
961 for (int i = 0; i < object_ids.Count; i++)
962 {
963 UUID uuid = object_ids[i].AsUUID();
964 float Physc;
965 float simulc;
966 float streamc;
967
968 SceneObjectGroup grp = m_Scene.GetGroupByPrim(uuid);
969 if (grp != null)
970 {
971 grp.GetSelectedCosts(out Physc, out streamc, out simulc);
972 phys += Physc;
973 stream += streamc;
974 simul += simulc;
975 }
976 }
977 }
978 else if (req.ContainsKey("selected_prims"))
979 {
980 OSDArray object_ids = (OSDArray)req["selected_prims"];
981
982 // don't see in use in any of the 2 viewers
983 // guess it should be for edit linked but... nothing
984 // should go to SOP per part
985 for (int i = 0; i < object_ids.Count; i++)
986 {
987 UUID uuid = object_ids[i].AsUUID();
988
989 SceneObjectPart part = m_Scene.GetSceneObjectPart(uuid);
990 if (part != null)
991 {
992 phys += part.PhysicsCost;
993 stream += part.StreamingCost;
994 simul += part.SimulationCost;
995 }
996 }
997 }
998
999 if (simul != 0)
1000 {
1001 OSDMap object_data = new OSDMap();
1002
1003 object_data["physics"] = phys;
1004 object_data["streaming"] = stream;
1005 object_data["simulation"] = simul;
1006
1007 resp["selected"] = object_data;
1008 }
1009
1010 string response = OSDParser.SerializeLLSDXmlString(resp);
1011 return response;
1012 }
857 } 1013 }
858 1014
859 public class AssetUploader 1015 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/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index 36af55f..413536d 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -64,6 +64,8 @@ namespace OpenSim.Region.ClientStack.Linden
64 private Commands m_commands = new Commands(); 64 private Commands m_commands = new Commands();
65 public ICommands Commands { get { return m_commands; } } 65 public ICommands Commands { get { return m_commands; } }
66 66
67 public event ConsoleMessage OnConsoleMessage;
68
67 public void Initialise(IConfigSource source) 69 public void Initialise(IConfigSource source)
68 { 70 {
69 m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help); 71 m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help);
@@ -118,6 +120,11 @@ namespace OpenSim.Region.ClientStack.Linden
118 OSD osd = OSD.FromString(message); 120 OSD osd = OSD.FromString(message);
119 121
120 m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID); 122 m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID);
123
124 ConsoleMessage handlerConsoleMessage = OnConsoleMessage;
125
126 if (handlerConsoleMessage != null)
127 handlerConsoleMessage( agentID, message);
121 } 128 }
122 129
123 public bool RunCommand(string command, UUID invokerID) 130 public bool RunCommand(string command, UUID invokerID)
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 148d0e0..2dcc9cb 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;
@@ -380,6 +388,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
380 get { return m_startpos; } 388 get { return m_startpos; }
381 set { m_startpos = value; } 389 set { m_startpos = value; }
382 } 390 }
391 public bool DeliverPackets
392 {
393 get { return m_deliverPackets; }
394 set {
395 m_deliverPackets = value;
396 m_udpClient.m_deliverPackets = value;
397 }
398 }
383 public UUID AgentId { get { return m_agentId; } } 399 public UUID AgentId { get { return m_agentId; } }
384 public ISceneAgent SceneAgent { get; set; } 400 public ISceneAgent SceneAgent { get; set; }
385 public UUID ActiveGroupId { get { return m_activeGroupID; } } 401 public UUID ActiveGroupId { get { return m_activeGroupID; } }
@@ -457,7 +473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
457 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 473 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
458 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 474 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
459 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 475 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
460 m_killRecord = new HashSet<uint>(); 476// m_killRecord = new HashSet<uint>();
461// m_attachmentsSent = new HashSet<uint>(); 477// m_attachmentsSent = new HashSet<uint>();
462 478
463 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 479 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
@@ -487,12 +503,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
487 503
488 #region Client Methods 504 #region Client Methods
489 505
506
507 /// <summary>
508 /// Close down the client view
509 /// </summary>
490 public void Close() 510 public void Close()
491 { 511 {
492 Close(false); 512 Close(true, false);
493 } 513 }
494 514
495 public void Close(bool force) 515 public void Close(bool sendStop, bool force)
496 { 516 {
497 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g. 517 // We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
498 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection. 518 // a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
@@ -504,7 +524,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
504 return; 524 return;
505 525
506 IsActive = false; 526 IsActive = false;
507 CloseWithoutChecks(); 527 CloseWithoutChecks(sendStop);
508 } 528 }
509 } 529 }
510 530
@@ -517,12 +537,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
517 /// 537 ///
518 /// Callers must lock ClosingSyncLock before calling. 538 /// Callers must lock ClosingSyncLock before calling.
519 /// </remarks> 539 /// </remarks>
520 public void CloseWithoutChecks() 540 public void CloseWithoutChecks(bool sendStop)
521 { 541 {
522 m_log.DebugFormat( 542 m_log.DebugFormat(
523 "[CLIENT]: Close has been called for {0} attached to scene {1}", 543 "[CLIENT]: Close has been called for {0} attached to scene {1}",
524 Name, m_scene.RegionInfo.RegionName); 544 Name, m_scene.RegionInfo.RegionName);
525 545
546 if (sendStop)
547 {
548 // Send the STOP packet
549 DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator);
550 OutPacket(disable, ThrottleOutPacketType.Unknown);
551 }
552
526 // Shutdown the image manager 553 // Shutdown the image manager
527 ImageManager.Close(); 554 ImageManager.Close();
528 555
@@ -819,7 +846,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
819 reply.ChatData.OwnerID = fromAgentID; 846 reply.ChatData.OwnerID = fromAgentID;
820 reply.ChatData.SourceID = fromAgentID; 847 reply.ChatData.SourceID = fromAgentID;
821 848
822 OutPacket(reply, ThrottleOutPacketType.Task); 849 OutPacket(reply, ThrottleOutPacketType.Unknown);
823 } 850 }
824 851
825 /// <summary> 852 /// <summary>
@@ -1105,6 +1132,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1105 public virtual void SendLayerData(float[] map) 1132 public virtual void SendLayerData(float[] map)
1106 { 1133 {
1107 Util.FireAndForget(DoSendLayerData, map); 1134 Util.FireAndForget(DoSendLayerData, map);
1135
1136 // Send it sync, and async. It's not that much data
1137 // and it improves user experience just so much!
1138 DoSendLayerData(map);
1108 } 1139 }
1109 1140
1110 /// <summary> 1141 /// <summary>
@@ -1117,16 +1148,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1117 1148
1118 try 1149 try
1119 { 1150 {
1120 //for (int y = 0; y < 16; y++) 1151 for (int y = 0; y < 16; y++)
1121 //{ 1152 {
1122 // for (int x = 0; x < 16; x++) 1153 for (int x = 0; x < 16; x+=4)
1123 // { 1154 {
1124 // SendLayerData(x, y, map); 1155 SendLayerPacket(x, y, map);
1125 // } 1156 }
1126 //} 1157 }
1127
1128 // Send LayerData in a spiral pattern. Fun!
1129 SendLayerTopRight(map, 0, 0, 15, 15);
1130 } 1158 }
1131 catch (Exception e) 1159 catch (Exception e)
1132 { 1160 {
@@ -1134,51 +1162,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1134 } 1162 }
1135 } 1163 }
1136 1164
1137 private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2)
1138 {
1139 // Row
1140 for (int i = x1; i <= x2; i++)
1141 SendLayerData(i, y1, map);
1142
1143 // Column
1144 for (int j = y1 + 1; j <= y2; j++)
1145 SendLayerData(x2, j, map);
1146
1147 if (x2 - x1 > 0)
1148 SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2);
1149 }
1150
1151 void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2)
1152 {
1153 // Row in reverse
1154 for (int i = x2; i >= x1; i--)
1155 SendLayerData(i, y2, map);
1156
1157 // Column in reverse
1158 for (int j = y2 - 1; j >= y1; j--)
1159 SendLayerData(x1, j, map);
1160
1161 if (x2 - x1 > 0)
1162 SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1);
1163 }
1164
1165 /// <summary> 1165 /// <summary>
1166 /// Sends a set of four patches (x, x+1, ..., x+3) to the client 1166 /// Sends a set of four patches (x, x+1, ..., x+3) to the client
1167 /// </summary> 1167 /// </summary>
1168 /// <param name="map">heightmap</param> 1168 /// <param name="map">heightmap</param>
1169 /// <param name="px">X coordinate for patches 0..12</param> 1169 /// <param name="px">X coordinate for patches 0..12</param>
1170 /// <param name="py">Y coordinate for patches 0..15</param> 1170 /// <param name="py">Y coordinate for patches 0..15</param>
1171 // private void SendLayerPacket(float[] map, int y, int x) 1171 private void SendLayerPacket(int x, int y, float[] map)
1172 // { 1172 {
1173 // int[] patches = new int[4]; 1173 int[] patches = new int[4];
1174 // patches[0] = x + 0 + y * 16; 1174 patches[0] = x + 0 + y * 16;
1175 // patches[1] = x + 1 + y * 16; 1175 patches[1] = x + 1 + y * 16;
1176 // patches[2] = x + 2 + y * 16; 1176 patches[2] = x + 2 + y * 16;
1177 // patches[3] = x + 3 + y * 16; 1177 patches[3] = x + 3 + y * 16;
1178 1178
1179 // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); 1179 float[] heightmap = (map.Length == 65536) ?
1180 // OutPacket(layerpack, ThrottleOutPacketType.Land); 1180 map :
1181 // } 1181 LLHeightFieldMoronize(map);
1182
1183 try
1184 {
1185 Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1186 OutPacket(layerpack, ThrottleOutPacketType.Land);
1187 }
1188 catch
1189 {
1190 for (int px = x ; px < x + 4 ; px++)
1191 SendLayerData(px, y, map);
1192 }
1193 }
1182 1194
1183 /// <summary> 1195 /// <summary>
1184 /// Sends a specified patch to a client 1196 /// Sends a specified patch to a client
@@ -1198,7 +1210,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1198 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); 1210 LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches);
1199 layerpack.Header.Reliable = true; 1211 layerpack.Header.Reliable = true;
1200 1212
1201 OutPacket(layerpack, ThrottleOutPacketType.Land); 1213 OutPacket(layerpack, ThrottleOutPacketType.Task);
1202 } 1214 }
1203 catch (Exception e) 1215 catch (Exception e)
1204 { 1216 {
@@ -1561,7 +1573,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1561 1573
1562 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1574 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1563 { 1575 {
1564// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1576// foreach (uint id in localIDs)
1577// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1565 1578
1566 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1579 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1567 // TODO: don't create new blocks if recycling an old packet 1580 // TODO: don't create new blocks if recycling an old packet
@@ -1583,17 +1596,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1583 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race 1596 // We MUST lock for both manipulating the kill record and sending the packet, in order to avoid a race
1584 // condition where a kill can be processed before an out-of-date update for the same object. 1597 // condition where a kill can be processed before an out-of-date update for the same object.
1585 // ProcessEntityUpdates() also takes the m_killRecord lock. 1598 // ProcessEntityUpdates() also takes the m_killRecord lock.
1586 lock (m_killRecord) 1599// lock (m_killRecord)
1587 { 1600// {
1588 foreach (uint localID in localIDs) 1601// foreach (uint localID in localIDs)
1589 m_killRecord.Add(localID); 1602// m_killRecord.Add(localID);
1590 1603
1591 // The throttle queue used here must match that being used for updates. Otherwise, there is a 1604 // The throttle queue used here must match that being used for updates. Otherwise, there is a
1592 // chance that a kill packet put on a separate queue will be sent to the client before an existing 1605 // chance that a kill packet put on a separate queue will be sent to the client before an existing
1593 // update packet on another queue. Receiving updates after kills results in unowned and undeletable 1606 // update packet on another queue. Receiving updates after kills results in unowned and undeletable
1594 // scene objects in a viewer until that viewer is relogged in. 1607 // scene objects in a viewer until that viewer is relogged in.
1595 OutPacket(kill, ThrottleOutPacketType.Task); 1608 OutPacket(kill, ThrottleOutPacketType.Task);
1596 } 1609// }
1597 } 1610 }
1598 } 1611 }
1599 1612
@@ -2132,16 +2145,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2132 replytask.InventoryData.TaskID = taskID; 2145 replytask.InventoryData.TaskID = taskID;
2133 replytask.InventoryData.Serial = serial; 2146 replytask.InventoryData.Serial = serial;
2134 replytask.InventoryData.Filename = fileName; 2147 replytask.InventoryData.Filename = fileName;
2135 OutPacket(replytask, ThrottleOutPacketType.Asset); 2148 OutPacket(replytask, ThrottleOutPacketType.Task);
2136 } 2149 }
2137 2150
2138 public void SendXferPacket(ulong xferID, uint packet, byte[] data) 2151 public void SendXferPacket(ulong xferID, uint packet, byte[] data, bool isTaskInventory)
2139 { 2152 {
2153 ThrottleOutPacketType type = ThrottleOutPacketType.Asset;
2154 if (isTaskInventory)
2155 type = ThrottleOutPacketType.Task;
2156
2140 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket); 2157 SendXferPacketPacket sendXfer = (SendXferPacketPacket)PacketPool.Instance.GetPacket(PacketType.SendXferPacket);
2141 sendXfer.XferID.ID = xferID; 2158 sendXfer.XferID.ID = xferID;
2142 sendXfer.XferID.Packet = packet; 2159 sendXfer.XferID.Packet = packet;
2143 sendXfer.DataPacket.Data = data; 2160 sendXfer.DataPacket.Data = data;
2144 OutPacket(sendXfer, ThrottleOutPacketType.Asset); 2161 OutPacket(sendXfer, type);
2145 } 2162 }
2146 2163
2147 public void SendAbortXferPacket(ulong xferID) 2164 public void SendAbortXferPacket(ulong xferID)
@@ -2323,6 +2340,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2323 OutPacket(sound, ThrottleOutPacketType.Task); 2340 OutPacket(sound, ThrottleOutPacketType.Task);
2324 } 2341 }
2325 2342
2343 public void SendTransferAbort(TransferRequestPacket transferRequest)
2344 {
2345 TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort);
2346 abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
2347 abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType;
2348 m_log.Debug("[Assets] Aborting transfer; asset request failed");
2349 OutPacket(abort, ThrottleOutPacketType.Task);
2350 }
2351
2326 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) 2352 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
2327 { 2353 {
2328 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); 2354 SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger);
@@ -2615,6 +2641,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2615 } 2641 }
2616 } 2642 }
2617 2643
2644 public void SendPartPhysicsProprieties(ISceneEntity entity)
2645 {
2646 SceneObjectPart part = (SceneObjectPart)entity;
2647 if (part != null && AgentId != UUID.Zero)
2648 {
2649 try
2650 {
2651 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
2652 if (eq != null)
2653 {
2654 uint localid = part.LocalId;
2655 byte physshapetype = part.PhysicsShapeType;
2656 float density = part.Density;
2657 float friction = part.Friction;
2658 float bounce = part.Bounciness;
2659 float gravmod = part.GravityModifier;
2660
2661 eq.partPhysicsProperties(localid, physshapetype, density, friction, bounce, gravmod,AgentId);
2662 }
2663 }
2664 catch (Exception ex)
2665 {
2666 m_log.Error("Unable to send part Physics Proprieties - exception: " + ex.ToString());
2667 }
2668 part.UpdatePhysRequired = false;
2669 }
2670 }
2671
2672
2618 2673
2619 public void SendGroupNameReply(UUID groupLLUID, string GroupName) 2674 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
2620 { 2675 {
@@ -2712,7 +2767,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2712 else 2767 else
2713 { 2768 {
2714 int processedLength = 0; 2769 int processedLength = 0;
2715 int maxChunkSize = Settings.MAX_PACKET_SIZE - 100; 2770// int maxChunkSize = Settings.MAX_PACKET_SIZE - 100;
2771
2772 int maxChunkSize = (int) MaxTransferBytesPerPacket;
2716 int packetNumber = 0; 2773 int packetNumber = 0;
2717 2774
2718 while (processedLength < req.AssetInf.Data.Length) 2775 while (processedLength < req.AssetInf.Data.Length)
@@ -2783,7 +2840,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2783 reply.Data.ParcelID = parcelID; 2840 reply.Data.ParcelID = parcelID;
2784 reply.Data.OwnerID = land.OwnerID; 2841 reply.Data.OwnerID = land.OwnerID;
2785 reply.Data.Name = Utils.StringToBytes(land.Name); 2842 reply.Data.Name = Utils.StringToBytes(land.Name);
2786 reply.Data.Desc = Utils.StringToBytes(land.Description); 2843 if (land != null && land.Description != null && land.Description != String.Empty)
2844 reply.Data.Desc = Utils.StringToBytes(land.Description.Substring(0, land.Description.Length > 254 ? 254: land.Description.Length));
2845 else
2846 reply.Data.Desc = new Byte[0];
2787 reply.Data.ActualArea = land.Area; 2847 reply.Data.ActualArea = land.Area;
2788 reply.Data.BillableArea = land.Area; // TODO: what is this? 2848 reply.Data.BillableArea = land.Area; // TODO: what is this?
2789 2849
@@ -3518,7 +3578,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3518 3578
3519 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance); 3579 AvatarAppearancePacket avp = (AvatarAppearancePacket)PacketPool.Instance.GetPacket(PacketType.AvatarAppearance);
3520 // TODO: don't create new blocks if recycling an old packet 3580 // TODO: don't create new blocks if recycling an old packet
3521 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; 3581 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[visualParams.Length];
3522 avp.ObjectData.TextureEntry = textureEntry; 3582 avp.ObjectData.TextureEntry = textureEntry;
3523 3583
3524 AvatarAppearancePacket.VisualParamBlock avblock = null; 3584 AvatarAppearancePacket.VisualParamBlock avblock = null;
@@ -3648,7 +3708,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3648 /// </summary> 3708 /// </summary>
3649 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) 3709 public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3650 { 3710 {
3651 //double priority = m_prioritizer.GetUpdatePriority(this, entity); 3711 if (entity is SceneObjectPart)
3712 {
3713 SceneObjectPart e = (SceneObjectPart)entity;
3714 SceneObjectGroup g = e.ParentGroup;
3715 if (g.RootPart.Shape.State > 30) // HUD
3716 if (g.OwnerID != AgentId)
3717 return; // Don't send updates for other people's HUDs
3718 }
3719
3652 uint priority = m_prioritizer.GetUpdatePriority(this, entity); 3720 uint priority = m_prioritizer.GetUpdatePriority(this, entity);
3653 3721
3654 lock (m_entityUpdates.SyncRoot) 3722 lock (m_entityUpdates.SyncRoot)
@@ -3715,27 +3783,74 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3715 3783
3716 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race 3784 // We must lock for both manipulating the kill record and sending the packet, in order to avoid a race
3717 // condition where a kill can be processed before an out-of-date update for the same object. 3785 // condition where a kill can be processed before an out-of-date update for the same object.
3718 lock (m_killRecord) 3786 float avgTimeDilation = 1.0f;
3787 IEntityUpdate iupdate;
3788 Int32 timeinqueue; // this is just debugging code & can be dropped later
3789
3790 while (updatesThisCall < maxUpdates)
3719 { 3791 {
3720 float avgTimeDilation = 1.0f; 3792 lock (m_entityUpdates.SyncRoot)
3721 IEntityUpdate iupdate; 3793 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3722 Int32 timeinqueue; // this is just debugging code & can be dropped later 3794 break;
3795
3796 EntityUpdate update = (EntityUpdate)iupdate;
3797
3798 avgTimeDilation += update.TimeDilation;
3799 avgTimeDilation *= 0.5f;
3723 3800
3724 while (updatesThisCall < maxUpdates) 3801 if (update.Entity is SceneObjectPart)
3725 { 3802 {
3726 lock (m_entityUpdates.SyncRoot) 3803 SceneObjectPart part = (SceneObjectPart)update.Entity;
3727 if (!m_entityUpdates.TryDequeue(out iupdate, out timeinqueue))
3728 break;
3729 3804
3730 EntityUpdate update = (EntityUpdate)iupdate; 3805 if (part.ParentGroup.IsDeleted)
3731 3806 continue;
3732 avgTimeDilation += update.TimeDilation;
3733 avgTimeDilation *= 0.5f;
3734 3807
3735 if (update.Entity is SceneObjectPart) 3808 if (part.ParentGroup.IsAttachment)
3809 { // Someone else's HUD, why are we getting these?
3810 if (part.ParentGroup.OwnerID != AgentId &&
3811 part.ParentGroup.RootPart.Shape.State > 30)
3812 continue;
3813 ScenePresence sp;
3814 // Owner is not in the sim, don't update it to
3815 // anyone
3816 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3817 continue;
3818
3819 List<SceneObjectGroup> atts = sp.GetAttachments();
3820 bool found = false;
3821 foreach (SceneObjectGroup att in atts)
3822 {
3823 if (att == part.ParentGroup)
3824 {
3825 found = true;
3826 break;
3827 }
3828 }
3829
3830 // It's an attachment of a valid avatar, but
3831 // doesn't seem to be attached, skip
3832 if (!found)
3833 continue;
3834
3835 // On vehicle crossing, the attachments are received
3836 // while the avatar is still a child. Don't send
3837 // updates here because the LocalId has not yet
3838 // been updated and the viewer will derender the
3839 // attachments until the avatar becomes root.
3840 if (sp.IsChildAgent)
3841 continue;
3842
3843 // If the object is an attachment we don't want it to be in the kill
3844 // record. Else attaching from inworld and subsequently dropping
3845 // it will no longer work.
3846// lock (m_killRecord)
3847// {
3848// m_killRecord.Remove(part.LocalId);
3849// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId);
3850// }
3851 }
3852 else
3736 { 3853 {
3737 SceneObjectPart part = (SceneObjectPart)update.Entity;
3738
3739 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client 3854 // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client
3740 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good 3855 // will never receive an update after a prim kill. Even then, keeping the kill record may be a good
3741 // safety measure. 3856 // safety measure.
@@ -3746,236 +3861,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3746 // 3861 //
3747 // This doesn't appear to apply to child prims - a client will happily ignore these updates 3862 // This doesn't appear to apply to child prims - a client will happily ignore these updates
3748 // after the root prim has been deleted. 3863 // after the root prim has been deleted.
3749 if (m_killRecord.Contains(part.LocalId)) 3864 //
3750 { 3865 // We ignore this for attachments because attaching something from inworld breaks unless we do.
3751 // m_log.WarnFormat( 3866// lock (m_killRecord)
3752 // "[CLIENT]: Preventing update for prim with local id {0} after client for user {1} told it was deleted", 3867// {
3753 // part.LocalId, Name); 3868// if (m_killRecord.Contains(part.LocalId))
3754 continue; 3869// continue;
3755 } 3870// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId))
3756 3871// continue;
3757 if (part.ParentGroup.IsAttachment && m_disableFacelights) 3872// }
3873 }
3874
3875 if (part.ParentGroup.IsAttachment && m_disableFacelights)
3876 {
3877 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand &&
3878 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3758 { 3879 {
3759 if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && 3880 part.Shape.LightEntry = false;
3760 part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand)
3761 {
3762 part.Shape.LightEntry = false;
3763 }
3764 } 3881 }
3765 } 3882 }
3766 3883 }
3767 #region UpdateFlags to packet type conversion 3884
3768 3885 ++updatesThisCall;
3769 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags; 3886
3770 3887 #region UpdateFlags to packet type conversion
3771 bool canUseCompressed = true; 3888
3772 bool canUseImproved = true; 3889 PrimUpdateFlags updateFlags = (PrimUpdateFlags)update.Flags;
3773 3890
3774 // Compressed object updates only make sense for LL primitives 3891 bool canUseCompressed = true;
3775 if (!(update.Entity is SceneObjectPart)) 3892 bool canUseImproved = true;
3893
3894 // Compressed object updates only make sense for LL primitives
3895 if (!(update.Entity is SceneObjectPart))
3896 {
3897 canUseCompressed = false;
3898 }
3899
3900 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3901 {
3902 canUseCompressed = false;
3903 canUseImproved = false;
3904 }
3905 else
3906 {
3907 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3908 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3909 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3910 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3776 { 3911 {
3777 canUseCompressed = false; 3912 canUseCompressed = false;
3778 } 3913 }
3779 3914
3780 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) 3915 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3916 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3917 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3918 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3919 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3920 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3921 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3922 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3923 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3924 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3925 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3926 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3927 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3928 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3781 { 3929 {
3782 canUseCompressed = false;
3783 canUseImproved = false; 3930 canUseImproved = false;
3784 } 3931 }
3785 else 3932 }
3786 {
3787 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3788 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3789 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3790 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3791 {
3792 canUseCompressed = false;
3793 }
3794
3795 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3796 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3797 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3798 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3799 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3800 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3801 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3802 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3803 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3804 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3805 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3806 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3807 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3808 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3809 {
3810 canUseImproved = false;
3811 }
3812 }
3813
3814 #endregion UpdateFlags to packet type conversion
3815
3816 #region Block Construction
3817
3818 // TODO: Remove this once we can build compressed updates
3819 canUseCompressed = false;
3820 3933
3821 if (!canUseImproved && !canUseCompressed) 3934 #endregion UpdateFlags to packet type conversion
3822 {
3823 ObjectUpdatePacket.ObjectDataBlock updateBlock;
3824 3935
3825 if (update.Entity is ScenePresence) 3936 #region Block Construction
3826 {
3827 updateBlock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
3828 }
3829 else
3830 {
3831 SceneObjectPart part = (SceneObjectPart)update.Entity;
3832 updateBlock = CreatePrimUpdateBlock(part, AgentId);
3833
3834 // If the part has become a private hud since the update was scheduled then we do not
3835 // want to send it to other avatars.
3836 if (part.ParentGroup.IsAttachment
3837 && part.ParentGroup.HasPrivateAttachmentPoint
3838 && part.ParentGroup.AttachedAvatar != AgentId)
3839 continue;
3840
3841 // If the part has since been deleted, then drop the update. In the case of attachments,
3842 // this is to avoid spurious updates to other viewers since post-processing of attachments
3843 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3844 // of the test above).
3845 //
3846 // Actual deletions (kills) happen in another method.
3847 if (part.ParentGroup.IsDeleted)
3848 continue;
3849 }
3850 3937
3851 objectUpdateBlocks.Value.Add(updateBlock); 3938 // TODO: Remove this once we can build compressed updates
3852 objectUpdates.Value.Add(update); 3939 canUseCompressed = false;
3853 }
3854 else if (!canUseImproved)
3855 {
3856 SceneObjectPart part = (SceneObjectPart)update.Entity;
3857 ObjectUpdateCompressedPacket.ObjectDataBlock compressedBlock
3858 = CreateCompressedUpdateBlock(part, updateFlags);
3859
3860 // If the part has since been deleted, then drop the update. In the case of attachments,
3861 // this is to avoid spurious updates to other viewers since post-processing of attachments
3862 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3863 // of the test above).
3864 //
3865 // Actual deletions (kills) happen in another method.
3866 if (part.ParentGroup.IsDeleted)
3867 continue;
3868 3940
3869 compressedUpdateBlocks.Value.Add(compressedBlock); 3941 if (!canUseImproved && !canUseCompressed)
3870 compressedUpdates.Value.Add(update); 3942 {
3943 if (update.Entity is ScenePresence)
3944 {
3945 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3871 } 3946 }
3872 else 3947 else
3873 { 3948 {
3874 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId) 3949 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3875 {
3876 // Self updates go into a special list
3877 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3878 terseAgentUpdates.Value.Add(update);
3879 }
3880 else
3881 {
3882 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseUpdateBlock
3883 = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
3884
3885 // Everything else goes here
3886 if (update.Entity is SceneObjectPart)
3887 {
3888 SceneObjectPart part = (SceneObjectPart)update.Entity;
3889
3890 // If the part has become a private hud since the update was scheduled then we do not
3891 // want to send it to other avatars.
3892 if (part.ParentGroup.IsAttachment
3893 && part.ParentGroup.HasPrivateAttachmentPoint
3894 && part.ParentGroup.AttachedAvatar != AgentId)
3895 continue;
3896
3897 // If the part has since been deleted, then drop the update. In the case of attachments,
3898 // this is to avoid spurious updates to other viewers since post-processing of attachments
3899 // has to change the IsAttachment flag for various reasons (which will end up in a pass
3900 // of the test above).
3901 //
3902 // Actual deletions (kills) happen in another method.
3903 if (part.ParentGroup.IsDeleted)
3904 continue;
3905 }
3906
3907 terseUpdateBlocks.Value.Add(terseUpdateBlock);
3908 terseUpdates.Value.Add(update);
3909 }
3910 } 3950 }
3951 }
3952 else if (!canUseImproved)
3953 {
3954 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3955 }
3956 else
3957 {
3958 if (update.Entity is ScenePresence && ((ScenePresence)update.Entity).UUID == AgentId)
3959 // Self updates go into a special list
3960 terseAgentUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3961 else
3962 // Everything else goes here
3963 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3964 }
3965
3966 #endregion Block Construction
3967 }
3911 3968
3912 ++updatesThisCall; 3969 #region Packet Sending
3913 3970
3914 #endregion Block Construction 3971 const float TIME_DILATION = 1.0f;
3915 } 3972 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f);
3916 3973
3917 #region Packet Sending 3974 if (terseAgentUpdateBlocks.IsValueCreated)
3918 ushort timeDilation = Utils.FloatToUInt16(avgTimeDilation, 0.0f, 1.0f); 3975 {
3976 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3919 3977
3920 if (terseAgentUpdateBlocks.IsValueCreated) 3978 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3921 { 3979 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3922 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3980 packet.RegionData.TimeDilation = timeDilation;
3981 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3923 3982
3924 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3983 for (int i = 0; i < blocks.Count; i++)
3925 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3984 packet.ObjectData[i] = blocks[i];
3926 packet.RegionData.TimeDilation = timeDilation;
3927 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3928 3985
3929 for (int i = 0; i < blocks.Count; i++) 3986 OutPacket(packet, ThrottleOutPacketType.Unknown, true);
3930 packet.ObjectData[i] = blocks[i]; 3987 }
3931 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3932 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
3933 }
3934 3988
3935 if (objectUpdateBlocks.IsValueCreated) 3989 if (objectUpdateBlocks.IsValueCreated)
3936 { 3990 {
3937 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value; 3991 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3938 3992
3939 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3993 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3940 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3994 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3941 packet.RegionData.TimeDilation = timeDilation; 3995 packet.RegionData.TimeDilation = timeDilation;
3942 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3996 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3943 3997
3944 for (int i = 0; i < blocks.Count; i++) 3998 for (int i = 0; i < blocks.Count; i++)
3945 packet.ObjectData[i] = blocks[i]; 3999 packet.ObjectData[i] = blocks[i];
3946 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4000
3947 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 4001 OutPacket(packet, ThrottleOutPacketType.Task, true);
3948 } 4002 }
3949 4003
3950 if (compressedUpdateBlocks.IsValueCreated) 4004 if (compressedUpdateBlocks.IsValueCreated)
3951 { 4005 {
3952 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value; 4006 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3953 4007
3954 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 4008 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3955 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4009 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3956 packet.RegionData.TimeDilation = timeDilation; 4010 packet.RegionData.TimeDilation = timeDilation;
3957 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 4011 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3958
3959 for (int i = 0; i < blocks.Count; i++)
3960 packet.ObjectData[i] = blocks[i];
3961 // If any of the packets created from this call go unacknowledged, all of the updates will be resent
3962 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
3963 }
3964 4012
3965 if (terseUpdateBlocks.IsValueCreated) 4013 for (int i = 0; i < blocks.Count; i++)
3966 { 4014 packet.ObjectData[i] = blocks[i];
3967 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 4015
3968 4016 OutPacket(packet, ThrottleOutPacketType.Task, true);
3969 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 4017 }
3970 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4018
3971 packet.RegionData.TimeDilation = timeDilation; 4019 if (terseUpdateBlocks.IsValueCreated)
3972 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4020 {
3973 4021 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3974 for (int i = 0; i < blocks.Count; i++) 4022
3975 packet.ObjectData[i] = blocks[i]; 4023 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3976 // If any of the packets created from this call go unacknowledged, all of the updates will be resent 4024 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3977 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4025 packet.RegionData.TimeDilation = timeDilation;
3978 } 4026 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
4027
4028 for (int i = 0; i < blocks.Count; i++)
4029 packet.ObjectData[i] = blocks[i];
4030
4031 OutPacket(packet, ThrottleOutPacketType.Task, true);
3979 } 4032 }
3980 4033
3981 #endregion Packet Sending 4034 #endregion Packet Sending
@@ -4268,11 +4321,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4268 4321
4269 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4322 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4270 // of the object rather than the properties when the packet was created 4323 // of the object rather than the properties when the packet was created
4271 OutPacket(packet, ThrottleOutPacketType.Task, true, 4324 // HACK : Remove intelligent resending until it's fixed in core
4272 delegate(OutgoingPacket oPacket) 4325 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4273 { 4326 // delegate(OutgoingPacket oPacket)
4274 ResendPropertyUpdates(updates, oPacket); 4327 // {
4275 }); 4328 // ResendPropertyUpdates(updates, oPacket);
4329 // });
4330 OutPacket(packet, ThrottleOutPacketType.Task, true);
4276 4331
4277 // pbcnt += blocks.Count; 4332 // pbcnt += blocks.Count;
4278 // ppcnt++; 4333 // ppcnt++;
@@ -4298,11 +4353,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4298 // of the object rather than the properties when the packet was created 4353 // of the object rather than the properties when the packet was created
4299 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4354 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4300 updates.Add(familyUpdates.Value[i]); 4355 updates.Add(familyUpdates.Value[i]);
4301 OutPacket(packet, ThrottleOutPacketType.Task, true, 4356 // HACK : Remove intelligent resending until it's fixed in core
4302 delegate(OutgoingPacket oPacket) 4357 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4303 { 4358 // delegate(OutgoingPacket oPacket)
4304 ResendPropertyUpdates(updates, oPacket); 4359 // {
4305 }); 4360 // ResendPropertyUpdates(updates, oPacket);
4361 // });
4362 OutPacket(packet, ThrottleOutPacketType.Task, true);
4306 4363
4307 // fpcnt++; 4364 // fpcnt++;
4308 // fbcnt++; 4365 // fbcnt++;
@@ -4451,37 +4508,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4451 if (bl[i].BannedUserID == UUID.Zero) 4508 if (bl[i].BannedUserID == UUID.Zero)
4452 continue; 4509 continue;
4453 BannedUsers.Add(bl[i].BannedUserID); 4510 BannedUsers.Add(bl[i].BannedUserID);
4454 }
4455 4511
4456 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); 4512 if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
4457 packet.AgentData.TransactionID = UUID.Random(); 4513 {
4458 packet.AgentData.AgentID = AgentId; 4514 EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
4459 packet.AgentData.SessionID = SessionId; 4515 packet.AgentData.TransactionID = UUID.Random();
4460 packet.MethodData.Invoice = invoice; 4516 packet.AgentData.AgentID = AgentId;
4461 packet.MethodData.Method = Utils.StringToBytes("setaccess"); 4517 packet.AgentData.SessionID = SessionId;
4518 packet.MethodData.Invoice = invoice;
4519 packet.MethodData.Method = Utils.StringToBytes("setaccess");
4462 4520
4463 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; 4521 EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
4464 4522
4465 for (int i = 0; i < (6 + BannedUsers.Count); i++) 4523 int j;
4466 { 4524 for (j = 0; j < (6 + BannedUsers.Count); j++)
4467 returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); 4525 {
4468 } 4526 returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
4469 int j = 0; 4527 }
4528 j = 0;
4470 4529
4471 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; 4530 returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
4472 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; 4531 returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
4473 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4532 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4474 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4533 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4475 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; 4534 returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
4476 returnblock[j].Parameter = Utils.StringToBytes("0"); j++; 4535 returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
4477 4536
4478 foreach (UUID banned in BannedUsers) 4537 foreach (UUID banned in BannedUsers)
4479 { 4538 {
4480 returnblock[j].Parameter = banned.GetBytes(); j++; 4539 returnblock[j].Parameter = banned.GetBytes(); j++;
4540 }
4541 packet.ParamList = returnblock;
4542 packet.Header.Reliable = true;
4543 OutPacket(packet, ThrottleOutPacketType.Task);
4544
4545 BannedUsers.Clear();
4546 }
4481 } 4547 }
4482 packet.ParamList = returnblock; 4548
4483 packet.Header.Reliable = false;
4484 OutPacket(packet, ThrottleOutPacketType.Task);
4485 } 4549 }
4486 4550
4487 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) 4551 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
@@ -4667,7 +4731,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4667 4731
4668 if (landData.SimwideArea > 0) 4732 if (landData.SimwideArea > 0)
4669 { 4733 {
4670 int simulatorCapacity = (int)(((float)landData.SimwideArea / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); 4734 int simulatorCapacity = (int)((long)landData.SimwideArea * (long)m_scene.RegionInfo.ObjectCapacity * (long)m_scene.RegionInfo.RegionSettings.ObjectBonus / 65536L);
4735 // Never report more than sim total capacity
4736 if (simulatorCapacity > m_scene.RegionInfo.ObjectCapacity)
4737 simulatorCapacity = m_scene.RegionInfo.ObjectCapacity;
4671 updateMessage.SimWideMaxPrims = simulatorCapacity; 4738 updateMessage.SimWideMaxPrims = simulatorCapacity;
4672 } 4739 }
4673 else 4740 else
@@ -4796,14 +4863,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4796 4863
4797 if (notifyCount > 0) 4864 if (notifyCount > 0)
4798 { 4865 {
4799 if (notifyCount > 32) 4866// if (notifyCount > 32)
4800 { 4867// {
4801 m_log.InfoFormat( 4868// m_log.InfoFormat(
4802 "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}" 4869// "[LAND]: More than {0} avatars own prims on this parcel. Only sending back details of first {0}"
4803 + " - a developer might want to investigate whether this is a hard limit", 32); 4870// + " - a developer might want to investigate whether this is a hard limit", 32);
4804 4871//
4805 notifyCount = 32; 4872// notifyCount = 32;
4806 } 4873// }
4807 4874
4808 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock 4875 ParcelObjectOwnersReplyPacket.DataBlock[] dataBlock
4809 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount]; 4876 = new ParcelObjectOwnersReplyPacket.DataBlock[notifyCount];
@@ -4858,9 +4925,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4858 { 4925 {
4859 ScenePresence presence = (ScenePresence)entity; 4926 ScenePresence presence = (ScenePresence)entity;
4860 4927
4928 position = presence.OffsetPosition;
4929 rotation = presence.Rotation;
4930
4931 if (presence.ParentID != 0)
4932 {
4933 SceneObjectPart part = m_scene.GetSceneObjectPart(presence.ParentID);
4934 if (part != null && part != part.ParentGroup.RootPart)
4935 {
4936 position = part.OffsetPosition + presence.OffsetPosition * part.RotationOffset;
4937 rotation = part.RotationOffset * presence.Rotation;
4938 }
4939 }
4940
4861 attachPoint = 0; 4941 attachPoint = 0;
4862 collisionPlane = presence.CollisionPlane; 4942 collisionPlane = presence.CollisionPlane;
4863 position = presence.OffsetPosition;
4864 velocity = presence.Velocity; 4943 velocity = presence.Velocity;
4865 acceleration = Vector3.Zero; 4944 acceleration = Vector3.Zero;
4866 4945
@@ -4870,7 +4949,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4870// acceleration = new Vector3(1, 0, 0); 4949// acceleration = new Vector3(1, 0, 0);
4871 4950
4872 angularVelocity = Vector3.Zero; 4951 angularVelocity = Vector3.Zero;
4873 rotation = presence.Rotation;
4874 4952
4875 if (sendTexture) 4953 if (sendTexture)
4876 textureEntry = presence.Appearance.Texture.GetBytes(); 4954 textureEntry = presence.Appearance.Texture.GetBytes();
@@ -4975,13 +5053,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4975 5053
4976 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) 5054 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4977 { 5055 {
5056 Vector3 offsetPosition = data.OffsetPosition;
5057 Quaternion rotation = data.Rotation;
5058 uint parentID = data.ParentID;
5059
5060 if (parentID != 0)
5061 {
5062 SceneObjectPart part = m_scene.GetSceneObjectPart(parentID);
5063 if (part != null && part != part.ParentGroup.RootPart)
5064 {
5065 offsetPosition = part.OffsetPosition + data.OffsetPosition * part.RotationOffset;
5066 rotation = part.RotationOffset * data.Rotation;
5067 parentID = part.ParentGroup.RootPart.LocalId;
5068 }
5069 }
5070
4978 byte[] objectData = new byte[76]; 5071 byte[] objectData = new byte[76];
4979 5072
4980 data.CollisionPlane.ToBytes(objectData, 0); 5073 data.CollisionPlane.ToBytes(objectData, 0);
4981 data.OffsetPosition.ToBytes(objectData, 16); 5074 offsetPosition.ToBytes(objectData, 16);
4982// data.Velocity.ToBytes(objectData, 28); 5075// data.Velocity.ToBytes(objectData, 28);
4983// data.Acceleration.ToBytes(objectData, 40); 5076// data.Acceleration.ToBytes(objectData, 40);
4984 data.Rotation.ToBytes(objectData, 52); 5077 rotation.ToBytes(objectData, 52);
4985 //data.AngularVelocity.ToBytes(objectData, 64); 5078 //data.AngularVelocity.ToBytes(objectData, 64);
4986 5079
4987 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 5080 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
@@ -4995,7 +5088,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4995 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + 5088 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4996 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); 5089 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4997 update.ObjectData = objectData; 5090 update.ObjectData = objectData;
4998 update.ParentID = data.ParentID; 5091 update.ParentID = parentID;
4999 update.PathCurve = 16; 5092 update.PathCurve = 16;
5000 update.PathScaleX = 100; 5093 update.PathScaleX = 100;
5001 update.PathScaleY = 100; 5094 update.PathScaleY = 100;
@@ -5013,10 +5106,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5013 update.TextureEntry = Utils.EmptyBytes; 5106 update.TextureEntry = Utils.EmptyBytes;
5014// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; 5107// update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
5015 5108
5109/* 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)
5016 update.UpdateFlags = (uint)( 5110 update.UpdateFlags = (uint)(
5017 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | 5111 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
5018 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | 5112 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
5019 PrimFlags.ObjectOwnerModify); 5113 PrimFlags.ObjectOwnerModify);
5114*/
5115 update.UpdateFlags = 0;
5020 5116
5021 return update; 5117 return update;
5022 } 5118 }
@@ -5336,6 +5432,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5336 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); 5432 AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false);
5337 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); 5433 AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false);
5338 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); 5434 AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode);
5435 AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments);
5339 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); 5436 AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false);
5340 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); 5437 AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents);
5341 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); 5438 AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery);
@@ -5402,6 +5499,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5402 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest); 5499 AddLocalPacketHandler(PacketType.GroupVoteHistoryRequest, HandleGroupVoteHistoryRequest);
5403 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes); 5500 AddLocalPacketHandler(PacketType.SimWideDeletes, HandleSimWideDeletes);
5404 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard); 5501 AddLocalPacketHandler(PacketType.SendPostcard, HandleSendPostcard);
5502 AddLocalPacketHandler(PacketType.ChangeInventoryItemFlags, HandleChangeInventoryItemFlags);
5405 5503
5406 AddGenericPacketHandler("autopilot", HandleAutopilot); 5504 AddGenericPacketHandler("autopilot", HandleAutopilot);
5407 } 5505 }
@@ -5437,6 +5535,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5437 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5535 (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
5438 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5536 (x.CameraUpAxis != lastarg.CameraUpAxis) ||
5439 (x.ControlFlags != lastarg.ControlFlags) || 5537 (x.ControlFlags != lastarg.ControlFlags) ||
5538 (x.ControlFlags != 0) ||
5440 (x.Far != lastarg.Far) || 5539 (x.Far != lastarg.Far) ||
5441 (x.Flags != lastarg.Flags) || 5540 (x.Flags != lastarg.Flags) ||
5442 (x.State != lastarg.State) || 5541 (x.State != lastarg.State) ||
@@ -6334,6 +6433,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6334 { 6433 {
6335 handlerCompleteMovementToRegion(sender, true); 6434 handlerCompleteMovementToRegion(sender, true);
6336 } 6435 }
6436 else
6437 m_log.Debug("HandleCompleteAgentMovement NULL handler");
6438
6337 handlerCompleteMovementToRegion = null; 6439 handlerCompleteMovementToRegion = null;
6338 6440
6339 return true; 6441 return true;
@@ -6351,7 +6453,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6351 return true; 6453 return true;
6352 } 6454 }
6353 #endregion 6455 #endregion
6354 6456/*
6355 StartAnim handlerStartAnim = null; 6457 StartAnim handlerStartAnim = null;
6356 StopAnim handlerStopAnim = null; 6458 StopAnim handlerStopAnim = null;
6357 6459
@@ -6375,6 +6477,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
6375 } 6477 }
6376 } 6478 }
6377 return true; 6479 return true;
6480*/
6481 ChangeAnim handlerChangeAnim = null;
6482
6483 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
6484 {
6485 handlerChangeAnim = OnChangeAnim;
6486 if (handlerChangeAnim != null)
6487 {
6488 handlerChangeAnim(AgentAni.AnimationList[i].AnimID, AgentAni.AnimationList[i].StartAnim, false);
6489 }
6490 }
6491
6492 handlerChangeAnim = OnChangeAnim;
6493 if (handlerChangeAnim != null)
6494 {
6495 handlerChangeAnim(UUID.Zero, false, true);
6496 }
6497
6498 return true;
6378 } 6499 }
6379 6500
6380 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack) 6501 private bool HandleAgentRequestSit(IClientAPI sender, Packet Pack)
@@ -7000,10 +7121,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7000 // 46,47,48 are special positions within the packet 7121 // 46,47,48 are special positions within the packet
7001 // This may change so perhaps we need a better way 7122 // This may change so perhaps we need a better way
7002 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?) 7123 // of storing this (OMV.FlagUpdatePacket.UsePhysics,etc?)
7003 bool UsePhysics = (data[46] != 0) ? true : false; 7124 /*
7004 bool IsTemporary = (data[47] != 0) ? true : false; 7125 bool UsePhysics = (data[46] != 0) ? true : false;
7005 bool IsPhantom = (data[48] != 0) ? true : false; 7126 bool IsTemporary = (data[47] != 0) ? true : false;
7006 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this); 7127 bool IsPhantom = (data[48] != 0) ? true : false;
7128 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, this);
7129 */
7130 bool UsePhysics = flags.AgentData.UsePhysics;
7131 bool IsPhantom = flags.AgentData.IsPhantom;
7132 bool IsTemporary = flags.AgentData.IsTemporary;
7133 ObjectFlagUpdatePacket.ExtraPhysicsBlock[] blocks = flags.ExtraPhysics;
7134 ExtraPhysicsData physdata = new ExtraPhysicsData();
7135
7136 if (blocks == null || blocks.Length == 0)
7137 {
7138 physdata.PhysShapeType = PhysShapeType.invalid;
7139 }
7140 else
7141 {
7142 ObjectFlagUpdatePacket.ExtraPhysicsBlock phsblock = blocks[0];
7143 physdata.PhysShapeType = (PhysShapeType)phsblock.PhysicsShapeType;
7144 physdata.Bounce = phsblock.Restitution;
7145 physdata.Density = phsblock.Density;
7146 physdata.Friction = phsblock.Friction;
7147 physdata.GravitationModifier = phsblock.GravityMultiplier;
7148 }
7149
7150 handlerUpdatePrimFlags(flags.AgentData.ObjectLocalID, UsePhysics, IsTemporary, IsPhantom, physdata, this);
7007 } 7151 }
7008 return true; 7152 return true;
7009 } 7153 }
@@ -9857,7 +10001,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9857 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID, 10001 handlerUpdateMuteListEntry(this, UpdateMuteListEntry.MuteData.MuteID,
9858 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName), 10002 Utils.BytesToString(UpdateMuteListEntry.MuteData.MuteName),
9859 UpdateMuteListEntry.MuteData.MuteType, 10003 UpdateMuteListEntry.MuteData.MuteType,
9860 UpdateMuteListEntry.AgentData.AgentID); 10004 UpdateMuteListEntry.MuteData.MuteFlags);
9861 return true; 10005 return true;
9862 } 10006 }
9863 return false; 10007 return false;
@@ -9872,8 +10016,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9872 { 10016 {
9873 handlerRemoveMuteListEntry(this, 10017 handlerRemoveMuteListEntry(this,
9874 RemoveMuteListEntry.MuteData.MuteID, 10018 RemoveMuteListEntry.MuteData.MuteID,
9875 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName), 10019 Utils.BytesToString(RemoveMuteListEntry.MuteData.MuteName));
9876 RemoveMuteListEntry.AgentData.AgentID);
9877 return true; 10020 return true;
9878 } 10021 }
9879 return false; 10022 return false;
@@ -9917,10 +10060,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9917 return false; 10060 return false;
9918 } 10061 }
9919 10062
10063 private bool HandleChangeInventoryItemFlags(IClientAPI client, Packet packet)
10064 {
10065 ChangeInventoryItemFlagsPacket ChangeInventoryItemFlags =
10066 (ChangeInventoryItemFlagsPacket)packet;
10067 ChangeInventoryItemFlags handlerChangeInventoryItemFlags = OnChangeInventoryItemFlags;
10068 if (handlerChangeInventoryItemFlags != null)
10069 {
10070 foreach(ChangeInventoryItemFlagsPacket.InventoryDataBlock b in ChangeInventoryItemFlags.InventoryData)
10071 handlerChangeInventoryItemFlags(this, b.ItemID, b.Flags);
10072 return true;
10073 }
10074 return false;
10075 }
10076
9920 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack) 10077 private bool HandleUseCircuitCode(IClientAPI sender, Packet Pack)
9921 { 10078 {
9922 return true; 10079 return true;
9923 } 10080 }
10081
10082 private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack)
10083 {
10084 CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack;
10085
10086 #region Packet Session and User Check
10087 if (m_checkPackets)
10088 {
10089 if (packet.AgentData.SessionID != SessionId ||
10090 packet.AgentData.AgentID != AgentId)
10091 return true;
10092 }
10093 #endregion
10094 MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null;
10095 List<InventoryItemBase> items = new List<InventoryItemBase>();
10096 foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData)
10097 {
10098 InventoryItemBase b = new InventoryItemBase();
10099 b.ID = n.OldItemID;
10100 b.Folder = n.OldFolderID;
10101 items.Add(b);
10102 }
10103
10104 handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy;
10105 if (handlerMoveItemsAndLeaveCopy != null)
10106 {
10107 handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID);
10108 }
10109
10110 return true;
10111 }
9924 10112
9925 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) 10113 private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack)
9926 { 10114 {
@@ -10347,6 +10535,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10347 groupProfileReply.GroupData.MaturePublish = d.MaturePublish; 10535 groupProfileReply.GroupData.MaturePublish = d.MaturePublish;
10348 groupProfileReply.GroupData.OwnerRole = d.OwnerRole; 10536 groupProfileReply.GroupData.OwnerRole = d.OwnerRole;
10349 10537
10538 Scene scene = (Scene)m_scene;
10539 if (scene.Permissions.IsGod(sender.AgentId) && (!sender.IsGroupMember(groupProfileRequest.GroupData.GroupID)))
10540 {
10541 ScenePresence p;
10542 if (scene.TryGetScenePresence(sender.AgentId, out p))
10543 {
10544 if (p.GodLevel >= 200)
10545 {
10546 groupProfileReply.GroupData.OpenEnrollment = true;
10547 groupProfileReply.GroupData.MembershipFee = 0;
10548 }
10549 }
10550 }
10551
10350 OutPacket(groupProfileReply, ThrottleOutPacketType.Task); 10552 OutPacket(groupProfileReply, ThrottleOutPacketType.Task);
10351 } 10553 }
10352 return true; 10554 return true;
@@ -10920,11 +11122,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10920 11122
10921 StartLure handlerStartLure = OnStartLure; 11123 StartLure handlerStartLure = OnStartLure;
10922 if (handlerStartLure != null) 11124 if (handlerStartLure != null)
10923 handlerStartLure(startLureRequest.Info.LureType, 11125 {
10924 Utils.BytesToString( 11126 for (int i = 0 ; i < startLureRequest.TargetData.Length ; i++)
10925 startLureRequest.Info.Message), 11127 {
10926 startLureRequest.TargetData[0].TargetID, 11128 handlerStartLure(startLureRequest.Info.LureType,
10927 this); 11129 Utils.BytesToString(
11130 startLureRequest.Info.Message),
11131 startLureRequest.TargetData[i].TargetID,
11132 this);
11133 }
11134 }
10928 return true; 11135 return true;
10929 } 11136 }
10930 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack) 11137 private bool HandleTeleportLureRequest(IClientAPI sender, Packet Pack)
@@ -11038,10 +11245,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11038 } 11245 }
11039 #endregion 11246 #endregion
11040 11247
11041 ClassifiedDelete handlerClassifiedGodDelete = OnClassifiedGodDelete; 11248 ClassifiedGodDelete handlerClassifiedGodDelete = OnClassifiedGodDelete;
11042 if (handlerClassifiedGodDelete != null) 11249 if (handlerClassifiedGodDelete != null)
11043 handlerClassifiedGodDelete( 11250 handlerClassifiedGodDelete(
11044 classifiedGodDelete.Data.ClassifiedID, 11251 classifiedGodDelete.Data.ClassifiedID,
11252 classifiedGodDelete.Data.QueryID,
11045 this); 11253 this);
11046 return true; 11254 return true;
11047 } 11255 }
@@ -11407,209 +11615,147 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11407 } 11615 }
11408 else 11616 else
11409 { 11617 {
11410// m_log.DebugFormat( 11618 ClientChangeObject updatehandler = onClientChangeObject;
11411// "[CLIENT]: Processing block {0} type {1} for {2} {3}",
11412// i, block.Type, part.Name, part.LocalId);
11413 11619
11414// // Do this once since fetch parts creates a new array. 11620 if (updatehandler != null)
11415// SceneObjectPart[] parts = part.ParentGroup.Parts; 11621 {
11416// for (int j = 0; j < parts.Length; j++) 11622 ObjectChangeData udata = new ObjectChangeData();
11417// {
11418// part.StoreUndoState();
11419// parts[j].IgnoreUndoUpdate = true;
11420// }
11421 11623
11422 UpdatePrimGroupRotation handlerUpdatePrimGroupRotation; 11624 /*ubit from ll JIRA:
11625 * 0x01 position
11626 * 0x02 rotation
11627 * 0x04 scale
11628
11629 * 0x08 LINK_SET
11630 * 0x10 UNIFORM for scale
11631 */
11423 11632
11424 switch (block.Type) 11633 // translate to internal changes
11425 { 11634 // not all cases .. just the ones older code did
11426 case 1:
11427 Vector3 pos1 = new Vector3(block.Data, 0);
11428 11635
11429 UpdateVector handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11636 switch (block.Type)
11430 if (handlerUpdatePrimSinglePosition != null) 11637 {
11431 { 11638 case 1: //change position sp
11432 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11639 udata.position = new Vector3(block.Data, 0);
11433 handlerUpdatePrimSinglePosition(localId, pos1, this);
11434 }
11435 break;
11436 11640
11437 case 2: 11641 udata.change = ObjectChangeType.primP;
11438 Quaternion rot1 = new Quaternion(block.Data, 0, true); 11642 updatehandler(localId, udata, this);
11643 break;
11439 11644
11440 UpdatePrimSingleRotation handlerUpdatePrimSingleRotation = OnUpdatePrimSingleRotation; 11645 case 2: // rotation sp
11441 if (handlerUpdatePrimSingleRotation != null) 11646 udata.rotation = new Quaternion(block.Data, 0, true);
11442 {
11443 // m_log.Info("new tab rotation is " + rot1.X + " , " + rot1.Y + " , " + rot1.Z + " , " + rot1.W);
11444 handlerUpdatePrimSingleRotation(localId, rot1, this);
11445 }
11446 break;
11447 11647
11448 case 3: 11648 udata.change = ObjectChangeType.primR;
11449 Vector3 rotPos = new Vector3(block.Data, 0); 11649 updatehandler(localId, udata, this);
11450 Quaternion rot2 = new Quaternion(block.Data, 12, true); 11650 break;
11451 11651
11452 UpdatePrimSingleRotationPosition handlerUpdatePrimSingleRotationPosition = OnUpdatePrimSingleRotationPosition; 11652 case 3: // position plus rotation
11453 if (handlerUpdatePrimSingleRotationPosition != null) 11653 udata.position = new Vector3(block.Data, 0);
11454 { 11654 udata.rotation = new Quaternion(block.Data, 12, true);
11455 // m_log.Debug("new mouse rotation position is " + rotPos.X + " , " + rotPos.Y + " , " + rotPos.Z);
11456 // m_log.Info("new mouse rotation is " + rot2.X + " , " + rot2.Y + " , " + rot2.Z + " , " + rot2.W);
11457 handlerUpdatePrimSingleRotationPosition(localId, rot2, rotPos, this);
11458 }
11459 break;
11460 11655
11461 case 4: 11656 udata.change = ObjectChangeType.primPR;
11462 case 20: 11657 updatehandler(localId, udata, this);
11463 Vector3 scale4 = new Vector3(block.Data, 0); 11658 break;
11464 11659
11465 UpdateVector handlerUpdatePrimScale = OnUpdatePrimScale; 11660 case 4: // scale sp
11466 if (handlerUpdatePrimScale != null) 11661 udata.scale = new Vector3(block.Data, 0);
11467 { 11662 udata.change = ObjectChangeType.primS;
11468 // m_log.Debug("new scale is " + scale4.X + " , " + scale4.Y + " , " + scale4.Z);
11469 handlerUpdatePrimScale(localId, scale4, this);
11470 }
11471 break;
11472 11663
11473 case 5: 11664 updatehandler(localId, udata, this);
11474 Vector3 scale1 = new Vector3(block.Data, 12); 11665 break;
11475 Vector3 pos11 = new Vector3(block.Data, 0);
11476 11666
11477 handlerUpdatePrimScale = OnUpdatePrimScale; 11667 case 0x14: // uniform scale sp
11478 if (handlerUpdatePrimScale != null) 11668 udata.scale = new Vector3(block.Data, 0);
11479 {
11480 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11481 handlerUpdatePrimScale(localId, scale1, this);
11482 11669
11483 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11670 udata.change = ObjectChangeType.primUS;
11484 if (handlerUpdatePrimSinglePosition != null) 11671 updatehandler(localId, udata, this);
11485 { 11672 break;
11486 handlerUpdatePrimSinglePosition(localId, pos11, this);
11487 }
11488 }
11489 break;
11490 11673
11491 case 9: 11674 case 5: // scale and position sp
11492 Vector3 pos2 = new Vector3(block.Data, 0); 11675 udata.position = new Vector3(block.Data, 0);
11676 udata.scale = new Vector3(block.Data, 12);
11493 11677
11494 UpdateVector handlerUpdateVector = OnUpdatePrimGroupPosition; 11678 udata.change = ObjectChangeType.primPS;
11679 updatehandler(localId, udata, this);
11680 break;
11495 11681
11496 if (handlerUpdateVector != null) 11682 case 0x15: //uniform scale and position
11497 { 11683 udata.position = new Vector3(block.Data, 0);
11498 handlerUpdateVector(localId, pos2, this); 11684 udata.scale = new Vector3(block.Data, 12);
11499 }
11500 break;
11501 11685
11502 case 10: 11686 udata.change = ObjectChangeType.primPUS;
11503 Quaternion rot3 = new Quaternion(block.Data, 0, true); 11687 updatehandler(localId, udata, this);
11688 break;
11504 11689
11505 UpdatePrimRotation handlerUpdatePrimRotation = OnUpdatePrimGroupRotation; 11690 // now group related (bit 4)
11506 if (handlerUpdatePrimRotation != null) 11691 case 9: //( 8 + 1 )group position
11507 { 11692 udata.position = new Vector3(block.Data, 0);
11508 // Console.WriteLine("new rotation is " + rot3.X + " , " + rot3.Y + " , " + rot3.Z + " , " + rot3.W);
11509 handlerUpdatePrimRotation(localId, rot3, this);
11510 }
11511 break;
11512 11693
11513 case 11: 11694 udata.change = ObjectChangeType.groupP;
11514 Vector3 pos3 = new Vector3(block.Data, 0); 11695 updatehandler(localId, udata, this);
11515 Quaternion rot4 = new Quaternion(block.Data, 12, true); 11696 break;
11516 11697
11517 handlerUpdatePrimGroupRotation = OnUpdatePrimGroupMouseRotation; 11698 case 0x0A: // (8 + 2) group rotation
11518 if (handlerUpdatePrimGroupRotation != null) 11699 udata.rotation = new Quaternion(block.Data, 0, true);
11519 {
11520 // m_log.Debug("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z);
11521 // m_log.Debug("new group mouse rotation is " + rot4.X + " , " + rot4.Y + " , " + rot4.Z + " , " + rot4.W);
11522 handlerUpdatePrimGroupRotation(localId, pos3, rot4, this);
11523 }
11524 break;
11525 case 12:
11526 case 28:
11527 Vector3 scale7 = new Vector3(block.Data, 0);
11528 11700
11529 UpdateVector handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11701 udata.change = ObjectChangeType.groupR;
11530 if (handlerUpdatePrimGroupScale != null) 11702 updatehandler(localId, udata, this);
11531 { 11703 break;
11532 // m_log.Debug("new scale is " + scale7.X + " , " + scale7.Y + " , " + scale7.Z);
11533 handlerUpdatePrimGroupScale(localId, scale7, this);
11534 }
11535 break;
11536 11704
11537 case 13: 11705 case 0x0B: //( 8 + 2 + 1) group rotation and position
11538 Vector3 scale2 = new Vector3(block.Data, 12); 11706 udata.position = new Vector3(block.Data, 0);
11539 Vector3 pos4 = new Vector3(block.Data, 0); 11707 udata.rotation = new Quaternion(block.Data, 12, true);
11540 11708
11541 handlerUpdatePrimScale = OnUpdatePrimScale; 11709 udata.change = ObjectChangeType.groupPR;
11542 if (handlerUpdatePrimScale != null) 11710 updatehandler(localId, udata, this);
11543 { 11711 break;
11544 //m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11545 handlerUpdatePrimScale(localId, scale2, this);
11546 11712
11547 // Change the position based on scale (for bug number 246) 11713 case 0x0C: // (8 + 4) group scale
11548 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11714 // only afects root prim and only sent by viewer editor object tab scaling
11549 // m_log.Debug("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); 11715 // mouse edition only allows uniform scaling
11550 if (handlerUpdatePrimSinglePosition != null) 11716 // SL MAY CHANGE THIS in viewers
11551 {
11552 handlerUpdatePrimSinglePosition(localId, pos4, this);
11553 }
11554 }
11555 break;
11556 11717
11557 case 29: 11718 udata.scale = new Vector3(block.Data, 0);
11558 Vector3 scale5 = new Vector3(block.Data, 12);
11559 Vector3 pos5 = new Vector3(block.Data, 0);
11560 11719
11561 handlerUpdatePrimGroupScale = OnUpdatePrimGroupScale; 11720 udata.change = ObjectChangeType.groupS;
11562 if (handlerUpdatePrimGroupScale != null) 11721 updatehandler(localId, udata, this);
11563 {
11564 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z);
11565 part.StoreUndoState(true);
11566 part.IgnoreUndoUpdate = true;
11567 handlerUpdatePrimGroupScale(localId, scale5, this);
11568 handlerUpdateVector = OnUpdatePrimGroupPosition;
11569 11722
11570 if (handlerUpdateVector != null) 11723 break;
11571 {
11572 handlerUpdateVector(localId, pos5, this);
11573 }
11574 11724
11575 part.IgnoreUndoUpdate = false; 11725 case 0x0D: //(8 + 4 + 1) group scale and position
11576 } 11726 // exception as above
11577 11727
11578 break; 11728 udata.position = new Vector3(block.Data, 0);
11729 udata.scale = new Vector3(block.Data, 12);
11579 11730
11580 case 21: 11731 udata.change = ObjectChangeType.groupPS;
11581 Vector3 scale6 = new Vector3(block.Data, 12); 11732 updatehandler(localId, udata, this);
11582 Vector3 pos6 = new Vector3(block.Data, 0); 11733 break;
11583 11734
11584 handlerUpdatePrimScale = OnUpdatePrimScale; 11735 case 0x1C: // (0x10 + 8 + 4 ) group scale UNIFORM
11585 if (handlerUpdatePrimScale != null) 11736 udata.scale = new Vector3(block.Data, 0);
11586 {
11587 part.StoreUndoState(false);
11588 part.IgnoreUndoUpdate = true;
11589 11737
11590 // m_log.Debug("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); 11738 udata.change = ObjectChangeType.groupUS;
11591 handlerUpdatePrimScale(localId, scale6, this); 11739 updatehandler(localId, udata, this);
11592 handlerUpdatePrimSinglePosition = OnUpdatePrimSinglePosition; 11740 break;
11593 if (handlerUpdatePrimSinglePosition != null)
11594 {
11595 handlerUpdatePrimSinglePosition(localId, pos6, this);
11596 }
11597 11741
11598 part.IgnoreUndoUpdate = false; 11742 case 0x1D: // (UNIFORM + GROUP + SCALE + POS)
11599 } 11743 udata.position = new Vector3(block.Data, 0);
11600 break; 11744 udata.scale = new Vector3(block.Data, 12);
11601 11745
11602 default: 11746 udata.change = ObjectChangeType.groupPUS;
11603 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type)); 11747 updatehandler(localId, udata, this);
11604 break; 11748 break;
11749
11750 default:
11751 m_log.Debug("[CLIENT]: MultipleObjUpdate recieved an unknown packet type: " + (block.Type));
11752 break;
11753 }
11605 } 11754 }
11606 11755
11607// for (int j = 0; j < parts.Length; j++)
11608// parts[j].IgnoreUndoUpdate = false;
11609 } 11756 }
11610 } 11757 }
11611 } 11758 }
11612
11613 return true; 11759 return true;
11614 } 11760 }
11615 11761
@@ -12059,7 +12205,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12059// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}", 12205// "[LLCLIENTVIEW]: Received transfer request for {0} in {1} type {2} by {3}",
12060// requestID, taskID, (SourceType)sourceType, Name); 12206// requestID, taskID, (SourceType)sourceType, Name);
12061 12207
12208
12209 //Note, the bool returned from the below function is useless since it is always false.
12062 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); 12210 m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived);
12211
12063 } 12212 }
12064 12213
12065 /// <summary> 12214 /// <summary>
@@ -12125,7 +12274,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12125 /// <returns></returns> 12274 /// <returns></returns>
12126 private static int CalculateNumPackets(byte[] data) 12275 private static int CalculateNumPackets(byte[] data)
12127 { 12276 {
12128 const uint m_maxPacketSize = 600; 12277// const uint m_maxPacketSize = 600;
12278 uint m_maxPacketSize = MaxTransferBytesPerPacket;
12129 int numPackets = 1; 12279 int numPackets = 1;
12130 12280
12131 if (data == null) 12281 if (data == null)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index 8963756..c472176 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
@@ -440,6 +441,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
440 if (category >= 0 && category < m_packetOutboxes.Length) 441 if (category >= 0 && category < m_packetOutboxes.Length)
441 { 442 {
442 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category]; 443 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue = m_packetOutboxes[category];
444
445 if (m_deliverPackets == false)
446 {
447 queue.Enqueue(packet);
448 return true;
449 }
450
443 TokenBucket bucket = m_throttleCategories[category]; 451 TokenBucket bucket = m_throttleCategories[category];
444 452
445 // Don't send this packet if there is already a packet waiting in the queue 453 // Don't send this packet if there is already a packet waiting in the queue
@@ -489,7 +497,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
489 /// <returns>True if any packets were sent, otherwise false</returns> 497 /// <returns>True if any packets were sent, otherwise false</returns>
490 public bool DequeueOutgoing() 498 public bool DequeueOutgoing()
491 { 499 {
492 OutgoingPacket packet; 500 if (m_deliverPackets == false) return false;
501
502 OutgoingPacket packet = null;
493 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue; 503 OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
494 TokenBucket bucket; 504 TokenBucket bucket;
495 bool packetSent = false; 505 bool packetSent = false;
@@ -521,32 +531,49 @@ namespace OpenSim.Region.ClientStack.LindenUDP
521 // No dequeued packet waiting to be sent, try to pull one off 531 // No dequeued packet waiting to be sent, try to pull one off
522 // this queue 532 // this queue
523 queue = m_packetOutboxes[i]; 533 queue = m_packetOutboxes[i];
524 if (queue.Dequeue(out packet)) 534 if (queue != null)
525 { 535 {
526 // A packet was pulled off the queue. See if we have 536 bool success = false;
527 // enough tokens in the bucket to send it out 537 try
528 if (bucket.RemoveTokens(packet.Buffer.DataLength))
529 { 538 {
530 // Send the packet 539 success = queue.Dequeue(out packet);
531 m_udpServer.SendPacketFinal(packet);
532 packetSent = true;
533 } 540 }
534 else 541 catch
535 { 542 {
536 // Save the dequeued packet for the next iteration 543 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
537 m_nextPackets[i] = packet;
538 } 544 }
539 545 if (success)
540 // If the queue is empty after this dequeue, fire the queue 546 {
541 // empty callback now so it has a chance to fill before we 547 // A packet was pulled off the queue. See if we have
542 // get back here 548 // enough tokens in the bucket to send it out
543 if (queue.Count == 0) 549 if (bucket.RemoveTokens(packet.Buffer.DataLength))
550 {
551 // Send the packet
552 m_udpServer.SendPacketFinal(packet);
553 packetSent = true;
554 }
555 else
556 {
557 // Save the dequeued packet for the next iteration
558 m_nextPackets[i] = packet;
559 }
560
561 // If the queue is empty after this dequeue, fire the queue
562 // empty callback now so it has a chance to fill before we
563 // get back here
564 if (queue.Count == 0)
565 emptyCategories |= CategoryToFlag(i);
566 }
567 else
568 {
569 // No packets in this queue. Fire the queue empty callback
570 // if it has not been called recently
544 emptyCategories |= CategoryToFlag(i); 571 emptyCategories |= CategoryToFlag(i);
572 }
545 } 573 }
546 else 574 else
547 { 575 {
548 // No packets in this queue. Fire the queue empty callback 576 m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
549 // if it has not been called recently
550 emptyCategories |= CategoryToFlag(i); 577 emptyCategories |= CategoryToFlag(i);
551 } 578 }
552 } 579 }
@@ -704,4 +731,4 @@ namespace OpenSim.Region.ClientStack.LindenUDP
704 } 731 }
705 } 732 }
706 } 733 }
707} \ No newline at end of file 734}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 55780d6..fb73e1d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -155,6 +155,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
155 /// <summary>Flag to signal when clients should send pings</summary> 155 /// <summary>Flag to signal when clients should send pings</summary>
156 protected bool m_sendPing; 156 protected bool m_sendPing;
157 157
158 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
159
158 private int m_defaultRTO = 0; 160 private int m_defaultRTO = 0;
159 private int m_maxRTO = 0; 161 private int m_maxRTO = 0;
160 private int m_ackTimeout = 0; 162 private int m_ackTimeout = 0;
@@ -765,19 +767,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
765 767
766 #region Packet to Client Mapping 768 #region Packet to Client Mapping
767 769
768 // UseCircuitCode handling 770 // If there is already a client for this endpoint, don't process UseCircuitCode
769 if (packet.Type == PacketType.UseCircuitCode) 771 IClientAPI client = null;
772 if (!m_scene.TryGetClient(address, out client))
770 { 773 {
771 object[] array = new object[] { buffer, packet }; 774 // UseCircuitCode handling
775 if (packet.Type == PacketType.UseCircuitCode)
776 {
777 // And if there is a UseCircuitCode pending, also drop it
778 lock (m_pendingCache)
779 {
780 if (m_pendingCache.Contains(address))
781 return;
772 782
773 Util.FireAndForget(HandleUseCircuitCode, array); 783 m_pendingCache.AddOrUpdate(address, new Queue<UDPPacketBuffer>(), 60);
784 }
774 785
775 return; 786 object[] array = new object[] { buffer, packet };
787
788 Util.FireAndForget(HandleUseCircuitCode, array);
789
790 return;
791 }
792 }
793
794 // If this is a pending connection, enqueue, don't process yet
795 lock (m_pendingCache)
796 {
797 Queue<UDPPacketBuffer> queue;
798 if (m_pendingCache.TryGetValue(address, out queue))
799 {
800 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
801 queue.Enqueue(buffer);
802 return;
803 }
776 } 804 }
777 805
778 // Determine which agent this packet came from 806 // Determine which agent this packet came from
779 IClientAPI client; 807 if (client == null || !(client is LLClientView))
780 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
781 { 808 {
782 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 809 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
783 return; 810 return;
@@ -786,7 +813,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
786 udpClient = ((LLClientView)client).UDPClient; 813 udpClient = ((LLClientView)client).UDPClient;
787 814
788 if (!udpClient.IsConnected) 815 if (!udpClient.IsConnected)
816 {
817// m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
789 return; 818 return;
819 }
790 820
791 #endregion Packet to Client Mapping 821 #endregion Packet to Client Mapping
792 822
@@ -1011,6 +1041,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1011 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1041 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1012 if (client != null) 1042 if (client != null)
1013 client.SceneAgent.SendInitialDataToMe(); 1043 client.SceneAgent.SendInitialDataToMe();
1044
1045 // Now we know we can handle more data
1046 Thread.Sleep(200);
1047
1048 // Obtain the queue and remove it from the cache
1049 Queue<UDPPacketBuffer> queue = null;
1050
1051 lock (m_pendingCache)
1052 {
1053 if (!m_pendingCache.TryGetValue(remoteEndPoint, out queue))
1054 {
1055 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1056 return;
1057 }
1058 m_pendingCache.Remove(remoteEndPoint);
1059 }
1060
1061 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1062
1063 // Reinject queued packets
1064 while(queue.Count > 0)
1065 {
1066 UDPPacketBuffer buf = queue.Dequeue();
1067 PacketReceived(buf);
1068 }
1069 queue = null;
1014 } 1070 }
1015 else 1071 else
1016 { 1072 {
@@ -1018,6 +1074,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1018 m_log.WarnFormat( 1074 m_log.WarnFormat(
1019 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1075 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1020 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); 1076 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
1077 lock (m_pendingCache)
1078 m_pendingCache.Remove(remoteEndPoint);
1021 } 1079 }
1022 1080
1023 // m_log.DebugFormat( 1081 // m_log.DebugFormat(
@@ -1136,7 +1194,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1136 if (!client.SceneAgent.IsChildAgent) 1194 if (!client.SceneAgent.IsChildAgent)
1137 client.Kick("Simulator logged you out due to connection timeout"); 1195 client.Kick("Simulator logged you out due to connection timeout");
1138 1196
1139 client.CloseWithoutChecks(); 1197 client.CloseWithoutChecks(true);
1140 } 1198 }
1141 } 1199 }
1142 1200
@@ -1148,6 +1206,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1148 1206
1149 while (base.IsRunning) 1207 while (base.IsRunning)
1150 { 1208 {
1209 m_scene.ThreadAlive(1);
1151 try 1210 try
1152 { 1211 {
1153 IncomingPacket incomingPacket = null; 1212 IncomingPacket incomingPacket = null;
@@ -1190,6 +1249,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1190 1249
1191 while (base.IsRunning) 1250 while (base.IsRunning)
1192 { 1251 {
1252 m_scene.ThreadAlive(2);
1193 try 1253 try
1194 { 1254 {
1195 m_packetSent = false; 1255 m_packetSent = false;
@@ -1455,8 +1515,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1455 if (!client.IsLoggingOut) 1515 if (!client.IsLoggingOut)
1456 { 1516 {
1457 client.IsLoggingOut = true; 1517 client.IsLoggingOut = true;
1458 client.Close(); 1518 client.Close(false, false);
1459 } 1519 }
1460 } 1520 }
1461 } 1521 }
1462} \ No newline at end of file 1522}
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,