diff options
Diffstat (limited to 'OpenSim/Region')
30 files changed, 1383 insertions, 1134 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 05a2a63..b027882 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -51,6 +51,44 @@ using Nini.Config; | |||
51 | 51 | ||
52 | namespace OpenSim.Region.ClientStack.LindenUDP | 52 | namespace OpenSim.Region.ClientStack.LindenUDP |
53 | { | 53 | { |
54 | #region Enums | ||
55 | |||
56 | /// <summary> | ||
57 | /// Specifies the fields that have been changed when sending a prim or | ||
58 | /// avatar update | ||
59 | /// </summary> | ||
60 | [Flags] | ||
61 | public enum PrimUpdateFlags : uint | ||
62 | { | ||
63 | None = 0, | ||
64 | AttachmentPoint = 1 << 0, | ||
65 | Material = 1 << 1, | ||
66 | ClickAction = 1 << 2, | ||
67 | Scale = 1 << 3, | ||
68 | ParentID = 1 << 4, | ||
69 | PrimFlags = 1 << 5, | ||
70 | PrimData = 1 << 6, | ||
71 | MediaURL = 1 << 7, | ||
72 | ScratchPad = 1 << 8, | ||
73 | Textures = 1 << 9, | ||
74 | TextureAnim = 1 << 10, | ||
75 | NameValue = 1 << 11, | ||
76 | Position = 1 << 12, | ||
77 | Rotation = 1 << 13, | ||
78 | Velocity = 1 << 14, | ||
79 | Acceleration = 1 << 15, | ||
80 | AngularVelocity = 1 << 16, | ||
81 | CollisionPlane = 1 << 17, | ||
82 | Text = 1 << 18, | ||
83 | Particles = 1 << 19, | ||
84 | ExtraData = 1 << 20, | ||
85 | Sound = 1 << 21, | ||
86 | Joint = 1 << 22, | ||
87 | FullUpdate = UInt32.MaxValue | ||
88 | } | ||
89 | |||
90 | #endregion Enums | ||
91 | |||
54 | public delegate bool PacketMethod(IClientAPI simClient, Packet packet); | 92 | public delegate bool PacketMethod(IClientAPI simClient, Packet packet); |
55 | 93 | ||
56 | /// <summary> | 94 | /// <summary> |
@@ -257,6 +295,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
257 | public event MuteListRequest OnMuteListRequest; | 295 | public event MuteListRequest OnMuteListRequest; |
258 | public event AvatarInterestUpdate OnAvatarInterestUpdate; | 296 | public event AvatarInterestUpdate OnAvatarInterestUpdate; |
259 | public event PlacesQuery OnPlacesQuery; | 297 | public event PlacesQuery OnPlacesQuery; |
298 | public event AgentFOV OnAgentFOV; | ||
260 | 299 | ||
261 | #endregion Events | 300 | #endregion Events |
262 | 301 | ||
@@ -282,12 +321,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
282 | private readonly IGroupsModule m_GroupsModule; | 321 | private readonly IGroupsModule m_GroupsModule; |
283 | 322 | ||
284 | private int m_cachedTextureSerial; | 323 | private int m_cachedTextureSerial; |
285 | private Timer m_avatarTerseUpdateTimer; | 324 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates; |
286 | private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 325 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates; |
287 | private Timer m_primTerseUpdateTimer; | 326 | private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates; |
288 | private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
289 | private Timer m_primFullUpdateTimer; | ||
290 | private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = new List<ObjectUpdatePacket.ObjectDataBlock>(); | ||
291 | private int m_moneyBalance; | 327 | private int m_moneyBalance; |
292 | private int m_animationSequenceNumber = 1; | 328 | private int m_animationSequenceNumber = 1; |
293 | private bool m_SendLogoutPacketWhenClosing = true; | 329 | private bool m_SendLogoutPacketWhenClosing = true; |
@@ -296,26 +332,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
296 | 332 | ||
297 | protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); | 333 | protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); |
298 | protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers | 334 | protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers |
299 | protected IScene m_scene; | 335 | protected Scene m_scene; |
300 | protected LLImageManager m_imageManager; | 336 | protected LLImageManager m_imageManager; |
301 | protected string m_firstName; | 337 | protected string m_firstName; |
302 | protected string m_lastName; | 338 | protected string m_lastName; |
303 | protected Thread m_clientThread; | 339 | protected Thread m_clientThread; |
304 | protected Vector3 m_startpos; | 340 | protected Vector3 m_startpos; |
305 | protected EndPoint m_userEndPoint; | 341 | protected EndPoint m_userEndPoint; |
306 | protected UUID m_activeGroupID = UUID.Zero; | 342 | protected UUID m_activeGroupID; |
307 | protected string m_activeGroupName = String.Empty; | 343 | protected string m_activeGroupName = String.Empty; |
308 | protected ulong m_activeGroupPowers; | 344 | protected ulong m_activeGroupPowers; |
309 | protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>(); | 345 | protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>(); |
310 | protected int m_terrainCheckerCount; | 346 | protected int m_terrainCheckerCount; |
311 | 347 | protected uint m_agentFOVCounter; | |
312 | // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet | 348 | |
313 | protected int m_primTerseUpdatesPerPacket = 10; | 349 | // These numbers are guesses at a decent tradeoff between responsiveness |
314 | protected int m_primFullUpdatesPerPacket = 14; | 350 | // of the interest list and throughput. Lower is more responsive, higher |
315 | protected int m_primTerseUpdateRate = 10; | 351 | // is better throughput |
316 | protected int m_primFullUpdateRate = 14; | 352 | protected int m_primTerseUpdatesPerPacket = 25; |
317 | protected int m_avatarTerseUpdateRate = 50; | 353 | protected int m_primFullUpdatesPerPacket = 100; |
318 | protected int m_avatarTerseUpdatesPerPacket = 5; | 354 | protected int m_avatarTerseUpdatesPerPacket = 10; |
319 | /// <summary>Number of texture packets to put on the queue each time the | 355 | /// <summary>Number of texture packets to put on the queue each time the |
320 | /// OnQueueEmpty event is triggered for the texture category</summary> | 356 | /// OnQueueEmpty event is triggered for the texture category</summary> |
321 | protected int m_textureSendLimit = 20; | 357 | protected int m_textureSendLimit = 20; |
@@ -369,21 +405,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
369 | /// <summary> | 405 | /// <summary> |
370 | /// Constructor | 406 | /// Constructor |
371 | /// </summary> | 407 | /// </summary> |
372 | public LLClientView(EndPoint remoteEP, IScene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, | 408 | public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, |
373 | UUID agentId, UUID sessionId, uint circuitCode) | 409 | UUID agentId, UUID sessionId, uint circuitCode) |
374 | { | 410 | { |
375 | RegisterInterface<IClientIM>(this); | 411 | RegisterInterface<IClientIM>(this); |
376 | RegisterInterface<IClientChat>(this); | 412 | RegisterInterface<IClientChat>(this); |
377 | RegisterInterface<IClientIPEndpoint>(this); | 413 | RegisterInterface<IClientIPEndpoint>(this); |
378 | 414 | ||
379 | InitDefaultAnimations(); | 415 | InitDefaultAnimations(); |
380 | 416 | ||
381 | m_scene = scene; | 417 | m_scene = scene; |
418 | |||
419 | m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
420 | m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
421 | m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count); | ||
422 | |||
382 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); | 423 | m_assetService = m_scene.RequestModuleInterface<IAssetService>(); |
383 | m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); | 424 | m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); |
384 | m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); | 425 | m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); |
385 | m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>()); | 426 | m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>()); |
386 | m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); | 427 | m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion()); |
387 | m_agentId = agentId; | 428 | m_agentId = agentId; |
388 | m_sessionId = sessionId; | 429 | m_sessionId = sessionId; |
389 | m_secureSessionId = sessionInfo.LoginInfo.SecureSession; | 430 | m_secureSessionId = sessionInfo.LoginInfo.SecureSession; |
@@ -438,25 +479,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
438 | // Remove ourselves from the scene | 479 | // Remove ourselves from the scene |
439 | m_scene.RemoveClient(AgentId); | 480 | m_scene.RemoveClient(AgentId); |
440 | 481 | ||
441 | // Shut down timers. Thread Context of this method is murky. Lock all timers | ||
442 | if (m_avatarTerseUpdateTimer.Enabled) | ||
443 | lock (m_avatarTerseUpdateTimer) | ||
444 | m_avatarTerseUpdateTimer.Stop(); | ||
445 | if (m_primTerseUpdateTimer.Enabled) | ||
446 | lock (m_primTerseUpdateTimer) | ||
447 | m_primTerseUpdateTimer.Stop(); | ||
448 | if (m_primFullUpdateTimer.Enabled) | ||
449 | lock (m_primFullUpdateTimer) | ||
450 | m_primFullUpdateTimer.Stop(); | ||
451 | |||
452 | // We can't reach into other scenes and close the connection | 482 | // We can't reach into other scenes and close the connection |
453 | // We need to do this over grid communications | 483 | // We need to do this over grid communications |
454 | //m_scene.CloseAllAgents(CircuitCode); | 484 | //m_scene.CloseAllAgents(CircuitCode); |
455 | 485 | ||
456 | m_avatarTerseUpdateTimer.Dispose(); | ||
457 | m_primTerseUpdateTimer.Dispose(); | ||
458 | m_primFullUpdateTimer.Dispose(); | ||
459 | |||
460 | // Disable UDP handling for this client | 486 | // Disable UDP handling for this client |
461 | m_udpClient.Shutdown(); | 487 | m_udpClient.Shutdown(); |
462 | 488 | ||
@@ -474,7 +500,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
474 | kupack.UserInfo.SessionID = SessionId; | 500 | kupack.UserInfo.SessionID = SessionId; |
475 | kupack.TargetBlock.TargetIP = 0; | 501 | kupack.TargetBlock.TargetIP = 0; |
476 | kupack.TargetBlock.TargetPort = 0; | 502 | kupack.TargetBlock.TargetPort = 0; |
477 | kupack.UserInfo.Reason = Utils.StringToBytes(message); | 503 | kupack.UserInfo.Reason = Util.StringToBytes256(message); |
478 | OutPacket(kupack, ThrottleOutPacketType.Task); | 504 | OutPacket(kupack, ThrottleOutPacketType.Task); |
479 | // You must sleep here or users get no message! | 505 | // You must sleep here or users get no message! |
480 | Thread.Sleep(500); | 506 | Thread.Sleep(500); |
@@ -483,18 +509,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
483 | 509 | ||
484 | public void Stop() | 510 | public void Stop() |
485 | { | 511 | { |
486 | // Shut down timers. Thread Context is Murky, lock all timers! | ||
487 | if (m_avatarTerseUpdateTimer.Enabled) | ||
488 | lock (m_avatarTerseUpdateTimer) | ||
489 | m_avatarTerseUpdateTimer.Stop(); | ||
490 | |||
491 | if (m_primTerseUpdateTimer.Enabled) | ||
492 | lock (m_primTerseUpdateTimer) | ||
493 | m_primTerseUpdateTimer.Stop(); | ||
494 | 512 | ||
495 | if (m_primFullUpdateTimer.Enabled) | ||
496 | lock (m_primFullUpdateTimer) | ||
497 | m_primFullUpdateTimer.Stop(); | ||
498 | } | 513 | } |
499 | 514 | ||
500 | #endregion Client Methods | 515 | #endregion Client Methods |
@@ -590,18 +605,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
590 | 605 | ||
591 | public virtual void Start() | 606 | public virtual void Start() |
592 | { | 607 | { |
593 | m_avatarTerseUpdateTimer = new Timer(m_avatarTerseUpdateRate); | ||
594 | m_avatarTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessAvatarTerseUpdates); | ||
595 | m_avatarTerseUpdateTimer.AutoReset = false; | ||
596 | |||
597 | m_primTerseUpdateTimer = new Timer(m_primTerseUpdateRate); | ||
598 | m_primTerseUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimTerseUpdates); | ||
599 | m_primTerseUpdateTimer.AutoReset = false; | ||
600 | |||
601 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); | ||
602 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); | ||
603 | m_primFullUpdateTimer.AutoReset = false; | ||
604 | |||
605 | m_scene.AddNewClient(this); | 608 | m_scene.AddNewClient(this); |
606 | 609 | ||
607 | RefreshGroupMembership(); | 610 | RefreshGroupMembership(); |
@@ -642,7 +645,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
642 | handshake.RegionInfo.WaterHeight = args.waterHeight; | 645 | handshake.RegionInfo.WaterHeight = args.waterHeight; |
643 | 646 | ||
644 | handshake.RegionInfo.RegionFlags = args.regionFlags; | 647 | handshake.RegionInfo.RegionFlags = args.regionFlags; |
645 | handshake.RegionInfo.SimName = Utils.StringToBytes(args.regionName); | 648 | handshake.RegionInfo.SimName = Util.StringToBytes256(args.regionName); |
646 | handshake.RegionInfo.SimOwner = args.SimOwner; | 649 | handshake.RegionInfo.SimOwner = args.SimOwner; |
647 | handshake.RegionInfo.TerrainBase0 = args.terrainBase0; | 650 | handshake.RegionInfo.TerrainBase0 = args.terrainBase0; |
648 | handshake.RegionInfo.TerrainBase1 = args.terrainBase1; | 651 | handshake.RegionInfo.TerrainBase1 = args.terrainBase1; |
@@ -698,11 +701,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
698 | { | 701 | { |
699 | ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); | 702 | ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); |
700 | reply.ChatData.Audible = audible; | 703 | reply.ChatData.Audible = audible; |
701 | reply.ChatData.Message = Utils.StringToBytes(message); | 704 | reply.ChatData.Message = Util.StringToBytes1024(message); |
702 | reply.ChatData.ChatType = type; | 705 | reply.ChatData.ChatType = type; |
703 | reply.ChatData.SourceType = source; | 706 | reply.ChatData.SourceType = source; |
704 | reply.ChatData.Position = fromPos; | 707 | reply.ChatData.Position = fromPos; |
705 | reply.ChatData.FromName = Utils.StringToBytes(fromName); | 708 | reply.ChatData.FromName = Util.StringToBytes256(fromName); |
706 | reply.ChatData.OwnerID = fromAgentID; | 709 | reply.ChatData.OwnerID = fromAgentID; |
707 | reply.ChatData.SourceID = fromAgentID; | 710 | reply.ChatData.SourceID = fromAgentID; |
708 | 711 | ||
@@ -723,7 +726,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
723 | 726 | ||
724 | msg.AgentData.AgentID = new UUID(im.fromAgentID); | 727 | msg.AgentData.AgentID = new UUID(im.fromAgentID); |
725 | msg.AgentData.SessionID = UUID.Zero; | 728 | msg.AgentData.SessionID = UUID.Zero; |
726 | msg.MessageBlock.FromAgentName = Utils.StringToBytes(im.fromAgentName); | 729 | msg.MessageBlock.FromAgentName = Util.StringToBytes256(im.fromAgentName); |
727 | msg.MessageBlock.Dialog = im.dialog; | 730 | msg.MessageBlock.Dialog = im.dialog; |
728 | msg.MessageBlock.FromGroup = im.fromGroup; | 731 | msg.MessageBlock.FromGroup = im.fromGroup; |
729 | if (im.imSessionID == UUID.Zero.Guid) | 732 | if (im.imSessionID == UUID.Zero.Guid) |
@@ -736,12 +739,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
736 | msg.MessageBlock.RegionID = new UUID(im.RegionID); | 739 | msg.MessageBlock.RegionID = new UUID(im.RegionID); |
737 | msg.MessageBlock.Timestamp = im.timestamp; | 740 | msg.MessageBlock.Timestamp = im.timestamp; |
738 | msg.MessageBlock.ToAgentID = new UUID(im.toAgentID); | 741 | msg.MessageBlock.ToAgentID = new UUID(im.toAgentID); |
739 | // Cap the message length at 1099. There is a limit in ImprovedInstantMessagePacket | 742 | msg.MessageBlock.Message = Util.StringToBytes1024(im.message); |
740 | // the limit is 1100 but a 0 byte gets added to mark the end of the string | ||
741 | if (im.message != null && im.message.Length > 1099) | ||
742 | msg.MessageBlock.Message = Utils.StringToBytes(im.message.Substring(0, 1099)); | ||
743 | else | ||
744 | msg.MessageBlock.Message = Utils.StringToBytes(im.message); | ||
745 | msg.MessageBlock.BinaryBucket = im.binaryBucket; | 743 | msg.MessageBlock.BinaryBucket = im.binaryBucket; |
746 | 744 | ||
747 | if (im.message.StartsWith("[grouptest]")) | 745 | if (im.message.StartsWith("[grouptest]")) |
@@ -759,7 +757,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
759 | eq.ChatterboxInvitation( | 757 | eq.ChatterboxInvitation( |
760 | new UUID("00000000-68f9-1111-024e-222222111123"), | 758 | new UUID("00000000-68f9-1111-024e-222222111123"), |
761 | "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0, | 759 | "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0, |
762 | false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Utils.StringToBytes("OpenSimulator Testing")); | 760 | false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing")); |
763 | 761 | ||
764 | eq.ChatterBoxSessionAgentListUpdates( | 762 | eq.ChatterBoxSessionAgentListUpdates( |
765 | new UUID("00000000-68f9-1111-024e-222222111123"), | 763 | new UUID("00000000-68f9-1111-024e-222222111123"), |
@@ -776,13 +774,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
776 | public void SendGenericMessage(string method, List<string> message) | 774 | public void SendGenericMessage(string method, List<string> message) |
777 | { | 775 | { |
778 | GenericMessagePacket gmp = new GenericMessagePacket(); | 776 | GenericMessagePacket gmp = new GenericMessagePacket(); |
779 | gmp.MethodData.Method = Utils.StringToBytes(method); | 777 | gmp.MethodData.Method = Util.StringToBytes256(method); |
780 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; | 778 | gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; |
781 | int i = 0; | 779 | int i = 0; |
782 | foreach (string val in message) | 780 | foreach (string val in message) |
783 | { | 781 | { |
784 | gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); | 782 | gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); |
785 | gmp.ParamList[i++].Parameter = Utils.StringToBytes(val); | 783 | gmp.ParamList[i++].Parameter = Util.StringToBytes256(val); |
786 | } | 784 | } |
787 | OutPacket(gmp, ThrottleOutPacketType.Task); | 785 | OutPacket(gmp, ThrottleOutPacketType.Task); |
788 | } | 786 | } |
@@ -1046,7 +1044,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1046 | newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; | 1044 | newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; |
1047 | newSimPack.RegionData.SimIP += (uint)byteIP[0]; | 1045 | newSimPack.RegionData.SimIP += (uint)byteIP[0]; |
1048 | newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port; | 1046 | newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port; |
1049 | newSimPack.RegionData.SeedCapability = Utils.StringToBytes(capsURL); | 1047 | newSimPack.RegionData.SeedCapability = Util.StringToBytes256(capsURL); |
1050 | 1048 | ||
1051 | // Hack to get this out immediately and skip throttles | 1049 | // Hack to get this out immediately and skip throttles |
1052 | OutPacket(newSimPack, ThrottleOutPacketType.Unknown); | 1050 | OutPacket(newSimPack, ThrottleOutPacketType.Unknown); |
@@ -1124,7 +1122,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1124 | teleport.Info.RegionHandle = regionHandle; | 1122 | teleport.Info.RegionHandle = regionHandle; |
1125 | teleport.Info.SimAccess = simAccess; | 1123 | teleport.Info.SimAccess = simAccess; |
1126 | 1124 | ||
1127 | teleport.Info.SeedCapability = Utils.StringToBytes(capsURL); | 1125 | teleport.Info.SeedCapability = Util.StringToBytes256(capsURL); |
1128 | 1126 | ||
1129 | IPAddress oIP = newRegionEndPoint.Address; | 1127 | IPAddress oIP = newRegionEndPoint.Address; |
1130 | byte[] byteIP = oIP.GetAddressBytes(); | 1128 | byte[] byteIP = oIP.GetAddressBytes(); |
@@ -1149,7 +1147,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1149 | { | 1147 | { |
1150 | TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed); | 1148 | TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed); |
1151 | tpFailed.Info.AgentID = AgentId; | 1149 | tpFailed.Info.AgentID = AgentId; |
1152 | tpFailed.Info.Reason = Utils.StringToBytes(reason); | 1150 | tpFailed.Info.Reason = Util.StringToBytes256(reason); |
1153 | tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0]; | 1151 | tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0]; |
1154 | 1152 | ||
1155 | // Hack to get this out immediately and skip throttles | 1153 | // Hack to get this out immediately and skip throttles |
@@ -1881,11 +1879,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1881 | AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate); | 1879 | AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate); |
1882 | sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid; | 1880 | sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid; |
1883 | sendAgentDataUpdate.AgentData.AgentID = agentid; | 1881 | sendAgentDataUpdate.AgentData.AgentID = agentid; |
1884 | sendAgentDataUpdate.AgentData.FirstName = Utils.StringToBytes(firstname); | 1882 | sendAgentDataUpdate.AgentData.FirstName = Util.StringToBytes256(firstname); |
1885 | sendAgentDataUpdate.AgentData.GroupName = Utils.StringToBytes(groupname); | 1883 | sendAgentDataUpdate.AgentData.GroupName = Util.StringToBytes256(groupname); |
1886 | sendAgentDataUpdate.AgentData.GroupPowers = grouppowers; | 1884 | sendAgentDataUpdate.AgentData.GroupPowers = grouppowers; |
1887 | sendAgentDataUpdate.AgentData.GroupTitle = Utils.StringToBytes(grouptitle); | 1885 | sendAgentDataUpdate.AgentData.GroupTitle = Util.StringToBytes256(grouptitle); |
1888 | sendAgentDataUpdate.AgentData.LastName = Utils.StringToBytes(lastname); | 1886 | sendAgentDataUpdate.AgentData.LastName = Util.StringToBytes256(lastname); |
1889 | OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task); | 1887 | OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task); |
1890 | } | 1888 | } |
1891 | 1889 | ||
@@ -1898,7 +1896,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1898 | { | 1896 | { |
1899 | AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); | 1897 | AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); |
1900 | alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); | 1898 | alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); |
1901 | alertPack.AlertData.Message = Utils.StringToBytes(message); | 1899 | alertPack.AlertData.Message = Util.StringToBytes256(message); |
1902 | alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0]; | 1900 | alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0]; |
1903 | OutPacket(alertPack, ThrottleOutPacketType.Task); | 1901 | OutPacket(alertPack, ThrottleOutPacketType.Task); |
1904 | } | 1902 | } |
@@ -1925,7 +1923,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1925 | { | 1923 | { |
1926 | AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); | 1924 | AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); |
1927 | alertPack.AgentData.AgentID = AgentId; | 1925 | alertPack.AgentData.AgentID = AgentId; |
1928 | alertPack.AlertData.Message = Utils.StringToBytes(message); | 1926 | alertPack.AlertData.Message = Util.StringToBytes256(message); |
1929 | alertPack.AlertData.Modal = modal; | 1927 | alertPack.AlertData.Modal = modal; |
1930 | 1928 | ||
1931 | return alertPack; | 1929 | return alertPack; |
@@ -1935,12 +1933,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1935 | string url) | 1933 | string url) |
1936 | { | 1934 | { |
1937 | LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL); | 1935 | LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL); |
1938 | loadURL.Data.ObjectName = Utils.StringToBytes(objectname); | 1936 | loadURL.Data.ObjectName = Util.StringToBytes256(objectname); |
1939 | loadURL.Data.ObjectID = objectID; | 1937 | loadURL.Data.ObjectID = objectID; |
1940 | loadURL.Data.OwnerID = ownerID; | 1938 | loadURL.Data.OwnerID = ownerID; |
1941 | loadURL.Data.OwnerIsGroup = groupOwned; | 1939 | loadURL.Data.OwnerIsGroup = groupOwned; |
1942 | loadURL.Data.Message = Utils.StringToBytes(message); | 1940 | loadURL.Data.Message = Util.StringToBytes256(message); |
1943 | loadURL.Data.URL = Utils.StringToBytes(url); | 1941 | loadURL.Data.URL = Util.StringToBytes256(url); |
1944 | OutPacket(loadURL, ThrottleOutPacketType.Task); | 1942 | OutPacket(loadURL, ThrottleOutPacketType.Task); |
1945 | } | 1943 | } |
1946 | 1944 | ||
@@ -1948,18 +1946,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1948 | { | 1946 | { |
1949 | ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); | 1947 | ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); |
1950 | dialog.Data.ObjectID = objectID; | 1948 | dialog.Data.ObjectID = objectID; |
1951 | dialog.Data.ObjectName = Utils.StringToBytes(objectname); | 1949 | dialog.Data.ObjectName = Util.StringToBytes256(objectname); |
1952 | // this is the username of the *owner* | 1950 | // this is the username of the *owner* |
1953 | dialog.Data.FirstName = Utils.StringToBytes(ownerFirstName); | 1951 | dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName); |
1954 | dialog.Data.LastName = Utils.StringToBytes(ownerLastName); | 1952 | dialog.Data.LastName = Util.StringToBytes256(ownerLastName); |
1955 | dialog.Data.Message = Utils.StringToBytes(msg); | 1953 | dialog.Data.Message = Util.StringToBytes1024(msg); |
1956 | dialog.Data.ImageID = textureID; | 1954 | dialog.Data.ImageID = textureID; |
1957 | dialog.Data.ChatChannel = ch; | 1955 | dialog.Data.ChatChannel = ch; |
1958 | ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length]; | 1956 | ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length]; |
1959 | for (int i = 0; i < buttonlabels.Length; i++) | 1957 | for (int i = 0; i < buttonlabels.Length; i++) |
1960 | { | 1958 | { |
1961 | buttons[i] = new ScriptDialogPacket.ButtonsBlock(); | 1959 | buttons[i] = new ScriptDialogPacket.ButtonsBlock(); |
1962 | buttons[i].ButtonLabel = Utils.StringToBytes(buttonlabels[i]); | 1960 | buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]); |
1963 | } | 1961 | } |
1964 | dialog.Buttons = buttons; | 1962 | dialog.Buttons = buttons; |
1965 | OutPacket(dialog, ThrottleOutPacketType.Task); | 1963 | OutPacket(dialog, ThrottleOutPacketType.Task); |
@@ -2115,19 +2113,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2115 | avatarReply.AgentData.AgentID = AgentId; | 2113 | avatarReply.AgentData.AgentID = AgentId; |
2116 | avatarReply.AgentData.AvatarID = avatarID; | 2114 | avatarReply.AgentData.AvatarID = avatarID; |
2117 | if (aboutText != null) | 2115 | if (aboutText != null) |
2118 | avatarReply.PropertiesData.AboutText = Utils.StringToBytes(aboutText); | 2116 | avatarReply.PropertiesData.AboutText = Util.StringToBytes1024(aboutText); |
2119 | else | 2117 | else |
2120 | avatarReply.PropertiesData.AboutText = Utils.StringToBytes(""); | 2118 | avatarReply.PropertiesData.AboutText = Utils.EmptyBytes; |
2121 | avatarReply.PropertiesData.BornOn = Utils.StringToBytes(bornOn); | 2119 | avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn); |
2122 | avatarReply.PropertiesData.CharterMember = charterMember; | 2120 | avatarReply.PropertiesData.CharterMember = charterMember; |
2123 | if (flAbout != null) | 2121 | if (flAbout != null) |
2124 | avatarReply.PropertiesData.FLAboutText = Utils.StringToBytes(flAbout); | 2122 | avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout); |
2125 | else | 2123 | else |
2126 | avatarReply.PropertiesData.FLAboutText = Utils.StringToBytes(""); | 2124 | avatarReply.PropertiesData.FLAboutText = Utils.EmptyBytes; |
2127 | avatarReply.PropertiesData.Flags = flags; | 2125 | avatarReply.PropertiesData.Flags = flags; |
2128 | avatarReply.PropertiesData.FLImageID = flImageID; | 2126 | avatarReply.PropertiesData.FLImageID = flImageID; |
2129 | avatarReply.PropertiesData.ImageID = imageID; | 2127 | avatarReply.PropertiesData.ImageID = imageID; |
2130 | avatarReply.PropertiesData.ProfileURL = Utils.StringToBytes(profileURL); | 2128 | avatarReply.PropertiesData.ProfileURL = Util.StringToBytes256(profileURL); |
2131 | avatarReply.PropertiesData.PartnerID = partnerID; | 2129 | avatarReply.PropertiesData.PartnerID = partnerID; |
2132 | OutPacket(avatarReply, ThrottleOutPacketType.Task); | 2130 | OutPacket(avatarReply, ThrottleOutPacketType.Task); |
2133 | } | 2131 | } |
@@ -2254,7 +2252,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2254 | Group.Contribution = GroupMembership[i].Contribution; | 2252 | Group.Contribution = GroupMembership[i].Contribution; |
2255 | Group.GroupID = GroupMembership[i].GroupID; | 2253 | Group.GroupID = GroupMembership[i].GroupID; |
2256 | Group.GroupInsigniaID = GroupMembership[i].GroupPicture; | 2254 | Group.GroupInsigniaID = GroupMembership[i].GroupPicture; |
2257 | Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); | 2255 | Group.GroupName = Util.StringToBytes256(GroupMembership[i].GroupName); |
2258 | Group.GroupPowers = GroupMembership[i].GroupPowers; | 2256 | Group.GroupPowers = GroupMembership[i].GroupPowers; |
2259 | Groups[i] = Group; | 2257 | Groups[i] = Group; |
2260 | 2258 | ||
@@ -2288,7 +2286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2288 | UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; | 2286 | UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; |
2289 | UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); | 2287 | UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); |
2290 | uidnamebloc.ID = groupLLUID; | 2288 | uidnamebloc.ID = groupLLUID; |
2291 | uidnamebloc.GroupName = Utils.StringToBytes(GroupName); | 2289 | uidnamebloc.GroupName = Util.StringToBytes256(GroupName); |
2292 | uidnameblock[0] = uidnamebloc; | 2290 | uidnameblock[0] = uidnamebloc; |
2293 | pack.UUIDNameBlock = uidnameblock; | 2291 | pack.UUIDNameBlock = uidnameblock; |
2294 | OutPacket(pack, ThrottleOutPacketType.Task); | 2292 | OutPacket(pack, ThrottleOutPacketType.Task); |
@@ -2313,8 +2311,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2313 | lsrepdb.Score = lsrpia[i].Score; | 2311 | lsrepdb.Score = lsrpia[i].Score; |
2314 | lsrepdb.TaskID = lsrpia[i].TaskID; | 2312 | lsrepdb.TaskID = lsrpia[i].TaskID; |
2315 | lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; | 2313 | lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; |
2316 | lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); | 2314 | lsrepdb.TaskName = Util.StringToBytes256(lsrpia[i].TaskName); |
2317 | lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); | 2315 | lsrepdb.OwnerName = Util.StringToBytes256(lsrpia[i].OwnerName); |
2318 | lsrepdba[i] = lsrepdb; | 2316 | lsrepdba[i] = lsrepdb; |
2319 | } | 2317 | } |
2320 | lsrp.ReportData = lsrepdba; | 2318 | lsrp.ReportData = lsrepdba; |
@@ -3127,7 +3125,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3127 | 3125 | ||
3128 | avp.Sender.IsTrial = false; | 3126 | avp.Sender.IsTrial = false; |
3129 | avp.Sender.ID = agentID; | 3127 | avp.Sender.ID = agentID; |
3130 | OutPacket(avp, ThrottleOutPacketType.State); | 3128 | OutPacket(avp, ThrottleOutPacketType.Task); |
3131 | } | 3129 | } |
3132 | 3130 | ||
3133 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) | 3131 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) |
@@ -3159,123 +3157,174 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3159 | 3157 | ||
3160 | #endregion | 3158 | #endregion |
3161 | 3159 | ||
3162 | #region Avatar Packet/data sending Methods | 3160 | #region Prim/Avatar Updates |
3163 | 3161 | ||
3164 | /// <summary> | 3162 | /*void SendObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) |
3165 | /// send a objectupdate packet with information about the clients avatar | ||
3166 | /// </summary> | ||
3167 | public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | ||
3168 | uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
3169 | { | 3163 | { |
3170 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3164 | bool canUseCompressed, canUseImproved; |
3171 | // TODO: don't create new blocks if recycling an old packet | 3165 | UpdateFlagsToPacketType(creatorFlags, updateFlags, out canUseCompressed, out canUseImproved); |
3172 | objupdate.RegionData.RegionHandle = regionHandle; | ||
3173 | objupdate.RegionData.TimeDilation = ushort.MaxValue; | ||
3174 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3175 | objupdate.ObjectData[0] = CreateDefaultAvatarPacket(textureEntry); | ||
3176 | 3166 | ||
3177 | //give this avatar object a local id and assign the user a name | 3167 | if (!canUseImproved && !canUseCompressed) |
3178 | objupdate.ObjectData[0].ID = avatarLocalID; | 3168 | SendFullObjectUpdate(obj, creatorFlags, updateFlags); |
3179 | objupdate.ObjectData[0].FullID = avatarID; | 3169 | else if (!canUseImproved) |
3180 | objupdate.ObjectData[0].ParentID = parentID; | 3170 | SendObjectUpdateCompressed(obj, creatorFlags, updateFlags); |
3181 | objupdate.ObjectData[0].NameValue = | 3171 | else |
3182 | Utils.StringToBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + "\nTitle STRING RW SV " + grouptitle); | 3172 | SendImprovedTerseObjectUpdate(obj, creatorFlags, updateFlags); |
3173 | } | ||
3183 | 3174 | ||
3184 | Vector3 pos2 = new Vector3(Pos.X, Pos.Y, Pos.Z); | 3175 | void SendFullObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) |
3185 | byte[] pb = pos2.GetBytes(); | 3176 | { |
3186 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); | 3177 | IClientAPI owner; |
3178 | if (m_scene.ClientManager.TryGetValue(obj.OwnerID, out owner) && owner is LLClientView) | ||
3179 | { | ||
3180 | LLClientView llOwner = (LLClientView)owner; | ||
3187 | 3181 | ||
3188 | byte[] rot = rotation.GetBytes(); | 3182 | // Send an update out to the owner |
3189 | Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length); | 3183 | ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket(); |
3184 | updateToOwner.RegionData.RegionHandle = obj.RegionHandle; | ||
3185 | //updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); | ||
3186 | updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3187 | updateToOwner.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags | creatorFlags | PrimFlags.ObjectYouOwner, 0); | ||
3190 | 3188 | ||
3191 | objupdate.Header.Zerocoded = true; | 3189 | m_udpServer.SendPacket(llOwner.UDPClient, updateToOwner, ThrottleOutPacketType.State, true); |
3192 | OutPacket(objupdate, ThrottleOutPacketType.Task); | 3190 | } |
3191 | |||
3192 | // Send an update out to everyone else | ||
3193 | ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket(); | ||
3194 | updateToOthers.RegionData.RegionHandle = obj.RegionHandle; | ||
3195 | //updateToOthers.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); | ||
3196 | updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3197 | updateToOthers.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags, 0); | ||
3198 | |||
3199 | m_scene.ClientManager.ForEach( | ||
3200 | delegate(IClientAPI client) | ||
3201 | { | ||
3202 | if (client.AgentId != obj.OwnerID && client is LLClientView) | ||
3203 | { | ||
3204 | LLClientView llClient = (LLClientView)client; | ||
3205 | m_udpServer.SendPacket(llClient.UDPClient, updateToOthers, ThrottleOutPacketType.State, true); | ||
3206 | } | ||
3207 | } | ||
3208 | ); | ||
3193 | } | 3209 | } |
3194 | 3210 | ||
3195 | /// <summary> | 3211 | void SendObjectUpdateCompressed(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) |
3196 | /// Send a terse positional/rotation/velocity update about an avatar | ||
3197 | /// to the client. This avatar can be that of the client itself. | ||
3198 | /// </summary> | ||
3199 | public virtual void SendAvatarTerseUpdate(ulong regionHandle, | ||
3200 | ushort timeDilation, uint localID, Vector3 position, | ||
3201 | Vector3 velocity, Quaternion rotation, UUID agentid) | ||
3202 | { | 3212 | { |
3203 | if (rotation.X == rotation.Y && | 3213 | } |
3204 | rotation.Y == rotation.Z && | ||
3205 | rotation.Z == rotation.W && rotation.W == 0) | ||
3206 | rotation = Quaternion.Identity; | ||
3207 | 3214 | ||
3208 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = | 3215 | void SendImprovedTerseObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) |
3209 | CreateAvatarImprovedBlock(localID, position, velocity,rotation); | 3216 | { |
3210 | 3217 | } | |
3211 | lock (m_avatarTerseUpdates) | ||
3212 | { | ||
3213 | m_avatarTerseUpdates.Add(terseBlock); | ||
3214 | 3218 | ||
3215 | // If packet is full or own movement packet, send it. | 3219 | void UpdateFlagsToPacketType(PrimFlags creatorFlags, PrimUpdateFlags updateFlags, out bool canUseCompressed, out bool canUseImproved) |
3216 | if (m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket) | 3220 | { |
3221 | canUseCompressed = true; | ||
3222 | canUseImproved = true; | ||
3223 | |||
3224 | if ((updateFlags & PrimUpdateFlags.FullUpdate) == PrimUpdateFlags.FullUpdate || creatorFlags != PrimFlags.None) | ||
3225 | { | ||
3226 | canUseCompressed = false; | ||
3227 | canUseImproved = false; | ||
3228 | } | ||
3229 | else | ||
3230 | { | ||
3231 | if ((updateFlags & PrimUpdateFlags.Velocity) != 0 || | ||
3232 | (updateFlags & PrimUpdateFlags.Acceleration) != 0 || | ||
3233 | (updateFlags & PrimUpdateFlags.CollisionPlane) != 0 || | ||
3234 | (updateFlags & PrimUpdateFlags.Joint) != 0) | ||
3217 | { | 3235 | { |
3218 | ProcessAvatarTerseUpdates(this, null); | 3236 | canUseCompressed = false; |
3219 | } | 3237 | } |
3220 | else if (m_avatarTerseUpdates.Count == 1) | 3238 | |
3239 | if ((updateFlags & PrimUpdateFlags.PrimFlags) != 0 || | ||
3240 | (updateFlags & PrimUpdateFlags.ParentID) != 0 || | ||
3241 | (updateFlags & PrimUpdateFlags.Scale) != 0 || | ||
3242 | (updateFlags & PrimUpdateFlags.PrimData) != 0 || | ||
3243 | (updateFlags & PrimUpdateFlags.Text) != 0 || | ||
3244 | (updateFlags & PrimUpdateFlags.NameValue) != 0 || | ||
3245 | (updateFlags & PrimUpdateFlags.ExtraData) != 0 || | ||
3246 | (updateFlags & PrimUpdateFlags.TextureAnim) != 0 || | ||
3247 | (updateFlags & PrimUpdateFlags.Sound) != 0 || | ||
3248 | (updateFlags & PrimUpdateFlags.Particles) != 0 || | ||
3249 | (updateFlags & PrimUpdateFlags.Material) != 0 || | ||
3250 | (updateFlags & PrimUpdateFlags.ClickAction) != 0 || | ||
3251 | (updateFlags & PrimUpdateFlags.MediaURL) != 0 || | ||
3252 | (updateFlags & PrimUpdateFlags.Joint) != 0) | ||
3221 | { | 3253 | { |
3222 | lock (m_avatarTerseUpdateTimer) | 3254 | canUseImproved = false; |
3223 | m_avatarTerseUpdateTimer.Start(); | ||
3224 | } | 3255 | } |
3225 | } | 3256 | } |
3226 | } | 3257 | }*/ |
3258 | |||
3259 | #endregion Prim/Avatar Updates | ||
3260 | |||
3261 | #region Avatar Packet/Data Sending Methods | ||
3227 | 3262 | ||
3228 | private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) | 3263 | /// <summary> |
3264 | /// Send an ObjectUpdate packet with information about an avatar | ||
3265 | /// </summary> | ||
3266 | public void SendAvatarData(SendAvatarData data) | ||
3229 | { | 3267 | { |
3230 | lock (m_avatarTerseUpdates) | 3268 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3231 | { | 3269 | objupdate.Header.Zerocoded = true; |
3232 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | ||
3233 | 3270 | ||
3234 | terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock(); | 3271 | objupdate.RegionData.RegionHandle = data.RegionHandle; |
3272 | objupdate.RegionData.TimeDilation = ushort.MaxValue; | ||
3273 | |||
3274 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3275 | objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); | ||
3235 | 3276 | ||
3236 | terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; | 3277 | OutPacket(objupdate, ThrottleOutPacketType.Task); |
3237 | terse.RegionData.TimeDilation = | 3278 | } |
3238 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||
3239 | 3279 | ||
3240 | int max = m_avatarTerseUpdatesPerPacket; | 3280 | /// <summary> |
3241 | if (max > m_avatarTerseUpdates.Count) | 3281 | /// Send a terse positional/rotation/velocity update about an avatar |
3242 | max = m_avatarTerseUpdates.Count; | 3282 | /// to the client. This avatar can be that of the client itself. |
3283 | /// </summary> | ||
3284 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) | ||
3285 | { | ||
3286 | if (data.Priority == double.NaN) | ||
3287 | { | ||
3288 | m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); | ||
3289 | return; | ||
3290 | } | ||
3243 | 3291 | ||
3244 | int count = 0; | 3292 | Quaternion rotation = data.Rotation; |
3245 | int size = 0; | 3293 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) |
3294 | rotation = Quaternion.Identity; | ||
3246 | 3295 | ||
3247 | byte[] zerobuffer = new byte[1024]; | 3296 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data); |
3248 | byte[] blockbuffer = new byte[1024]; | ||
3249 | 3297 | ||
3250 | for (count = 0 ; count < max ; count++) | 3298 | lock (m_avatarTerseUpdates.SyncRoot) |
3251 | { | 3299 | m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID); |
3252 | int length = 0; | ||
3253 | m_avatarTerseUpdates[count].ToBytes(blockbuffer, ref length); | ||
3254 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | ||
3255 | if (size + length > Packet.MTU) | ||
3256 | break; | ||
3257 | size += length; | ||
3258 | } | ||
3259 | 3300 | ||
3260 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | 3301 | // If we received an update about our own avatar, process the avatar update priority queue immediately |
3302 | if (data.AgentID == m_agentId) | ||
3303 | ProcessAvatarTerseUpdates(); | ||
3304 | } | ||
3261 | 3305 | ||
3262 | for (int i = 0 ; i < count ; i++) | 3306 | private void ProcessAvatarTerseUpdates() |
3263 | { | 3307 | { |
3264 | terse.ObjectData[i] = m_avatarTerseUpdates[0]; | 3308 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); |
3265 | m_avatarTerseUpdates.RemoveAt(0); | 3309 | terse.Header.Reliable = false; |
3266 | } | 3310 | terse.Header.Zerocoded = true; |
3267 | 3311 | ||
3268 | terse.Header.Reliable = false; | 3312 | //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock(); |
3269 | terse.Header.Zerocoded = true; | 3313 | terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; |
3270 | // FIXME: Move this to ThrottleOutPacketType.State when the real prioritization code is committed | 3314 | terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3271 | OutPacket(terse, ThrottleOutPacketType.Task); | ||
3272 | 3315 | ||
3273 | if (m_avatarTerseUpdates.Count == 0) | 3316 | lock (m_avatarTerseUpdates.SyncRoot) |
3274 | { | 3317 | { |
3275 | lock (m_avatarTerseUpdateTimer) | 3318 | int count = Math.Min(m_avatarTerseUpdates.Count, m_avatarTerseUpdatesPerPacket); |
3276 | m_avatarTerseUpdateTimer.Stop(); | 3319 | if (count == 0) |
3277 | } | 3320 | return; |
3321 | |||
3322 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | ||
3323 | for (int i = 0; i < count; i++) | ||
3324 | terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); | ||
3278 | } | 3325 | } |
3326 | |||
3327 | OutPacket(terse, ThrottleOutPacketType.Task); | ||
3279 | } | 3328 | } |
3280 | 3329 | ||
3281 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) | 3330 | public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) |
@@ -3314,319 +3363,231 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3314 | OutPacket(loc, ThrottleOutPacketType.Task); | 3363 | OutPacket(loc, ThrottleOutPacketType.Task); |
3315 | } | 3364 | } |
3316 | 3365 | ||
3317 | #endregion | 3366 | #endregion Avatar Packet/Data Sending Methods |
3318 | 3367 | ||
3319 | #region Primitive Packet/data Sending Methods | 3368 | #region Primitive Packet/Data Sending Methods |
3320 | 3369 | ||
3321 | /// <summary> | 3370 | public void SendPrimitiveToClient(SendPrimitiveData data) |
3322 | /// | ||
3323 | /// </summary> | ||
3324 | /// <param name="localID"></param> | ||
3325 | /// <param name="rotation"></param> | ||
3326 | /// <param name="attachPoint"></param> | ||
3327 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
3328 | { | 3371 | { |
3329 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3372 | if (data.priority == double.NaN) |
3373 | { | ||
3374 | m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); | ||
3330 | return; | 3375 | return; |
3376 | } | ||
3331 | 3377 | ||
3332 | ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach); | 3378 | Quaternion rotation = data.rotation; |
3333 | // TODO: don't create new blocks if recycling an old packet | 3379 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) |
3334 | attach.AgentData.AgentID = AgentId; | 3380 | rotation = Quaternion.Identity; |
3335 | attach.AgentData.SessionID = m_sessionId; | ||
3336 | attach.AgentData.AttachmentPoint = attachPoint; | ||
3337 | attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1]; | ||
3338 | attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock(); | ||
3339 | attach.ObjectData[0].ObjectLocalID = localID; | ||
3340 | attach.ObjectData[0].Rotation = rotation; | ||
3341 | attach.Header.Zerocoded = true; | ||
3342 | OutPacket(attach, ThrottleOutPacketType.Task); | ||
3343 | } | ||
3344 | |||
3345 | public void SendPrimitiveToClient( | ||
3346 | ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
3347 | Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, | ||
3348 | uint flags, UUID objectID, UUID ownerID, string text, byte[] color, | ||
3349 | uint parentID, byte[] particleSystem, byte clickAction, byte material) | ||
3350 | { | ||
3351 | byte[] textureanim = new byte[0]; | ||
3352 | |||
3353 | SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel, | ||
3354 | acc, rotation, rvel, flags, | ||
3355 | objectID, ownerID, text, color, parentID, particleSystem, | ||
3356 | clickAction, material, textureanim, false, 0, UUID.Zero, UUID.Zero, 0, 0, 0); | ||
3357 | } | ||
3358 | |||
3359 | public void SendPrimitiveToClient( | ||
3360 | ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | ||
3361 | Vector3 pos, Vector3 velocity, Vector3 acceleration, Quaternion rotation, Vector3 rotational_velocity, | ||
3362 | uint flags, | ||
3363 | UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, | ||
3364 | byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundGain, byte SoundFlags, double SoundRadius) | ||
3365 | { | ||
3366 | 3381 | ||
3367 | if (AttachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3382 | if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD |
3368 | return; | 3383 | return; |
3369 | if (primShape.PCode == 9 && primShape.State != 0 && parentID == 0) | 3384 | if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9) |
3370 | return; | 3385 | return; |
3371 | 3386 | ||
3372 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3387 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); |
3373 | rotation = Quaternion.Identity; | ||
3374 | 3388 | ||
3375 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(primShape, flags); | 3389 | lock (m_primFullUpdates.SyncRoot) |
3390 | m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); | ||
3391 | } | ||
3376 | 3392 | ||
3377 | objectData.ID = localID; | 3393 | void ProcessPrimFullUpdates() |
3378 | objectData.FullID = objectID; | 3394 | { |
3379 | objectData.OwnerID = ownerID; | 3395 | ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3396 | outPacket.Header.Zerocoded = true; | ||
3380 | 3397 | ||
3381 | objectData.Text = Util.StringToBytes256(text); | 3398 | outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; |
3382 | objectData.TextColor[0] = color[0]; | 3399 | outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3383 | objectData.TextColor[1] = color[1]; | ||
3384 | objectData.TextColor[2] = color[2]; | ||
3385 | objectData.TextColor[3] = color[3]; | ||
3386 | objectData.ParentID = parentID; | ||
3387 | objectData.PSBlock = particleSystem; | ||
3388 | objectData.ClickAction = clickAction; | ||
3389 | objectData.Material = material; | ||
3390 | objectData.Flags = 0; | ||
3391 | 3400 | ||
3392 | if (attachment) | 3401 | lock (m_primFullUpdates.SyncRoot) |
3393 | { | 3402 | { |
3394 | // Necessary??? | 3403 | int count = Math.Min(m_primFullUpdates.Count, m_primFullUpdatesPerPacket); |
3395 | objectData.JointAxisOrAnchor = new Vector3(0, 0, 2); | 3404 | if (count == 0) |
3396 | objectData.JointPivot = new Vector3(0, 0, 0); | 3405 | return; |
3397 | |||
3398 | // Item from inventory??? | ||
3399 | objectData.NameValue = | ||
3400 | Utils.StringToBytes("AttachItemID STRING RW SV " + AssetId.Guid); | ||
3401 | objectData.State = (byte)((AttachPoint % 16) * 16 + (AttachPoint / 16)); | ||
3402 | } | ||
3403 | 3406 | ||
3404 | // Xantor 20080528: Send sound info as well | 3407 | outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count]; |
3405 | // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again | 3408 | for (int i = 0; i < count; i++) |
3406 | objectData.Sound = SoundId; | 3409 | outPacket.ObjectData[i] = m_primFullUpdates.Dequeue(); |
3407 | if (SoundId == UUID.Zero) | ||
3408 | { | ||
3409 | objectData.OwnerID = UUID.Zero; | ||
3410 | objectData.Gain = 0.0f; | ||
3411 | objectData.Radius = 0.0f; | ||
3412 | objectData.Flags = 0; | ||
3413 | } | 3410 | } |
3414 | else | ||
3415 | { | ||
3416 | objectData.OwnerID = ownerID; | ||
3417 | objectData.Gain = (float)SoundGain; | ||
3418 | objectData.Radius = (float)SoundRadius; | ||
3419 | objectData.Flags = SoundFlags; | ||
3420 | } | ||
3421 | |||
3422 | byte[] pb = pos.GetBytes(); | ||
3423 | Array.Copy(pb, 0, objectData.ObjectData, 0, pb.Length); | ||
3424 | |||
3425 | byte[] vel = velocity.GetBytes(); | ||
3426 | Array.Copy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); | ||
3427 | 3411 | ||
3428 | byte[] rot = rotation.GetBytes(); | 3412 | OutPacket(outPacket, ThrottleOutPacketType.State); |
3429 | Array.Copy(rot, 0, objectData.ObjectData, 36, rot.Length); | 3413 | } |
3430 | |||
3431 | byte[] rvel = rotational_velocity.GetBytes(); | ||
3432 | Array.Copy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); | ||
3433 | 3414 | ||
3434 | if (textureanim.Length > 0) | 3415 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
3416 | { | ||
3417 | if (data.Priority == double.NaN) | ||
3435 | { | 3418 | { |
3436 | objectData.TextureAnim = textureanim; | 3419 | m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); |
3420 | return; | ||
3437 | } | 3421 | } |
3438 | 3422 | ||
3439 | lock (m_primFullUpdates) | 3423 | Quaternion rotation = data.Rotation; |
3440 | { | 3424 | if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) |
3441 | if (m_primFullUpdates.Count == 0) | 3425 | rotation = Quaternion.Identity; |
3442 | m_primFullUpdateTimer.Start(); | ||
3443 | 3426 | ||
3444 | m_primFullUpdates.Add(objectData); | 3427 | if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD |
3428 | return; | ||
3445 | 3429 | ||
3446 | if (m_primFullUpdates.Count >= m_primFullUpdatesPerPacket) | 3430 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); |
3447 | ProcessPrimFullUpdates(this, null); | ||
3448 | } | ||
3449 | } | ||
3450 | 3431 | ||
3451 | void HandleQueueEmpty(ThrottleOutPacketType queue) | 3432 | lock (m_primTerseUpdates.SyncRoot) |
3452 | { | 3433 | m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID); |
3453 | switch (queue) | ||
3454 | { | ||
3455 | case ThrottleOutPacketType.Texture: | ||
3456 | ProcessTextureRequests(); | ||
3457 | break; | ||
3458 | } | ||
3459 | } | 3434 | } |
3460 | 3435 | ||
3461 | void ProcessTextureRequests() | 3436 | void ProcessPrimTerseUpdates() |
3462 | { | 3437 | { |
3463 | if (m_imageManager != null) | 3438 | ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); |
3464 | m_imageManager.ProcessImageQueue(m_textureSendLimit); | 3439 | outPacket.Header.Reliable = false; |
3465 | } | 3440 | outPacket.Header.Zerocoded = true; |
3466 | 3441 | ||
3467 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) | 3442 | outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; |
3468 | { | 3443 | outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); |
3469 | lock (m_primFullUpdates) | ||
3470 | { | ||
3471 | if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) | ||
3472 | { | ||
3473 | lock (m_primFullUpdateTimer) | ||
3474 | m_primFullUpdateTimer.Stop(); | ||
3475 | 3444 | ||
3445 | lock (m_primTerseUpdates.SyncRoot) | ||
3446 | { | ||
3447 | int count = Math.Min(m_primTerseUpdates.Count, m_primTerseUpdatesPerPacket); | ||
3448 | if (count == 0) | ||
3476 | return; | 3449 | return; |
3477 | } | ||
3478 | |||
3479 | ObjectUpdatePacket outPacket = | ||
3480 | (ObjectUpdatePacket)PacketPool.Instance.GetPacket( | ||
3481 | PacketType.ObjectUpdate); | ||
3482 | |||
3483 | outPacket.RegionData.RegionHandle = | ||
3484 | Scene.RegionInfo.RegionHandle; | ||
3485 | outPacket.RegionData.TimeDilation = | ||
3486 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||
3487 | 3450 | ||
3488 | int max = m_primFullUpdates.Count; | 3451 | outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; |
3489 | if (max > m_primFullUpdatesPerPacket) | 3452 | for (int i = 0; i < count; i++) |
3490 | max = m_primFullUpdatesPerPacket; | 3453 | outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); |
3491 | 3454 | } | |
3492 | int count = 0; | ||
3493 | int size = 0; | ||
3494 | 3455 | ||
3495 | byte[] zerobuffer = new byte[1024]; | 3456 | OutPacket(outPacket, ThrottleOutPacketType.State); |
3496 | byte[] blockbuffer = new byte[1024]; | 3457 | } |
3497 | 3458 | ||
3498 | for (count = 0 ; count < max ; count++) | 3459 | public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) |
3460 | { | ||
3461 | PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler = | ||
3462 | delegate(ref double priority, uint local_id) | ||
3499 | { | 3463 | { |
3500 | int length = 0; | 3464 | priority = handler(new UpdatePriorityData(priority, local_id)); |
3501 | m_primFullUpdates[count].ToBytes(blockbuffer, ref length); | 3465 | return priority != double.NaN; |
3502 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | 3466 | }; |
3503 | if (size + length > Packet.MTU) | 3467 | PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler = |
3504 | break; | 3468 | delegate(ref double priority, uint local_id) |
3505 | size += length; | 3469 | { |
3506 | } | 3470 | priority = handler(new UpdatePriorityData(priority, local_id)); |
3471 | return priority != double.NaN; | ||
3472 | }; | ||
3507 | 3473 | ||
3508 | outPacket.ObjectData = | 3474 | if ((type & StateUpdateTypes.AvatarTerse) != 0) |
3509 | new ObjectUpdatePacket.ObjectDataBlock[count]; | 3475 | { |
3476 | lock (m_avatarTerseUpdates.SyncRoot) | ||
3477 | m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler); | ||
3478 | } | ||
3510 | 3479 | ||
3511 | for (int index = 0 ; index < count ; index++) | 3480 | if ((type & StateUpdateTypes.PrimitiveFull) != 0) |
3512 | { | 3481 | { |
3513 | outPacket.ObjectData[index] = m_primFullUpdates[0]; | 3482 | lock (m_primFullUpdates.SyncRoot) |
3514 | m_primFullUpdates.RemoveAt(0); | 3483 | m_primFullUpdates.Reprioritize(update_priority_handler); |
3515 | } | 3484 | } |
3516 | 3485 | ||
3517 | outPacket.Header.Zerocoded = true; | 3486 | if ((type & StateUpdateTypes.PrimitiveTerse) != 0) |
3518 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3487 | { |
3488 | lock (m_primTerseUpdates.SyncRoot) | ||
3489 | m_primTerseUpdates.Reprioritize(terse_update_priority_handler); | ||
3490 | } | ||
3491 | } | ||
3519 | 3492 | ||
3520 | if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) | 3493 | public void FlushPrimUpdates() |
3521 | lock (m_primFullUpdateTimer) | 3494 | { |
3522 | m_primFullUpdateTimer.Stop(); | 3495 | while (m_primFullUpdates.Count > 0) |
3496 | { | ||
3497 | ProcessPrimFullUpdates(); | ||
3498 | } | ||
3499 | while (m_primTerseUpdates.Count > 0) | ||
3500 | { | ||
3501 | ProcessPrimTerseUpdates(); | ||
3502 | } | ||
3503 | while (m_avatarTerseUpdates.Count > 0) | ||
3504 | { | ||
3505 | ProcessAvatarTerseUpdates(); | ||
3523 | } | 3506 | } |
3524 | } | 3507 | } |
3525 | 3508 | ||
3509 | #endregion Primitive Packet/Data Sending Methods | ||
3510 | |||
3526 | /// <summary> | 3511 | /// <summary> |
3527 | /// | 3512 | /// |
3528 | /// </summary> | 3513 | /// </summary> |
3529 | public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, | 3514 | /// <param name="localID"></param> |
3530 | Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) | 3515 | /// <param name="rotation"></param> |
3516 | /// <param name="attachPoint"></param> | ||
3517 | public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) | ||
3531 | { | 3518 | { |
3532 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3519 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD |
3533 | return; | 3520 | return; |
3534 | 3521 | ||
3535 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3522 | ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach); |
3536 | rotation = Quaternion.Identity; | 3523 | // TODO: don't create new blocks if recycling an old packet |
3537 | 3524 | attach.AgentData.AgentID = AgentId; | |
3538 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = | 3525 | attach.AgentData.SessionID = m_sessionId; |
3539 | CreatePrimImprovedBlock(localID, position, rotation, | 3526 | attach.AgentData.AttachmentPoint = attachPoint; |
3540 | velocity, rotationalvelocity, state); | 3527 | attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1]; |
3541 | 3528 | attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock(); | |
3542 | lock (m_primTerseUpdates) | 3529 | attach.ObjectData[0].ObjectLocalID = localID; |
3543 | { | 3530 | attach.ObjectData[0].Rotation = rotation; |
3544 | if (m_primTerseUpdates.Count == 0) | 3531 | attach.Header.Zerocoded = true; |
3545 | m_primTerseUpdateTimer.Start(); | 3532 | OutPacket(attach, ThrottleOutPacketType.Task); |
3546 | |||
3547 | m_primTerseUpdates.Add(objectData); | ||
3548 | |||
3549 | if (m_primTerseUpdates.Count >= m_primTerseUpdatesPerPacket) | ||
3550 | ProcessPrimTerseUpdates(this, null); | ||
3551 | } | ||
3552 | } | 3533 | } |
3553 | 3534 | ||
3554 | void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) | 3535 | void HandleQueueEmpty(ThrottleOutPacketType queue) |
3555 | { | 3536 | { |
3556 | lock (m_primTerseUpdates) | 3537 | switch (queue) |
3557 | { | 3538 | { |
3558 | if (m_primTerseUpdates.Count == 0) | 3539 | case ThrottleOutPacketType.Texture: |
3559 | { | 3540 | ProcessTextureRequests(); |
3560 | lock (m_primTerseUpdateTimer) | 3541 | break; |
3561 | m_primTerseUpdateTimer.Stop(); | 3542 | case ThrottleOutPacketType.Task: |
3562 | 3543 | if (Monitor.TryEnter(m_avatarTerseUpdates.SyncRoot, 1)) | |
3563 | return; | 3544 | { |
3564 | } | 3545 | try |
3565 | 3546 | { | |
3566 | ImprovedTerseObjectUpdatePacket outPacket = | 3547 | if (m_avatarTerseUpdates.Count > 0) |
3567 | (ImprovedTerseObjectUpdatePacket) | 3548 | { |
3568 | PacketPool.Instance.GetPacket( | ||
3569 | PacketType.ImprovedTerseObjectUpdate); | ||
3570 | |||
3571 | outPacket.RegionData.RegionHandle = | ||
3572 | Scene.RegionInfo.RegionHandle; | ||
3573 | outPacket.RegionData.TimeDilation = | ||
3574 | (ushort)(Scene.TimeDilation * ushort.MaxValue); | ||
3575 | |||
3576 | int max = m_primTerseUpdates.Count; | ||
3577 | if (max > m_primTerseUpdatesPerPacket) | ||
3578 | max = m_primTerseUpdatesPerPacket; | ||
3579 | |||
3580 | int count = 0; | ||
3581 | int size = 0; | ||
3582 | |||
3583 | byte[] zerobuffer = new byte[1024]; | ||
3584 | byte[] blockbuffer = new byte[1024]; | ||
3585 | |||
3586 | for (count = 0 ; count < max ; count++) | ||
3587 | { | ||
3588 | int length = 0; | ||
3589 | m_primTerseUpdates[count].ToBytes(blockbuffer, ref length); | ||
3590 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | ||
3591 | if (size + length > Packet.MTU) | ||
3592 | break; | ||
3593 | size += length; | ||
3594 | } | ||
3595 | |||
3596 | outPacket.ObjectData = | ||
3597 | new ImprovedTerseObjectUpdatePacket. | ||
3598 | ObjectDataBlock[count]; | ||
3599 | |||
3600 | for (int index = 0 ; index < count ; index++) | ||
3601 | { | ||
3602 | outPacket.ObjectData[index] = m_primTerseUpdates[0]; | ||
3603 | m_primTerseUpdates.RemoveAt(0); | ||
3604 | } | ||
3605 | 3549 | ||
3606 | outPacket.Header.Reliable = false; | 3550 | ProcessAvatarTerseUpdates(); |
3607 | outPacket.Header.Zerocoded = true; | 3551 | return; |
3608 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3552 | } |
3553 | } | ||
3554 | finally { Monitor.Exit(m_avatarTerseUpdates.SyncRoot); } | ||
3555 | } | ||
3556 | break; | ||
3557 | case ThrottleOutPacketType.State: | ||
3558 | if (Monitor.TryEnter(m_primFullUpdates.SyncRoot, 1)) | ||
3559 | { | ||
3560 | try | ||
3561 | { | ||
3562 | if (m_primFullUpdates.Count > 0) | ||
3563 | { | ||
3564 | ProcessPrimFullUpdates(); | ||
3565 | return; | ||
3566 | } | ||
3567 | } | ||
3568 | finally { Monitor.Exit(m_primFullUpdates.SyncRoot); } | ||
3569 | } | ||
3609 | 3570 | ||
3610 | if (m_primTerseUpdates.Count == 0) | 3571 | if (Monitor.TryEnter(m_primTerseUpdates.SyncRoot, 1)) |
3611 | lock (m_primTerseUpdateTimer) | 3572 | { |
3612 | m_primTerseUpdateTimer.Stop(); | 3573 | try |
3574 | { | ||
3575 | if (m_primTerseUpdates.Count > 0) | ||
3576 | { | ||
3577 | ProcessPrimTerseUpdates(); | ||
3578 | return; | ||
3579 | } | ||
3580 | } | ||
3581 | finally { Monitor.Exit(m_primTerseUpdates.SyncRoot); } | ||
3582 | } | ||
3583 | break; | ||
3613 | } | 3584 | } |
3614 | } | 3585 | } |
3615 | 3586 | ||
3616 | public void FlushPrimUpdates() | 3587 | void ProcessTextureRequests() |
3617 | { | 3588 | { |
3618 | while (m_primFullUpdates.Count > 0) | 3589 | if (m_imageManager != null) |
3619 | { | 3590 | m_imageManager.ProcessImageQueue(m_textureSendLimit); |
3620 | ProcessPrimFullUpdates(this, null); | ||
3621 | } | ||
3622 | while (m_primTerseUpdates.Count > 0) | ||
3623 | { | ||
3624 | ProcessPrimTerseUpdates(this, null); | ||
3625 | } | ||
3626 | while (m_avatarTerseUpdates.Count > 0) | ||
3627 | { | ||
3628 | ProcessAvatarTerseUpdates(this, null); | ||
3629 | } | ||
3630 | } | 3591 | } |
3631 | 3592 | ||
3632 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) | 3593 | public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) |
@@ -3810,8 +3771,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3810 | OutPacket(proper, ThrottleOutPacketType.Task); | 3771 | OutPacket(proper, ThrottleOutPacketType.Task); |
3811 | } | 3772 | } |
3812 | 3773 | ||
3813 | #endregion | ||
3814 | |||
3815 | #region Estate Data Sending Methods | 3774 | #region Estate Data Sending Methods |
3816 | 3775 | ||
3817 | private static bool convertParamStringToBool(byte[] field) | 3776 | private static bool convertParamStringToBool(byte[] field) |
@@ -4218,325 +4177,221 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4218 | 4177 | ||
4219 | #region Helper Methods | 4178 | #region Helper Methods |
4220 | 4179 | ||
4221 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, Vector3 pos, | 4180 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data) |
4222 | Vector3 velocity, | ||
4223 | Quaternion rotation) | ||
4224 | { | 4181 | { |
4225 | byte[] bytes = new byte[60]; | 4182 | return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity, |
4226 | int i = 0; | 4183 | data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry); |
4227 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = PacketPool.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
4228 | |||
4229 | dat.TextureEntry = new byte[0]; // AvatarTemplate.TextureEntry; | ||
4230 | |||
4231 | uint ID = localID; | ||
4232 | |||
4233 | bytes[i++] = (byte)(ID % 256); | ||
4234 | bytes[i++] = (byte)((ID >> 8) % 256); | ||
4235 | bytes[i++] = (byte)((ID >> 16) % 256); | ||
4236 | bytes[i++] = (byte)((ID >> 24) % 256); | ||
4237 | bytes[i++] = 0; | ||
4238 | bytes[i++] = 1; | ||
4239 | i += 14; | ||
4240 | bytes[i++] = 128; | ||
4241 | bytes[i++] = 63; | ||
4242 | |||
4243 | byte[] pb = pos.GetBytes(); | ||
4244 | Array.Copy(pb, 0, bytes, i, pb.Length); | ||
4245 | i += 12; | ||
4246 | |||
4247 | Vector3 internDirec = new Vector3(velocity.X, velocity.Y, velocity.Z); | ||
4248 | |||
4249 | internDirec = internDirec / 128.0f; | ||
4250 | internDirec.X += 1; | ||
4251 | internDirec.Y += 1; | ||
4252 | internDirec.Z += 1; | ||
4253 | |||
4254 | ushort InternVelocityX = (ushort)(32768 * internDirec.X); | ||
4255 | ushort InternVelocityY = (ushort)(32768 * internDirec.Y); | ||
4256 | ushort InternVelocityZ = (ushort)(32768 * internDirec.Z); | ||
4257 | |||
4258 | ushort ac = 32767; | ||
4259 | bytes[i++] = (byte)(InternVelocityX % 256); | ||
4260 | bytes[i++] = (byte)((InternVelocityX >> 8) % 256); | ||
4261 | bytes[i++] = (byte)(InternVelocityY % 256); | ||
4262 | bytes[i++] = (byte)((InternVelocityY >> 8) % 256); | ||
4263 | bytes[i++] = (byte)(InternVelocityZ % 256); | ||
4264 | bytes[i++] = (byte)((InternVelocityZ >> 8) % 256); | ||
4265 | |||
4266 | //accel | ||
4267 | bytes[i++] = (byte)(ac % 256); | ||
4268 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4269 | bytes[i++] = (byte)(ac % 256); | ||
4270 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4271 | bytes[i++] = (byte)(ac % 256); | ||
4272 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4273 | |||
4274 | //rotation | ||
4275 | ushort rw, rx, ry, rz; | ||
4276 | rw = (ushort)(32768 * (rotation.W + 1)); | ||
4277 | rx = (ushort)(32768 * (rotation.X + 1)); | ||
4278 | ry = (ushort)(32768 * (rotation.Y + 1)); | ||
4279 | rz = (ushort)(32768 * (rotation.Z + 1)); | ||
4280 | |||
4281 | //rot | ||
4282 | bytes[i++] = (byte)(rx % 256); | ||
4283 | bytes[i++] = (byte)((rx >> 8) % 256); | ||
4284 | bytes[i++] = (byte)(ry % 256); | ||
4285 | bytes[i++] = (byte)((ry >> 8) % 256); | ||
4286 | bytes[i++] = (byte)(rz % 256); | ||
4287 | bytes[i++] = (byte)((rz >> 8) % 256); | ||
4288 | bytes[i++] = (byte)(rw % 256); | ||
4289 | bytes[i++] = (byte)((rw >> 8) % 256); | ||
4290 | |||
4291 | //rotation vel | ||
4292 | bytes[i++] = (byte)(ac % 256); | ||
4293 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4294 | bytes[i++] = (byte)(ac % 256); | ||
4295 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4296 | bytes[i++] = (byte)(ac % 256); | ||
4297 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4298 | |||
4299 | dat.Data = bytes; | ||
4300 | |||
4301 | return (dat); | ||
4302 | } | 4184 | } |
4303 | 4185 | ||
4304 | /// <summary> | 4186 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) |
4305 | /// | ||
4306 | /// </summary> | ||
4307 | /// <param name="localID"></param> | ||
4308 | /// <param name="position"></param> | ||
4309 | /// <param name="rotation"></param> | ||
4310 | /// <returns></returns> | ||
4311 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID, | ||
4312 | Vector3 position, | ||
4313 | Quaternion rotation, | ||
4314 | Vector3 velocity, | ||
4315 | Vector3 rotationalvelocity, | ||
4316 | byte state) | ||
4317 | { | 4187 | { |
4318 | uint ID = localID; | 4188 | return CreateImprovedTerseBlock(false, data.LocalID, data.State, Vector4.Zero, data.Position, data.Velocity, |
4319 | byte[] bytes = new byte[60]; | 4189 | data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); |
4320 | |||
4321 | int i = 0; | ||
4322 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = PacketPool.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
4323 | dat.TextureEntry = new byte[0]; | ||
4324 | bytes[i++] = (byte)(ID % 256); | ||
4325 | bytes[i++] = (byte)((ID >> 8) % 256); | ||
4326 | bytes[i++] = (byte)((ID >> 16) % 256); | ||
4327 | bytes[i++] = (byte)((ID >> 24) % 256); | ||
4328 | bytes[i++] = (byte)(((state & 0xf0) >> 4) | ((state & 0x0f) << 4)); | ||
4329 | bytes[i++] = 0; | ||
4330 | |||
4331 | byte[] pb = position.GetBytes(); | ||
4332 | Array.Copy(pb, 0, bytes, i, pb.Length); | ||
4333 | i += 12; | ||
4334 | ushort ac = 32767; | ||
4335 | |||
4336 | ushort velx, vely, velz; | ||
4337 | Vector3 vel = new Vector3(velocity.X, velocity.Y, velocity.Z); | ||
4338 | |||
4339 | vel = vel / 128.0f; | ||
4340 | vel.X += 1; | ||
4341 | vel.Y += 1; | ||
4342 | vel.Z += 1; | ||
4343 | //vel | ||
4344 | velx = (ushort)(32768 * (vel.X)); | ||
4345 | vely = (ushort)(32768 * (vel.Y)); | ||
4346 | velz = (ushort)(32768 * (vel.Z)); | ||
4347 | |||
4348 | bytes[i++] = (byte)(velx % 256); | ||
4349 | bytes[i++] = (byte)((velx >> 8) % 256); | ||
4350 | bytes[i++] = (byte)(vely % 256); | ||
4351 | bytes[i++] = (byte)((vely >> 8) % 256); | ||
4352 | bytes[i++] = (byte)(velz % 256); | ||
4353 | bytes[i++] = (byte)((velz >> 8) % 256); | ||
4354 | |||
4355 | //accel | ||
4356 | bytes[i++] = (byte)(ac % 256); | ||
4357 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4358 | bytes[i++] = (byte)(ac % 256); | ||
4359 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4360 | bytes[i++] = (byte)(ac % 256); | ||
4361 | bytes[i++] = (byte)((ac >> 8) % 256); | ||
4362 | |||
4363 | ushort rw, rx, ry, rz; | ||
4364 | rw = (ushort)(32768 * (rotation.W + 1)); | ||
4365 | rx = (ushort)(32768 * (rotation.X + 1)); | ||
4366 | ry = (ushort)(32768 * (rotation.Y + 1)); | ||
4367 | rz = (ushort)(32768 * (rotation.Z + 1)); | ||
4368 | |||
4369 | //rot | ||
4370 | bytes[i++] = (byte)(rx % 256); | ||
4371 | bytes[i++] = (byte)((rx >> 8) % 256); | ||
4372 | bytes[i++] = (byte)(ry % 256); | ||
4373 | bytes[i++] = (byte)((ry >> 8) % 256); | ||
4374 | bytes[i++] = (byte)(rz % 256); | ||
4375 | bytes[i++] = (byte)((rz >> 8) % 256); | ||
4376 | bytes[i++] = (byte)(rw % 256); | ||
4377 | bytes[i++] = (byte)((rw >> 8) % 256); | ||
4378 | |||
4379 | //rotation vel | ||
4380 | Vector3 rvel = new Vector3(rotationalvelocity.X, rotationalvelocity.Y, rotationalvelocity.Z); | ||
4381 | |||
4382 | rvel = rvel / 128.0f; | ||
4383 | rvel.X += 1; | ||
4384 | rvel.Y += 1; | ||
4385 | rvel.Z += 1; | ||
4386 | //vel | ||
4387 | ushort rvelx = (ushort)(32768 * (rvel.X)); | ||
4388 | ushort rvely = (ushort)(32768 * (rvel.Y)); | ||
4389 | ushort rvelz = (ushort)(32768 * (rvel.Z)); | ||
4390 | |||
4391 | bytes[i++] = (byte)(rvelx % 256); | ||
4392 | bytes[i++] = (byte)((rvelx >> 8) % 256); | ||
4393 | bytes[i++] = (byte)(rvely % 256); | ||
4394 | bytes[i++] = (byte)((rvely >> 8) % 256); | ||
4395 | bytes[i++] = (byte)(rvelz % 256); | ||
4396 | bytes[i++] = (byte)((rvelz >> 8) % 256); | ||
4397 | dat.Data = bytes; | ||
4398 | |||
4399 | return dat; | ||
4400 | } | 4190 | } |
4401 | 4191 | ||
4402 | /// <summary> | 4192 | protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, byte state, |
4403 | /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive) | 4193 | Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation, |
4404 | /// </summary> | 4194 | Vector3 angularVelocity, byte[] textureEntry) |
4405 | /// <param name="primData"></param> | 4195 | { |
4406 | /// <returns></returns> | 4196 | int pos = 0; |
4407 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimitiveBaseShape primShape, uint flags) | 4197 | byte[] data = new byte[(avatar ? 60 : 44)]; |
4408 | { | ||
4409 | ObjectUpdatePacket.ObjectDataBlock objupdate = PacketPool.GetDataBlock<ObjectUpdatePacket.ObjectDataBlock>(); | ||
4410 | SetDefaultPrimPacketValues(objupdate); | ||
4411 | objupdate.UpdateFlags = flags; | ||
4412 | SetPrimPacketShapeData(objupdate, primShape); | ||
4413 | |||
4414 | if ((primShape.PCode == (byte)PCode.NewTree) || (primShape.PCode == (byte)PCode.Tree) || (primShape.PCode == (byte)PCode.Grass)) | ||
4415 | { | ||
4416 | objupdate.Data = new byte[1]; | ||
4417 | objupdate.Data[0] = primShape.State; | ||
4418 | } | ||
4419 | return objupdate; | ||
4420 | } | ||
4421 | |||
4422 | protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimitiveBaseShape primData) | ||
4423 | { | ||
4424 | objectData.TextureEntry = primData.TextureEntry; | ||
4425 | objectData.PCode = primData.PCode; | ||
4426 | objectData.State = primData.State; | ||
4427 | objectData.PathBegin = primData.PathBegin; | ||
4428 | objectData.PathEnd = primData.PathEnd; | ||
4429 | objectData.PathScaleX = primData.PathScaleX; | ||
4430 | objectData.PathScaleY = primData.PathScaleY; | ||
4431 | objectData.PathShearX = primData.PathShearX; | ||
4432 | objectData.PathShearY = primData.PathShearY; | ||
4433 | objectData.PathSkew = primData.PathSkew; | ||
4434 | objectData.ProfileBegin = primData.ProfileBegin; | ||
4435 | objectData.ProfileEnd = primData.ProfileEnd; | ||
4436 | objectData.Scale = primData.Scale; | ||
4437 | objectData.PathCurve = primData.PathCurve; | ||
4438 | objectData.ProfileCurve = primData.ProfileCurve; | ||
4439 | objectData.ProfileHollow = primData.ProfileHollow; | ||
4440 | objectData.PathRadiusOffset = primData.PathRadiusOffset; | ||
4441 | objectData.PathRevolutions = primData.PathRevolutions; | ||
4442 | objectData.PathTaperX = primData.PathTaperX; | ||
4443 | objectData.PathTaperY = primData.PathTaperY; | ||
4444 | objectData.PathTwist = primData.PathTwist; | ||
4445 | objectData.PathTwistBegin = primData.PathTwistBegin; | ||
4446 | objectData.ExtraParams = primData.ExtraParams; | ||
4447 | } | ||
4448 | 4198 | ||
4449 | /// <summary> | 4199 | // LocalID |
4450 | /// Set some default values in a ObjectUpdatePacket | 4200 | Utils.UIntToBytes(localID, data, pos); |
4451 | /// </summary> | 4201 | pos += 4; |
4452 | /// <param name="objdata"></param> | ||
4453 | protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata) | ||
4454 | { | ||
4455 | objdata.PSBlock = new byte[0]; | ||
4456 | objdata.ExtraParams = new byte[1]; | ||
4457 | objdata.MediaURL = new byte[0]; | ||
4458 | objdata.NameValue = new byte[0]; | ||
4459 | objdata.Text = new byte[0]; | ||
4460 | objdata.TextColor = new byte[4]; | ||
4461 | objdata.JointAxisOrAnchor = new Vector3(0, 0, 0); | ||
4462 | objdata.JointPivot = new Vector3(0, 0, 0); | ||
4463 | objdata.Material = 3; | ||
4464 | objdata.TextureAnim = new byte[0]; | ||
4465 | objdata.Sound = UUID.Zero; | ||
4466 | objdata.State = 0; | ||
4467 | objdata.Data = new byte[0]; | ||
4468 | |||
4469 | objdata.ObjectData = new byte[60]; | ||
4470 | objdata.ObjectData[46] = 128; | ||
4471 | objdata.ObjectData[47] = 63; | ||
4472 | } | ||
4473 | 4202 | ||
4474 | /// <summary> | 4203 | // Avatar/CollisionPlane |
4475 | /// | 4204 | data[pos++] = state; |
4476 | /// </summary> | 4205 | if (avatar) |
4477 | /// <returns></returns> | 4206 | { |
4478 | public ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry) | 4207 | data[pos++] = 1; |
4479 | { | ||
4480 | ObjectUpdatePacket.ObjectDataBlock objdata = PacketPool.GetDataBlock<ObjectUpdatePacket.ObjectDataBlock>(); | ||
4481 | // new OpenMetaverse.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); | ||
4482 | 4208 | ||
4483 | SetDefaultAvatarPacketValues(ref objdata); | 4209 | if (collisionPlane == Vector4.Zero) |
4484 | objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); | 4210 | collisionPlane = Vector4.UnitW; |
4485 | objdata.PathCurve = 16; | 4211 | |
4486 | objdata.ProfileCurve = 1; | 4212 | collisionPlane.ToBytes(data, pos); |
4487 | objdata.PathScaleX = 100; | 4213 | pos += 16; |
4488 | objdata.PathScaleY = 100; | 4214 | } |
4489 | objdata.ParentID = 0; | 4215 | else |
4490 | objdata.OwnerID = UUID.Zero; | ||
4491 | objdata.Scale = new Vector3(1, 1, 1); | ||
4492 | objdata.PCode = (byte)PCode.Avatar; | ||
4493 | if (textureEntry != null) | ||
4494 | { | 4216 | { |
4495 | objdata.TextureEntry = textureEntry; | 4217 | ++pos; |
4496 | } | 4218 | } |
4497 | Vector3 pos = new Vector3(objdata.ObjectData, 16); | ||
4498 | pos.X = 100f; | ||
4499 | objdata.ID = 8880000; | ||
4500 | objdata.NameValue = Utils.StringToBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User "); | ||
4501 | //Vector3 pos2 = new Vector3(100f, 100f, 23f); | ||
4502 | //objdata.FullID=user.AgentId; | ||
4503 | byte[] pb = pos.GetBytes(); | ||
4504 | Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length); | ||
4505 | 4219 | ||
4506 | return objdata; | 4220 | // Position |
4507 | } | 4221 | position.ToBytes(data, pos); |
4222 | pos += 12; | ||
4508 | 4223 | ||
4509 | /// <summary> | 4224 | // Velocity |
4510 | /// | 4225 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2; |
4511 | /// </summary> | 4226 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2; |
4512 | /// <param name="objdata"></param> | 4227 | Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2; |
4513 | protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata) | 4228 | |
4514 | { | 4229 | // Acceleration |
4515 | objdata.PSBlock = new byte[0]; | 4230 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2; |
4516 | objdata.ExtraParams = new byte[1]; | 4231 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2; |
4517 | objdata.MediaURL = new byte[0]; | 4232 | Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2; |
4518 | objdata.NameValue = new byte[0]; | 4233 | |
4519 | objdata.Text = new byte[0]; | 4234 | // Rotation |
4520 | objdata.TextColor = new byte[4]; | 4235 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.X, -1.0f, 1.0f), data, pos); pos += 2; |
4521 | objdata.JointAxisOrAnchor = new Vector3(0, 0, 0); | 4236 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Y, -1.0f, 1.0f), data, pos); pos += 2; |
4522 | objdata.JointPivot = new Vector3(0, 0, 0); | 4237 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Z, -1.0f, 1.0f), data, pos); pos += 2; |
4523 | objdata.Material = 4; | 4238 | Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2; |
4524 | objdata.TextureAnim = new byte[0]; | 4239 | |
4525 | objdata.Sound = UUID.Zero; | 4240 | // Angular Velocity |
4526 | Primitive.TextureEntry ntex = new Primitive.TextureEntry(new UUID("00000000-0000-0000-5005-000000000005")); | 4241 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2; |
4527 | objdata.TextureEntry = ntex.GetBytes(); | 4242 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; |
4528 | 4243 | Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; | |
4529 | objdata.State = 0; | 4244 | |
4530 | objdata.Data = new byte[0]; | 4245 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); |
4531 | 4246 | block.Data = data; | |
4532 | objdata.ObjectData = new byte[76]; | 4247 | |
4533 | objdata.ObjectData[15] = 128; | 4248 | if (textureEntry != null && textureEntry.Length > 0) |
4534 | objdata.ObjectData[16] = 63; | 4249 | { |
4535 | objdata.ObjectData[56] = 128; | 4250 | byte[] teBytesFinal = new byte[textureEntry.Length + 4]; |
4536 | objdata.ObjectData[61] = 102; | 4251 | |
4537 | objdata.ObjectData[62] = 40; | 4252 | // Texture Length |
4538 | objdata.ObjectData[63] = 61; | 4253 | Utils.IntToBytes(textureEntry.Length, textureEntry, 0); |
4539 | objdata.ObjectData[64] = 189; | 4254 | // Texture |
4255 | Buffer.BlockCopy(textureEntry, 0, teBytesFinal, 4, textureEntry.Length); | ||
4256 | |||
4257 | block.TextureEntry = teBytesFinal; | ||
4258 | } | ||
4259 | else | ||
4260 | { | ||
4261 | block.TextureEntry = Utils.EmptyBytes; | ||
4262 | } | ||
4263 | |||
4264 | return block; | ||
4265 | } | ||
4266 | |||
4267 | protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data) | ||
4268 | { | ||
4269 | byte[] objectData = new byte[60]; | ||
4270 | data.Position.ToBytes(objectData, 0); | ||
4271 | //data.Velocity.ToBytes(objectData, 12); | ||
4272 | //data.Acceleration.ToBytes(objectData, 24); | ||
4273 | data.Rotation.ToBytes(objectData, 36); | ||
4274 | //data.AngularVelocity.ToBytes(objectData, 48); | ||
4275 | |||
4276 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | ||
4277 | |||
4278 | update.Data = Utils.EmptyBytes; | ||
4279 | update.ExtraParams = new byte[1]; | ||
4280 | update.FullID = data.AvatarID; | ||
4281 | update.ID = data.AvatarLocalID; | ||
4282 | update.Material = (byte)Material.Flesh; | ||
4283 | update.MediaURL = Utils.EmptyBytes; | ||
4284 | update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " + | ||
4285 | data.LastName + "\nTitle STRING RW SV " + data.GroupTitle); | ||
4286 | update.ObjectData = objectData; | ||
4287 | update.ParentID = data.ParentID; | ||
4288 | update.PathCurve = 16; | ||
4289 | update.PathScaleX = 100; | ||
4290 | update.PathScaleY = 100; | ||
4291 | update.PCode = (byte)PCode.Avatar; | ||
4292 | update.ProfileCurve = 1; | ||
4293 | update.PSBlock = Utils.EmptyBytes; | ||
4294 | update.Scale = Vector3.One; | ||
4295 | update.Text = Utils.EmptyBytes; | ||
4296 | update.TextColor = new byte[4]; | ||
4297 | update.TextureAnim = Utils.EmptyBytes; | ||
4298 | update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes; | ||
4299 | update.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags | ||
4300 | |||
4301 | return update; | ||
4302 | } | ||
4303 | |||
4304 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) | ||
4305 | { | ||
4306 | byte[] objectData = new byte[60]; | ||
4307 | data.pos.ToBytes(objectData, 0); | ||
4308 | data.vel.ToBytes(objectData, 12); | ||
4309 | data.acc.ToBytes(objectData, 24); | ||
4310 | data.rotation.ToBytes(objectData, 36); | ||
4311 | data.rvel.ToBytes(objectData, 48); | ||
4312 | |||
4313 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | ||
4314 | update.ClickAction = (byte)data.clickAction; | ||
4315 | update.CRC = 0; | ||
4316 | update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes; | ||
4317 | update.FullID = data.objectID; | ||
4318 | update.ID = data.localID; | ||
4319 | //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated | ||
4320 | //update.JointPivot = Vector3.Zero; | ||
4321 | //update.JointType = 0; | ||
4322 | update.Material = data.material; | ||
4323 | update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim | ||
4324 | if (data.attachment) | ||
4325 | { | ||
4326 | update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId); | ||
4327 | update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); | ||
4328 | } | ||
4329 | else | ||
4330 | { | ||
4331 | update.NameValue = Utils.EmptyBytes; | ||
4332 | update.State = data.primShape.State; | ||
4333 | } | ||
4334 | update.ObjectData = objectData; | ||
4335 | update.ParentID = data.parentID; | ||
4336 | update.PathBegin = data.primShape.PathBegin; | ||
4337 | update.PathCurve = data.primShape.PathCurve; | ||
4338 | update.PathEnd = data.primShape.PathEnd; | ||
4339 | update.PathRadiusOffset = data.primShape.PathRadiusOffset; | ||
4340 | update.PathRevolutions = data.primShape.PathRevolutions; | ||
4341 | update.PathScaleX = data.primShape.PathScaleX; | ||
4342 | update.PathScaleY = data.primShape.PathScaleY; | ||
4343 | update.PathShearX = data.primShape.PathShearX; | ||
4344 | update.PathShearY = data.primShape.PathShearY; | ||
4345 | update.PathSkew = data.primShape.PathSkew; | ||
4346 | update.PathTaperX = data.primShape.PathTaperX; | ||
4347 | update.PathTaperY = data.primShape.PathTaperY; | ||
4348 | update.PathTwist = data.primShape.PathTwist; | ||
4349 | update.PathTwistBegin = data.primShape.PathTwistBegin; | ||
4350 | update.PCode = data.primShape.PCode; | ||
4351 | update.ProfileBegin = data.primShape.ProfileBegin; | ||
4352 | update.ProfileCurve = data.primShape.ProfileCurve; | ||
4353 | update.ProfileEnd = data.primShape.ProfileEnd; | ||
4354 | update.ProfileHollow = data.primShape.ProfileHollow; | ||
4355 | update.PSBlock = data.particleSystem ?? Utils.EmptyBytes; | ||
4356 | update.TextColor = data.color ?? Color4.Black.GetBytes(true); | ||
4357 | update.TextureAnim = data.textureanim ?? Utils.EmptyBytes; | ||
4358 | update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes; | ||
4359 | update.Scale = data.primShape.Scale; | ||
4360 | update.Text = Util.StringToBytes256(data.text); | ||
4361 | update.UpdateFlags = (uint)data.flags; | ||
4362 | |||
4363 | if (data.SoundId != UUID.Zero) | ||
4364 | { | ||
4365 | update.Sound = data.SoundId; | ||
4366 | update.OwnerID = data.ownerID; | ||
4367 | update.Gain = (float)data.SoundVolume; | ||
4368 | update.Radius = (float)data.SoundRadius; | ||
4369 | update.Flags = data.SoundFlags; | ||
4370 | } | ||
4371 | |||
4372 | switch ((PCode)data.primShape.PCode) | ||
4373 | { | ||
4374 | case PCode.Grass: | ||
4375 | case PCode.Tree: | ||
4376 | case PCode.NewTree: | ||
4377 | update.Data = new byte[] { data.primShape.State }; | ||
4378 | break; | ||
4379 | default: | ||
4380 | // TODO: Support ScratchPad | ||
4381 | //if (prim.ScratchPad != null) | ||
4382 | //{ | ||
4383 | // update.Data = new byte[prim.ScratchPad.Length]; | ||
4384 | // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); | ||
4385 | //} | ||
4386 | //else | ||
4387 | //{ | ||
4388 | // update.Data = Utils.EmptyBytes; | ||
4389 | //} | ||
4390 | update.Data = Utils.EmptyBytes; | ||
4391 | break; | ||
4392 | } | ||
4393 | |||
4394 | return update; | ||
4540 | } | 4395 | } |
4541 | 4396 | ||
4542 | public void SendNameReply(UUID profileId, string firstname, string lastname) | 4397 | public void SendNameReply(UUID profileId, string firstname, string lastname) |
@@ -4546,8 +4401,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4546 | packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1]; | 4401 | packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1]; |
4547 | packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock(); | 4402 | packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock(); |
4548 | packet.UUIDNameBlock[0].ID = profileId; | 4403 | packet.UUIDNameBlock[0].ID = profileId; |
4549 | packet.UUIDNameBlock[0].FirstName = Utils.StringToBytes(firstname); | 4404 | packet.UUIDNameBlock[0].FirstName = Util.StringToBytes256(firstname); |
4550 | packet.UUIDNameBlock[0].LastName = Utils.StringToBytes(lastname); | 4405 | packet.UUIDNameBlock[0].LastName = Util.StringToBytes256(lastname); |
4551 | 4406 | ||
4552 | OutPacket(packet, ThrottleOutPacketType.Task); | 4407 | OutPacket(packet, ThrottleOutPacketType.Task); |
4553 | } | 4408 | } |
@@ -4743,8 +4598,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4743 | scriptQuestion.Data.TaskID = taskID; | 4598 | scriptQuestion.Data.TaskID = taskID; |
4744 | scriptQuestion.Data.ItemID = itemID; | 4599 | scriptQuestion.Data.ItemID = itemID; |
4745 | scriptQuestion.Data.Questions = question; | 4600 | scriptQuestion.Data.Questions = question; |
4746 | scriptQuestion.Data.ObjectName = Utils.StringToBytes(taskName); | 4601 | scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName); |
4747 | scriptQuestion.Data.ObjectOwner = Utils.StringToBytes(ownerName); | 4602 | scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName); |
4748 | 4603 | ||
4749 | OutPacket(scriptQuestion, ThrottleOutPacketType.Task); | 4604 | OutPacket(scriptQuestion, ThrottleOutPacketType.Task); |
4750 | } | 4605 | } |
@@ -5138,7 +4993,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5138 | if (m_moneyBalance + debit >= 0) | 4993 | if (m_moneyBalance + debit >= 0) |
5139 | { | 4994 | { |
5140 | m_moneyBalance += debit; | 4995 | m_moneyBalance += debit; |
5141 | SendMoneyBalance(UUID.Zero, true, Utils.StringToBytes("Poof Poof!"), m_moneyBalance); | 4996 | SendMoneyBalance(UUID.Zero, true, Util.StringToBytes256("Poof Poof!"), m_moneyBalance); |
5142 | return true; | 4997 | return true; |
5143 | } | 4998 | } |
5144 | return false; | 4999 | return false; |
@@ -8736,19 +8591,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
8736 | 8591 | ||
8737 | #endregion | 8592 | #endregion |
8738 | 8593 | ||
8594 | case PacketType.AgentFOV: | ||
8595 | AgentFOVPacket fovPacket = (AgentFOVPacket)Pack; | ||
8739 | 8596 | ||
8740 | #region unimplemented handlers | 8597 | if (fovPacket.FOVBlock.GenCounter > m_agentFOVCounter) |
8741 | 8598 | { | |
8742 | case PacketType.StartPingCheck: | 8599 | m_agentFOVCounter = fovPacket.FOVBlock.GenCounter; |
8743 | StartPingCheckPacket pingStart = (StartPingCheckPacket)Pack; | 8600 | AgentFOV handlerAgentFOV = OnAgentFOV; |
8744 | CompletePingCheckPacket pingComplete = new CompletePingCheckPacket(); | 8601 | if (handlerAgentFOV != null) |
8745 | pingComplete.PingID.PingID = pingStart.PingID.PingID; | 8602 | { |
8746 | m_udpServer.SendPacket(m_udpClient, pingComplete, ThrottleOutPacketType.Unknown, false); | 8603 | handlerAgentFOV(this, fovPacket.FOVBlock.VerticalAngle); |
8604 | } | ||
8605 | } | ||
8747 | break; | 8606 | break; |
8748 | 8607 | ||
8749 | case PacketType.CompletePingCheck: | 8608 | #region unimplemented handlers |
8750 | // TODO: Do stats tracking or something with these? | ||
8751 | break; | ||
8752 | 8609 | ||
8753 | case PacketType.ViewerStats: | 8610 | case PacketType.ViewerStats: |
8754 | // TODO: handle this packet | 8611 | // TODO: handle this packet |
@@ -9080,7 +8937,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9080 | new GroupTitlesReplyPacket.GroupDataBlock(); | 8937 | new GroupTitlesReplyPacket.GroupDataBlock(); |
9081 | 8938 | ||
9082 | groupTitlesReply.GroupData[i].Title = | 8939 | groupTitlesReply.GroupData[i].Title = |
9083 | Utils.StringToBytes(d.Name); | 8940 | Util.StringToBytes256(d.Name); |
9084 | groupTitlesReply.GroupData[i].RoleID = | 8941 | groupTitlesReply.GroupData[i].RoleID = |
9085 | d.UUID; | 8942 | d.UUID; |
9086 | groupTitlesReply.GroupData[i].Selected = | 8943 | groupTitlesReply.GroupData[i].Selected = |
@@ -9117,10 +8974,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9117 | groupProfileRequest.GroupData.GroupID); | 8974 | groupProfileRequest.GroupData.GroupID); |
9118 | 8975 | ||
9119 | groupProfileReply.GroupData.GroupID = d.GroupID; | 8976 | groupProfileReply.GroupData.GroupID = d.GroupID; |
9120 | groupProfileReply.GroupData.Name = Utils.StringToBytes(d.Name); | 8977 | groupProfileReply.GroupData.Name = Util.StringToBytes256(d.Name); |
9121 | groupProfileReply.GroupData.Charter = Utils.StringToBytes(d.Charter); | 8978 | groupProfileReply.GroupData.Charter = Util.StringToBytes1024(d.Charter); |
9122 | groupProfileReply.GroupData.ShowInList = d.ShowInList; | 8979 | groupProfileReply.GroupData.ShowInList = d.ShowInList; |
9123 | groupProfileReply.GroupData.MemberTitle = Utils.StringToBytes(d.MemberTitle); | 8980 | groupProfileReply.GroupData.MemberTitle = Util.StringToBytes256(d.MemberTitle); |
9124 | groupProfileReply.GroupData.PowersMask = d.PowersMask; | 8981 | groupProfileReply.GroupData.PowersMask = d.PowersMask; |
9125 | groupProfileReply.GroupData.InsigniaID = d.InsigniaID; | 8982 | groupProfileReply.GroupData.InsigniaID = d.InsigniaID; |
9126 | groupProfileReply.GroupData.FounderID = d.FounderID; | 8983 | groupProfileReply.GroupData.FounderID = d.FounderID; |
@@ -9192,11 +9049,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9192 | groupMembersReply.MemberData[i].Contribution = | 9049 | groupMembersReply.MemberData[i].Contribution = |
9193 | m.Contribution; | 9050 | m.Contribution; |
9194 | groupMembersReply.MemberData[i].OnlineStatus = | 9051 | groupMembersReply.MemberData[i].OnlineStatus = |
9195 | Utils.StringToBytes(m.OnlineStatus); | 9052 | Util.StringToBytes256(m.OnlineStatus); |
9196 | groupMembersReply.MemberData[i].AgentPowers = | 9053 | groupMembersReply.MemberData[i].AgentPowers = |
9197 | m.AgentPowers; | 9054 | m.AgentPowers; |
9198 | groupMembersReply.MemberData[i].Title = | 9055 | groupMembersReply.MemberData[i].Title = |
9199 | Utils.StringToBytes(m.Title); | 9056 | Util.StringToBytes256(m.Title); |
9200 | groupMembersReply.MemberData[i].IsOwner = | 9057 | groupMembersReply.MemberData[i].IsOwner = |
9201 | m.IsOwner; | 9058 | m.IsOwner; |
9202 | } | 9059 | } |
@@ -9257,11 +9114,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9257 | groupRolesReply.RoleData[i].RoleID = | 9114 | groupRolesReply.RoleData[i].RoleID = |
9258 | d.RoleID; | 9115 | d.RoleID; |
9259 | groupRolesReply.RoleData[i].Name = | 9116 | groupRolesReply.RoleData[i].Name = |
9260 | Utils.StringToBytes(d.Name); | 9117 | Util.StringToBytes256(d.Name); |
9261 | groupRolesReply.RoleData[i].Title = | 9118 | groupRolesReply.RoleData[i].Title = |
9262 | Utils.StringToBytes(d.Title); | 9119 | Util.StringToBytes256(d.Title); |
9263 | groupRolesReply.RoleData[i].Description = | 9120 | groupRolesReply.RoleData[i].Description = |
9264 | Utils.StringToBytes(d.Description); | 9121 | Util.StringToBytes1024(d.Description); |
9265 | groupRolesReply.RoleData[i].Powers = | 9122 | groupRolesReply.RoleData[i].Powers = |
9266 | d.Powers; | 9123 | d.Powers; |
9267 | groupRolesReply.RoleData[i].Members = | 9124 | groupRolesReply.RoleData[i].Members = |
@@ -9488,9 +9345,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9488 | groupNoticesListReply.Data[i].Timestamp = | 9345 | groupNoticesListReply.Data[i].Timestamp = |
9489 | g.Timestamp; | 9346 | g.Timestamp; |
9490 | groupNoticesListReply.Data[i].FromName = | 9347 | groupNoticesListReply.Data[i].FromName = |
9491 | Utils.StringToBytes(g.FromName); | 9348 | Util.StringToBytes256(g.FromName); |
9492 | groupNoticesListReply.Data[i].Subject = | 9349 | groupNoticesListReply.Data[i].Subject = |
9493 | Utils.StringToBytes(g.Subject); | 9350 | Util.StringToBytes256(g.Subject); |
9494 | groupNoticesListReply.Data[i].HasAttachment = | 9351 | groupNoticesListReply.Data[i].HasAttachment = |
9495 | g.HasAttachment; | 9352 | g.HasAttachment; |
9496 | groupNoticesListReply.Data[i].AssetType = | 9353 | groupNoticesListReply.Data[i].AssetType = |
@@ -10089,12 +9946,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10089 | byte mediaLoop) | 9946 | byte mediaLoop) |
10090 | { | 9947 | { |
10091 | ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket(); | 9948 | ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket(); |
10092 | updatePacket.DataBlock.MediaURL = Utils.StringToBytes(mediaUrl); | 9949 | updatePacket.DataBlock.MediaURL = Util.StringToBytes256(mediaUrl); |
10093 | updatePacket.DataBlock.MediaID = mediaTextureID; | 9950 | updatePacket.DataBlock.MediaID = mediaTextureID; |
10094 | updatePacket.DataBlock.MediaAutoScale = autoScale; | 9951 | updatePacket.DataBlock.MediaAutoScale = autoScale; |
10095 | 9952 | ||
10096 | updatePacket.DataBlockExtended.MediaType = Utils.StringToBytes(mediaType); | 9953 | updatePacket.DataBlockExtended.MediaType = Util.StringToBytes256(mediaType); |
10097 | updatePacket.DataBlockExtended.MediaDesc = Utils.StringToBytes(mediaDesc); | 9954 | updatePacket.DataBlockExtended.MediaDesc = Util.StringToBytes256(mediaDesc); |
10098 | updatePacket.DataBlockExtended.MediaWidth = mediaWidth; | 9955 | updatePacket.DataBlockExtended.MediaWidth = mediaWidth; |
10099 | updatePacket.DataBlockExtended.MediaHeight = mediaHeight; | 9956 | updatePacket.DataBlockExtended.MediaHeight = mediaHeight; |
10100 | updatePacket.DataBlockExtended.MediaLoop = mediaLoop; | 9957 | updatePacket.DataBlockExtended.MediaLoop = mediaLoop; |
@@ -10371,5 +10228,166 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10371 | pack.TextureData.TextureID = textureID; | 10228 | pack.TextureData.TextureID = textureID; |
10372 | OutPacket(pack, ThrottleOutPacketType.Task); | 10229 | OutPacket(pack, ThrottleOutPacketType.Task); |
10373 | } | 10230 | } |
10231 | |||
10232 | #region PriorityQueue | ||
10233 | private class PriorityQueue<TPriority, TValue> | ||
10234 | { | ||
10235 | internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id); | ||
10236 | |||
10237 | private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[1]; | ||
10238 | private Dictionary<uint, LookupItem> m_lookupTable; | ||
10239 | private Comparison<TPriority> m_comparison; | ||
10240 | private object m_syncRoot = new object(); | ||
10241 | |||
10242 | internal PriorityQueue() : | ||
10243 | this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { } | ||
10244 | internal PriorityQueue(int capacity) : | ||
10245 | this(capacity, Comparer<TPriority>.Default) { } | ||
10246 | internal PriorityQueue(IComparer<TPriority> comparer) : | ||
10247 | this(new Comparison<TPriority>(comparer.Compare)) { } | ||
10248 | internal PriorityQueue(Comparison<TPriority> comparison) : | ||
10249 | this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, comparison) { } | ||
10250 | internal PriorityQueue(int capacity, IComparer<TPriority> comparer) : | ||
10251 | this(capacity, new Comparison<TPriority>(comparer.Compare)) { } | ||
10252 | internal PriorityQueue(int capacity, Comparison<TPriority> comparison) | ||
10253 | { | ||
10254 | m_lookupTable = new Dictionary<uint, LookupItem>(capacity); | ||
10255 | |||
10256 | for (int i = 0; i < m_heaps.Length; ++i) | ||
10257 | m_heaps[i] = new MinHeap<MinHeapItem>(capacity); | ||
10258 | this.m_comparison = comparison; | ||
10259 | } | ||
10260 | |||
10261 | internal object SyncRoot { get { return this.m_syncRoot; } } | ||
10262 | internal int Count | ||
10263 | { | ||
10264 | get | ||
10265 | { | ||
10266 | int count = 0; | ||
10267 | for (int i = 0; i < m_heaps.Length; ++i) | ||
10268 | count = m_heaps[i].Count; | ||
10269 | return count; | ||
10270 | } | ||
10271 | } | ||
10272 | |||
10273 | internal bool Enqueue(TPriority priority, TValue value, uint local_id) | ||
10274 | { | ||
10275 | LookupItem item; | ||
10276 | |||
10277 | if (m_lookupTable.TryGetValue(local_id, out item)) | ||
10278 | { | ||
10279 | item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.m_comparison); | ||
10280 | return false; | ||
10281 | } | ||
10282 | else | ||
10283 | { | ||
10284 | item.Heap = m_heaps[0]; | ||
10285 | item.Heap.Add(new MinHeapItem(priority, value, local_id, this.m_comparison), ref item.Handle); | ||
10286 | m_lookupTable.Add(local_id, item); | ||
10287 | return true; | ||
10288 | } | ||
10289 | } | ||
10290 | |||
10291 | internal TValue Peek() | ||
10292 | { | ||
10293 | for (int i = 0; i < m_heaps.Length; ++i) | ||
10294 | if (m_heaps[i].Count > 0) | ||
10295 | return m_heaps[i].Min().Value; | ||
10296 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | ||
10297 | } | ||
10298 | |||
10299 | internal TValue Dequeue() | ||
10300 | { | ||
10301 | for (int i = 0; i < m_heaps.Length; ++i) | ||
10302 | { | ||
10303 | if (m_heaps[i].Count > 0) | ||
10304 | { | ||
10305 | MinHeapItem item = m_heaps[i].RemoveMin(); | ||
10306 | m_lookupTable.Remove(item.LocalID); | ||
10307 | return item.Value; | ||
10308 | } | ||
10309 | } | ||
10310 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | ||
10311 | } | ||
10312 | |||
10313 | internal void Reprioritize(UpdatePriorityHandler handler) | ||
10314 | { | ||
10315 | MinHeapItem item; | ||
10316 | TPriority priority; | ||
10317 | |||
10318 | foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values)) | ||
10319 | { | ||
10320 | if (lookup.Heap.TryGetValue(lookup.Handle, out item)) | ||
10321 | { | ||
10322 | priority = item.Priority; | ||
10323 | if (handler(ref priority, item.LocalID)) | ||
10324 | { | ||
10325 | if (lookup.Heap.ContainsHandle(lookup.Handle)) | ||
10326 | lookup.Heap[lookup.Handle] = | ||
10327 | new MinHeapItem(priority, item.Value, item.LocalID); | ||
10328 | } | ||
10329 | else | ||
10330 | { | ||
10331 | m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update"); | ||
10332 | lookup.Heap.Remove(lookup.Handle); | ||
10333 | this.m_lookupTable.Remove(item.LocalID); | ||
10334 | } | ||
10335 | } | ||
10336 | } | ||
10337 | } | ||
10338 | |||
10339 | #region MinHeapItem | ||
10340 | private struct MinHeapItem : IComparable<MinHeapItem> | ||
10341 | { | ||
10342 | private TPriority priority; | ||
10343 | private TValue value; | ||
10344 | private uint local_id; | ||
10345 | private Comparison<TPriority> comparison; | ||
10346 | |||
10347 | internal MinHeapItem(TPriority priority, TValue value, uint local_id) : | ||
10348 | this(priority, value, local_id, Comparer<TPriority>.Default) { } | ||
10349 | internal MinHeapItem(TPriority priority, TValue value, uint local_id, IComparer<TPriority> comparer) : | ||
10350 | this(priority, value, local_id, new Comparison<TPriority>(comparer.Compare)) { } | ||
10351 | internal MinHeapItem(TPriority priority, TValue value, uint local_id, Comparison<TPriority> comparison) | ||
10352 | { | ||
10353 | this.priority = priority; | ||
10354 | this.value = value; | ||
10355 | this.local_id = local_id; | ||
10356 | this.comparison = comparison; | ||
10357 | } | ||
10358 | |||
10359 | internal TPriority Priority { get { return this.priority; } } | ||
10360 | internal TValue Value { get { return this.value; } } | ||
10361 | internal uint LocalID { get { return this.local_id; } } | ||
10362 | |||
10363 | public override string ToString() | ||
10364 | { | ||
10365 | StringBuilder sb = new StringBuilder(); | ||
10366 | sb.Append("["); | ||
10367 | if (this.priority != null) | ||
10368 | sb.Append(this.priority.ToString()); | ||
10369 | sb.Append(","); | ||
10370 | if (this.value != null) | ||
10371 | sb.Append(this.value.ToString()); | ||
10372 | sb.Append("]"); | ||
10373 | return sb.ToString(); | ||
10374 | } | ||
10375 | |||
10376 | public int CompareTo(MinHeapItem other) | ||
10377 | { | ||
10378 | return this.comparison(this.priority, other.priority); | ||
10379 | } | ||
10380 | } | ||
10381 | #endregion | ||
10382 | |||
10383 | #region LookupItem | ||
10384 | private struct LookupItem { | ||
10385 | internal MinHeap<MinHeapItem> Heap; | ||
10386 | internal IHandle Handle; | ||
10387 | } | ||
10388 | #endregion | ||
10389 | } | ||
10390 | #endregion | ||
10391 | |||
10374 | } | 10392 | } |
10375 | } | 10393 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index d25bf95..938cf50 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | |||
@@ -51,7 +51,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
51 | 51 | ||
52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
53 | private bool m_shuttingdown; | 53 | private bool m_shuttingdown; |
54 | private long m_lastloopprocessed; | ||
55 | private AssetBase m_missingImage; | 54 | private AssetBase m_missingImage; |
56 | private LLClientView m_client; //Client we're assigned to | 55 | private LLClientView m_client; //Client we're assigned to |
57 | private IAssetService m_assetCache; //Asset Cache | 56 | private IAssetService m_assetCache; //Asset Cache |
@@ -169,7 +168,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
169 | 168 | ||
170 | public bool ProcessImageQueue(int packetsToSend) | 169 | public bool ProcessImageQueue(int packetsToSend) |
171 | { | 170 | { |
172 | m_lastloopprocessed = DateTime.Now.Ticks; | ||
173 | int packetsSent = 0; | 171 | int packetsSent = 0; |
174 | 172 | ||
175 | while (packetsSent < packetsToSend) | 173 | while (packetsSent < packetsToSend) |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 4eee6b6..4b6a358 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -170,7 +170,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
170 | { | 170 | { |
171 | ThrottleOutPacketType type = (ThrottleOutPacketType)i; | 171 | ThrottleOutPacketType type = (ThrottleOutPacketType)i; |
172 | 172 | ||
173 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens | ||
173 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); | 174 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); |
175 | // Initialize the token buckets that control the throttling for each category | ||
174 | m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); | 176 | m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); |
175 | } | 177 | } |
176 | 178 | ||
@@ -293,36 +295,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
293 | int state = (int)((float)task * STATE_TASK_PERCENTAGE); | 295 | int state = (int)((float)task * STATE_TASK_PERCENTAGE); |
294 | task -= state; | 296 | task -= state; |
295 | 297 | ||
296 | int ceiling = Int32.MaxValue; | 298 | // Make sure none of the throttles are set below our packet MTU, |
297 | if (m_defaultThrottleRates.Total != 0) | 299 | // otherwise a throttle could become permanently clogged |
298 | { | 300 | resend = Math.Max(resend, LLUDPServer.MTU); |
299 | ceiling = m_defaultThrottleRates.Total; | 301 | land = Math.Max(land, LLUDPServer.MTU); |
300 | if (ceiling < Packet.MTU) ceiling = Packet.MTU; | 302 | wind = Math.Max(wind, LLUDPServer.MTU); |
301 | } | 303 | cloud = Math.Max(cloud, LLUDPServer.MTU); |
302 | 304 | task = Math.Max(task, LLUDPServer.MTU); | |
303 | resend = Utils.Clamp(resend, Packet.MTU, ceiling); | 305 | texture = Math.Max(texture, LLUDPServer.MTU); |
304 | land = Utils.Clamp(land, Packet.MTU, ceiling); | 306 | asset = Math.Max(asset, LLUDPServer.MTU); |
305 | wind = Utils.Clamp(wind, Packet.MTU, ceiling); | 307 | state = Math.Max(state, LLUDPServer.MTU); |
306 | cloud = Utils.Clamp(cloud, Packet.MTU, ceiling); | ||
307 | task = Utils.Clamp(task, Packet.MTU, ceiling); | ||
308 | texture = Utils.Clamp(texture, Packet.MTU, ceiling); | ||
309 | asset = Utils.Clamp(asset, Packet.MTU, ceiling); | ||
310 | state = Utils.Clamp(state, Packet.MTU, ceiling); | ||
311 | 308 | ||
312 | int total = resend + land + wind + cloud + task + texture + asset + state; | 309 | int total = resend + land + wind + cloud + task + texture + asset + state; |
313 | int taskTotal = task + state; | ||
314 | 310 | ||
315 | m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}", | 311 | m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, Total={9}", |
316 | AgentID, resend, land, wind, cloud, task, texture, asset, state, total); | 312 | AgentID, resend, land, wind, cloud, task, texture, asset, state, total); |
317 | 313 | ||
318 | SetThrottle(ThrottleOutPacketType.Resend, resend, resend); | 314 | // Update the token buckets with new throttle values |
319 | SetThrottle(ThrottleOutPacketType.Land, land, land); | 315 | TokenBucket bucket; |
320 | SetThrottle(ThrottleOutPacketType.Wind, wind, wind); | 316 | |
321 | SetThrottle(ThrottleOutPacketType.Cloud, cloud, cloud); | 317 | bucket = m_throttle; |
322 | SetThrottle(ThrottleOutPacketType.Task, task, taskTotal); | 318 | bucket.MaxBurst = total; |
323 | SetThrottle(ThrottleOutPacketType.Texture, texture, texture); | 319 | |
324 | SetThrottle(ThrottleOutPacketType.Asset, asset, asset); | 320 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
325 | SetThrottle(ThrottleOutPacketType.State, state, taskTotal); | 321 | bucket.DripRate = bucket.MaxBurst = resend; |
322 | |||
323 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; | ||
324 | bucket.DripRate = bucket.MaxBurst = land; | ||
325 | |||
326 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; | ||
327 | bucket.DripRate = bucket.MaxBurst = wind; | ||
328 | |||
329 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; | ||
330 | bucket.DripRate = bucket.MaxBurst = cloud; | ||
331 | |||
332 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; | ||
333 | bucket.DripRate = bucket.MaxBurst = asset; | ||
334 | |||
335 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; | ||
336 | bucket.DripRate = task + state + texture; | ||
337 | bucket.MaxBurst = task + state + texture; | ||
338 | |||
339 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.State]; | ||
340 | bucket.DripRate = state + texture; | ||
341 | bucket.MaxBurst = state + texture; | ||
342 | |||
343 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; | ||
344 | bucket.DripRate = texture; | ||
345 | bucket.MaxBurst = texture; | ||
326 | } | 346 | } |
327 | 347 | ||
328 | public byte[] GetThrottlesPacked() | 348 | public byte[] GetThrottlesPacked() |
@@ -342,17 +362,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
342 | return data; | 362 | return data; |
343 | } | 363 | } |
344 | 364 | ||
345 | public void SetThrottle(ThrottleOutPacketType category, int rate, int maxBurst) | ||
346 | { | ||
347 | int i = (int)category; | ||
348 | if (i >= 0 && i < m_throttleCategories.Length) | ||
349 | { | ||
350 | TokenBucket bucket = m_throttleCategories[(int)category]; | ||
351 | bucket.DripRate = rate; | ||
352 | bucket.MaxBurst = maxBurst; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | public bool EnqueueOutgoing(OutgoingPacket packet) | 365 | public bool EnqueueOutgoing(OutgoingPacket packet) |
357 | { | 366 | { |
358 | int category = (int)packet.Category; | 367 | int category = (int)packet.Category; |
@@ -395,9 +404,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
395 | TokenBucket bucket; | 404 | TokenBucket bucket; |
396 | bool packetSent = false; | 405 | bool packetSent = false; |
397 | 406 | ||
407 | //string queueDebugOutput = String.Empty; // Serious debug business | ||
408 | |||
398 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) | 409 | for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) |
399 | { | 410 | { |
400 | bucket = m_throttleCategories[i]; | 411 | bucket = m_throttleCategories[i]; |
412 | //queueDebugOutput += m_packetOutboxes[i].Count + " "; // Serious debug business | ||
401 | 413 | ||
402 | if (m_nextPackets[i] != null) | 414 | if (m_nextPackets[i] != null) |
403 | { | 415 | { |
@@ -449,6 +461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
449 | } | 461 | } |
450 | } | 462 | } |
451 | 463 | ||
464 | //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business | ||
452 | return packetSent; | 465 | return packetSent; |
453 | } | 466 | } |
454 | 467 | ||
@@ -493,8 +506,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
493 | /// for</param> | 506 | /// for</param> |
494 | private void BeginFireQueueEmpty(int throttleIndex) | 507 | private void BeginFireQueueEmpty(int throttleIndex) |
495 | { | 508 | { |
496 | if (!m_onQueueEmptyRunning[throttleIndex]) | 509 | // Unknown is -1 and Resend is 0. Make sure we are only firing the |
497 | Util.FireAndForget(FireQueueEmpty, throttleIndex); | 510 | // callback for categories other than those |
511 | if (throttleIndex > 0) | ||
512 | { | ||
513 | if (!m_onQueueEmptyRunning[throttleIndex]) | ||
514 | Util.FireAndForget(FireQueueEmpty, throttleIndex); | ||
515 | } | ||
498 | } | 516 | } |
499 | 517 | ||
500 | /// <summary> | 518 | /// <summary> |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 545a0bc..74175d0 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -89,6 +89,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
89 | /// </summary> | 89 | /// </summary> |
90 | public class LLUDPServer : OpenSimUDPBase | 90 | public class LLUDPServer : OpenSimUDPBase |
91 | { | 91 | { |
92 | /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> | ||
93 | public const int MTU = 1400; | ||
94 | |||
92 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 95 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
93 | 96 | ||
94 | /// <summary>Handlers for incoming packets</summary> | 97 | /// <summary>Handlers for incoming packets</summary> |
@@ -104,7 +107,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
104 | /// <summary>Manages authentication for agent circuits</summary> | 107 | /// <summary>Manages authentication for agent circuits</summary> |
105 | private AgentCircuitManager m_circuitManager; | 108 | private AgentCircuitManager m_circuitManager; |
106 | /// <summary>Reference to the scene this UDP server is attached to</summary> | 109 | /// <summary>Reference to the scene this UDP server is attached to</summary> |
107 | private IScene m_scene; | 110 | private Scene m_scene; |
108 | /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> | 111 | /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> |
109 | private Location m_location; | 112 | private Location m_location; |
110 | /// <summary>The measured resolution of Environment.TickCount</summary> | 113 | /// <summary>The measured resolution of Environment.TickCount</summary> |
@@ -181,15 +184,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
181 | 184 | ||
182 | public void AddScene(IScene scene) | 185 | public void AddScene(IScene scene) |
183 | { | 186 | { |
184 | if (m_scene == null) | 187 | if (m_scene != null) |
185 | { | 188 | { |
186 | m_scene = scene; | 189 | m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene"); |
187 | m_location = new Location(m_scene.RegionInfo.RegionHandle); | 190 | return; |
188 | } | 191 | } |
189 | else | 192 | |
193 | if (!(scene is Scene)) | ||
190 | { | 194 | { |
191 | m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene"); | 195 | m_log.Error("[LLUDPSERVER]: AddScene() called with an unrecognized scene type " + scene.GetType()); |
196 | return; | ||
192 | } | 197 | } |
198 | |||
199 | m_scene = (Scene)scene; | ||
200 | m_location = new Location(m_scene.RegionInfo.RegionHandle); | ||
193 | } | 201 | } |
194 | 202 | ||
195 | public bool HandlesRegion(Location x) | 203 | public bool HandlesRegion(Location x) |
@@ -267,38 +275,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
267 | { | 275 | { |
268 | int dataLength = data.Length; | 276 | int dataLength = data.Length; |
269 | bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0; | 277 | bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0; |
278 | bool doCopy = true; | ||
270 | 279 | ||
271 | // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum. | 280 | // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum. |
272 | // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting | 281 | // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting |
273 | // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here | 282 | // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here |
274 | // to accomodate for both common scenarios and provide ample room for ACK appending in both | 283 | // to accomodate for both common scenarios and provide ample room for ACK appending in both |
275 | int bufferSize = (dataLength > 180) ? Packet.MTU : 200; | 284 | int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; |
276 | 285 | ||
277 | UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); | 286 | UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); |
278 | 287 | ||
279 | // Zerocode if needed | 288 | // Zerocode if needed |
280 | if (doZerocode) | 289 | if (doZerocode) |
281 | { | 290 | { |
282 | try { dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data); } | 291 | try |
292 | { | ||
293 | dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data); | ||
294 | doCopy = false; | ||
295 | } | ||
283 | catch (IndexOutOfRangeException) | 296 | catch (IndexOutOfRangeException) |
284 | { | 297 | { |
285 | // The packet grew larger than the bufferSize while zerocoding. | 298 | // The packet grew larger than the bufferSize while zerocoding. |
286 | // Remove the MSG_ZEROCODED flag and send the unencoded data | 299 | // Remove the MSG_ZEROCODED flag and send the unencoded data |
287 | // instead | 300 | // instead |
288 | m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". Removing MSG_ZEROCODED flag"); | 301 | m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength + |
302 | " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag"); | ||
289 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); | 303 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); |
290 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | ||
291 | } | 304 | } |
292 | } | 305 | } |
293 | else | 306 | |
307 | // If the packet data wasn't already copied during zerocoding, copy it now | ||
308 | if (doCopy) | ||
294 | { | 309 | { |
295 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | 310 | if (dataLength <= buffer.Data.Length) |
311 | { | ||
312 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | ||
313 | } | ||
314 | else | ||
315 | { | ||
316 | m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + | ||
317 | type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length + ". Dropping packet"); | ||
318 | return; | ||
319 | } | ||
296 | } | 320 | } |
321 | |||
297 | buffer.DataLength = dataLength; | 322 | buffer.DataLength = dataLength; |
298 | 323 | ||
299 | #region Queue or Send | 324 | #region Queue or Send |
300 | 325 | ||
301 | // Look up the UDPClient this is going to | ||
302 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); | 326 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); |
303 | 327 | ||
304 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) | 328 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) |
@@ -513,7 +537,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
513 | IClientAPI client; | 537 | IClientAPI client; |
514 | if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) | 538 | if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) |
515 | { | 539 | { |
516 | m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + | 540 | m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + |
517 | " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients"); | 541 | " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients"); |
518 | return; | 542 | return; |
519 | } | 543 | } |
@@ -553,6 +577,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
553 | for (int i = 0; i < ackPacket.Packets.Length; i++) | 577 | for (int i = 0; i < ackPacket.Packets.Length; i++) |
554 | AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent); | 578 | AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent); |
555 | } | 579 | } |
580 | |||
581 | // We don't need to do anything else with PacketAck packets | ||
582 | return; | ||
556 | } | 583 | } |
557 | 584 | ||
558 | #endregion ACK Receiving | 585 | #endregion ACK Receiving |
@@ -560,20 +587,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
560 | #region ACK Sending | 587 | #region ACK Sending |
561 | 588 | ||
562 | if (packet.Header.Reliable) | 589 | if (packet.Header.Reliable) |
590 | { | ||
563 | udpClient.PendingAcks.Enqueue(packet.Header.Sequence); | 591 | udpClient.PendingAcks.Enqueue(packet.Header.Sequence); |
564 | 592 | ||
565 | // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, | 593 | // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, |
566 | // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove | 594 | // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove |
567 | // 2*MTU bytes from the value and send ACKs, and finally add the local value back to | 595 | // 2*MTU bytes from the value and send ACKs, and finally add the local value back to |
568 | // client.BytesSinceLastACK. Lockless thread safety | 596 | // client.BytesSinceLastACK. Lockless thread safety |
569 | int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0); | 597 | int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0); |
570 | bytesSinceLastACK += buffer.DataLength; | 598 | bytesSinceLastACK += buffer.DataLength; |
571 | if (bytesSinceLastACK > Packet.MTU * 2) | 599 | if (bytesSinceLastACK > LLUDPServer.MTU * 2) |
572 | { | 600 | { |
573 | bytesSinceLastACK -= Packet.MTU * 2; | 601 | bytesSinceLastACK -= LLUDPServer.MTU * 2; |
574 | SendAcks(udpClient); | 602 | SendAcks(udpClient); |
603 | } | ||
604 | Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK); | ||
575 | } | 605 | } |
576 | Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK); | ||
577 | 606 | ||
578 | #endregion ACK Sending | 607 | #endregion ACK Sending |
579 | 608 | ||
@@ -593,12 +622,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
593 | 622 | ||
594 | #endregion Incoming Packet Accounting | 623 | #endregion Incoming Packet Accounting |
595 | 624 | ||
596 | // Don't bother clogging up the queue with PacketAck packets that are already handled here | 625 | #region Ping Check Handling |
597 | if (packet.Type != PacketType.PacketAck) | 626 | |
627 | if (packet.Type == PacketType.StartPingCheck) | ||
628 | { | ||
629 | // We don't need to do anything else with ping checks | ||
630 | StartPingCheckPacket startPing = (StartPingCheckPacket)packet; | ||
631 | |||
632 | CompletePingCheckPacket completePing = new CompletePingCheckPacket(); | ||
633 | completePing.PingID.PingID = startPing.PingID.PingID; | ||
634 | SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false); | ||
635 | return; | ||
636 | } | ||
637 | else if (packet.Type == PacketType.CompletePingCheck) | ||
598 | { | 638 | { |
599 | // Inbox insertion | 639 | // We don't currently track client ping times |
600 | packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); | 640 | return; |
601 | } | 641 | } |
642 | |||
643 | #endregion Ping Check Handling | ||
644 | |||
645 | // Inbox insertion | ||
646 | packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); | ||
602 | } | 647 | } |
603 | 648 | ||
604 | protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent) | 649 | protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent) |
@@ -693,12 +738,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
693 | // on to en-US to avoid number parsing issues | 738 | // on to en-US to avoid number parsing issues |
694 | Culture.SetCurrentCulture(); | 739 | Culture.SetCurrentCulture(); |
695 | 740 | ||
696 | IncomingPacket incomingPacket = null; | ||
697 | |||
698 | while (base.IsRunning) | 741 | while (base.IsRunning) |
699 | { | 742 | { |
700 | if (packetInbox.Dequeue(100, ref incomingPacket)) | 743 | IncomingPacket incomingPacket = null; |
701 | Util.FireAndForget(ProcessInPacket, incomingPacket); | 744 | |
745 | try | ||
746 | { | ||
747 | if (packetInbox.Dequeue(100, ref incomingPacket)) | ||
748 | Util.FireAndForget(ProcessInPacket, incomingPacket); | ||
749 | } | ||
750 | catch (Exception ex) | ||
751 | { | ||
752 | m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex); | ||
753 | } | ||
702 | } | 754 | } |
703 | 755 | ||
704 | if (packetInbox.Count > 0) | 756 | if (packetInbox.Count > 0) |
@@ -747,7 +799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
747 | elapsed500MS = 0; | 799 | elapsed500MS = 0; |
748 | } | 800 | } |
749 | 801 | ||
750 | m_scene.ClientManager.ForEach( | 802 | m_scene.ClientManager.ForEachSync( |
751 | delegate(IClientAPI client) | 803 | delegate(IClientAPI client) |
752 | { | 804 | { |
753 | if (client is LLClientView) | 805 | if (client is LLClientView) |
diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 66a9b5a..cd59bdb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | |||
@@ -224,11 +224,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat | |||
224 | 224 | ||
225 | foreach (Scene s in m_scenes) | 225 | foreach (Scene s in m_scenes) |
226 | { | 226 | { |
227 | s.ForEachScenePresence(delegate(ScenePresence presence) | 227 | s.ForEachScenePresence( |
228 | { | 228 | delegate(ScenePresence presence) |
229 | TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, | 229 | { |
230 | c.Type, message, sourceType); | 230 | TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType); |
231 | }); | 231 | } |
232 | ); | ||
232 | } | 233 | } |
233 | } | 234 | } |
234 | 235 | ||
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 4896edf..3bb162e 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -756,7 +756,7 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
756 | 756 | ||
757 | public void sendRegionHandshakeToAll() | 757 | public void sendRegionHandshakeToAll() |
758 | { | 758 | { |
759 | m_scene.Broadcast(sendRegionHandshake); | 759 | m_scene.ForEachClient(sendRegionHandshake); |
760 | } | 760 | } |
761 | 761 | ||
762 | public void handleEstateChangeInfo(IClientAPI remoteClient, UUID invoice, UUID senderID, UInt32 parms1, UInt32 parms2) | 762 | public void handleEstateChangeInfo(IClientAPI remoteClient, UUID invoice, UUID senderID, UInt32 parms1, UInt32 parms2) |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index d2b5cb1..53c64cb 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -147,9 +147,10 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
147 | client.OnParcelDwellRequest += ClientOnParcelDwellRequest; | 147 | client.OnParcelDwellRequest += ClientOnParcelDwellRequest; |
148 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; | 148 | client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; |
149 | 149 | ||
150 | if (m_scene.Entities.ContainsKey(client.AgentId)) | 150 | EntityBase presenceEntity; |
151 | if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) | ||
151 | { | 152 | { |
152 | SendLandUpdate((ScenePresence)m_scene.Entities[client.AgentId], true); | 153 | SendLandUpdate((ScenePresence)presenceEntity, true); |
153 | SendParcelOverlay(client); | 154 | SendParcelOverlay(client); |
154 | } | 155 | } |
155 | } | 156 | } |
@@ -1061,7 +1062,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1061 | { | 1062 | { |
1062 | land.LandData.OwnerID = ownerID; | 1063 | land.LandData.OwnerID = ownerID; |
1063 | 1064 | ||
1064 | m_scene.Broadcast(SendParcelOverlay); | 1065 | m_scene.ForEachClient(SendParcelOverlay); |
1065 | land.SendLandUpdateToClient(remote_client); | 1066 | land.SendLandUpdateToClient(remote_client); |
1066 | } | 1067 | } |
1067 | } | 1068 | } |
@@ -1083,7 +1084,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1083 | land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 1084 | land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
1084 | else | 1085 | else |
1085 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 1086 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
1086 | m_scene.Broadcast(SendParcelOverlay); | 1087 | m_scene.ForEachClient(SendParcelOverlay); |
1087 | land.SendLandUpdateToClient(remote_client); | 1088 | land.SendLandUpdateToClient(remote_client); |
1088 | } | 1089 | } |
1089 | } | 1090 | } |
@@ -1107,7 +1108,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1107 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 1108 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
1108 | land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | 1109 | land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); |
1109 | land.LandData.IsGroupOwned = false; | 1110 | land.LandData.IsGroupOwned = false; |
1110 | m_scene.Broadcast(SendParcelOverlay); | 1111 | m_scene.ForEachClient(SendParcelOverlay); |
1111 | land.SendLandUpdateToClient(remote_client); | 1112 | land.SendLandUpdateToClient(remote_client); |
1112 | } | 1113 | } |
1113 | } | 1114 | } |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index b9b7da5..bfe85f1 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs | |||
@@ -139,10 +139,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
139 | } | 139 | } |
140 | else | 140 | else |
141 | { | 141 | { |
142 | //Normal Calculations | 142 | // Normal Calculations |
143 | return Convert.ToInt32( | 143 | return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.objectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); |
144 | Math.Round((Convert.ToDecimal(LandData.Area) / Convert.ToDecimal(65536)) * m_scene.objectCapacity * | ||
145 | Convert.ToDecimal(m_scene.RegionInfo.RegionSettings.ObjectBonus))); ; | ||
146 | } | 144 | } |
147 | } | 145 | } |
148 | public int GetSimulatorMaxPrimCount(ILandObject thisObject) | 146 | public int GetSimulatorMaxPrimCount(ILandObject thisObject) |
diff --git a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs b/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs index 6499915..d8c5ed9 100644 --- a/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/RegionCombinerModule.cs | |||
@@ -81,8 +81,12 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
81 | 81 | ||
82 | public void RegionLoaded(Scene scene) | 82 | public void RegionLoaded(Scene scene) |
83 | { | 83 | { |
84 | if (!enabledYN) | 84 | if (enabledYN) |
85 | return; | 85 | RegionLoadedDoWork(scene); |
86 | } | ||
87 | |||
88 | private void RegionLoadedDoWork(Scene scene) | ||
89 | { | ||
86 | /* | 90 | /* |
87 | // For testing on a single instance | 91 | // For testing on a single instance |
88 | if (scene.RegionInfo.RegionLocX == 1004 && scene.RegionInfo.RegionLocY == 1000) | 92 | if (scene.RegionInfo.RegionLocX == 1004 && scene.RegionInfo.RegionLocY == 1000) |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index d651fd4..5a5fcfe 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | |||
@@ -499,13 +499,11 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
499 | { | 499 | { |
500 | } | 500 | } |
501 | 501 | ||
502 | public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | 502 | public virtual void SendAvatarData(SendAvatarData data) |
503 | uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
504 | { | 503 | { |
505 | } | 504 | } |
506 | 505 | ||
507 | public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | 506 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) |
508 | Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid) | ||
509 | { | 507 | { |
510 | } | 508 | } |
511 | 509 | ||
@@ -521,27 +519,15 @@ namespace OpenSim.Region.Examples.SimpleModule | |||
521 | { | 519 | { |
522 | } | 520 | } |
523 | 521 | ||
524 | public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, | 522 | public virtual void SendPrimitiveToClient(SendPrimitiveData data) |
525 | PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, | ||
526 | Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, | ||
527 | UUID objectID, UUID ownerID, string text, byte[] color, | ||
528 | uint parentID, | ||
529 | byte[] particleSystem, byte clickAction, byte material) | ||
530 | { | 523 | { |
531 | } | 524 | } |
532 | public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, | 525 | |
533 | PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, | 526 | public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
534 | Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, | ||
535 | UUID objectID, UUID ownerID, string text, byte[] color, | ||
536 | uint parentID, | ||
537 | byte[] particleSystem, byte clickAction, byte material, byte[] textureanimation, | ||
538 | bool attachment, uint AttachmentPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) | ||
539 | { | 527 | { |
540 | } | 528 | } |
541 | public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | 529 | |
542 | Vector3 position, Quaternion rotation, Vector3 velocity, | 530 | public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) |
543 | Vector3 rotationalvelocity, byte state, UUID AssetId, | ||
544 | UUID ownerID, int attachPoint) | ||
545 | { | 531 | { |
546 | } | 532 | } |
547 | 533 | ||
diff --git a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs index 8e3f4a0..7251d57 100644 --- a/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs +++ b/OpenSim/Region/Framework/Interfaces/ISceneViewer.cs | |||
@@ -34,7 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces | |||
34 | { | 34 | { |
35 | void Reset(); | 35 | void Reset(); |
36 | void Close(); | 36 | void Close(); |
37 | int MaxPrimsPerFrame { get; set; } | ||
38 | void QueuePartForUpdate(SceneObjectPart part); | 37 | void QueuePartForUpdate(SceneObjectPart part); |
39 | void SendPrimUpdates(); | 38 | void SendPrimUpdates(); |
40 | } | 39 | } |
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index 0ceef39..099fcce 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs | |||
@@ -93,40 +93,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
93 | { | 93 | { |
94 | get | 94 | get |
95 | { | 95 | { |
96 | lock (m_lock) | 96 | return m_eb_uuid.Count; |
97 | { | ||
98 | return m_eb_uuid.Count; | ||
99 | } | ||
100 | } | 97 | } |
101 | } | 98 | } |
102 | 99 | ||
103 | public bool ContainsKey(UUID id) | 100 | public bool ContainsKey(UUID id) |
104 | { | 101 | { |
105 | lock (m_lock) | 102 | try |
106 | { | 103 | { |
107 | try | 104 | return m_eb_uuid.ContainsKey(id); |
108 | { | 105 | } |
109 | return m_eb_uuid.ContainsKey(id); | 106 | catch |
110 | } | 107 | { |
111 | catch | 108 | return false; |
112 | { | ||
113 | return false; | ||
114 | } | ||
115 | } | 109 | } |
116 | } | 110 | } |
117 | 111 | ||
118 | public bool ContainsKey(uint localID) | 112 | public bool ContainsKey(uint localID) |
119 | { | 113 | { |
120 | lock (m_lock) | 114 | try |
121 | { | 115 | { |
122 | try | 116 | return m_eb_localID.ContainsKey(localID); |
123 | { | 117 | } |
124 | return m_eb_localID.ContainsKey(localID); | 118 | catch |
125 | } | 119 | { |
126 | catch | 120 | return false; |
127 | { | ||
128 | return false; | ||
129 | } | ||
130 | } | 121 | } |
131 | } | 122 | } |
132 | 123 | ||
@@ -136,7 +127,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
136 | { | 127 | { |
137 | try | 128 | try |
138 | { | 129 | { |
139 | bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID); | 130 | bool a = false; |
131 | EntityBase entity; | ||
132 | if (m_eb_localID.TryGetValue(localID, out entity)) | ||
133 | a = m_eb_uuid.Remove(entity.UUID); | ||
134 | |||
140 | bool b = m_eb_localID.Remove(localID); | 135 | bool b = m_eb_localID.Remove(localID); |
141 | return a && b; | 136 | return a && b; |
142 | } | 137 | } |
@@ -154,7 +149,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
154 | { | 149 | { |
155 | try | 150 | try |
156 | { | 151 | { |
157 | bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId); | 152 | bool a = false; |
153 | EntityBase entity; | ||
154 | if (m_eb_uuid.TryGetValue(id, out entity)) | ||
155 | a = m_eb_localID.Remove(entity.LocalId); | ||
156 | |||
158 | bool b = m_eb_uuid.Remove(id); | 157 | bool b = m_eb_uuid.Remove(id); |
159 | return a && b; | 158 | return a && b; |
160 | } | 159 | } |
@@ -206,14 +205,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
206 | { | 205 | { |
207 | lock (m_lock) | 206 | lock (m_lock) |
208 | { | 207 | { |
209 | try | 208 | EntityBase entity; |
210 | { | 209 | if (m_eb_uuid.TryGetValue(id, out entity)) |
211 | return m_eb_uuid[id]; | 210 | return entity; |
212 | } | 211 | else |
213 | catch | ||
214 | { | ||
215 | return null; | 212 | return null; |
216 | } | ||
217 | } | 213 | } |
218 | } | 214 | } |
219 | set | 215 | set |
@@ -228,14 +224,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
228 | { | 224 | { |
229 | lock (m_lock) | 225 | lock (m_lock) |
230 | { | 226 | { |
231 | try | 227 | EntityBase entity; |
232 | { | 228 | if (m_eb_localID.TryGetValue(localID, out entity)) |
233 | return m_eb_localID[localID]; | 229 | return entity; |
234 | } | 230 | else |
235 | catch | ||
236 | { | ||
237 | return null; | 231 | return null; |
238 | } | ||
239 | } | 232 | } |
240 | } | 233 | } |
241 | set | 234 | set |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index c44c4c7..c2b9e73 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -2351,12 +2351,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2351 | item = InventoryService.GetItem(item); | 2351 | item = InventoryService.GetItem(item); |
2352 | 2352 | ||
2353 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); | 2353 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); |
2354 | IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>(); | ||
2355 | if (ava != null) | ||
2356 | { | ||
2357 | ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
2358 | } | ||
2359 | |||
2360 | } | 2354 | } |
2361 | return att.UUID; | 2355 | return att.UUID; |
2362 | } | 2356 | } |
@@ -2402,12 +2396,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2402 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); | 2396 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); |
2403 | item = InventoryService.GetItem(item); | 2397 | item = InventoryService.GetItem(item); |
2404 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); | 2398 | presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); |
2405 | |||
2406 | if (m_AvatarFactory != null) | ||
2407 | { | ||
2408 | m_log.InfoFormat("[SCENE INVENTORY]: Saving avatar attachment. AgentID:{0} ItemID:{1} AttachmentPoint:{2}", remoteClient.AgentId, itemID, AttachmentPt); | ||
2409 | m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
2410 | } | ||
2411 | } | 2399 | } |
2412 | } | 2400 | } |
2413 | 2401 | ||
@@ -2447,12 +2435,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2447 | if (TryGetAvatar(remoteClient.AgentId, out presence)) | 2435 | if (TryGetAvatar(remoteClient.AgentId, out presence)) |
2448 | { | 2436 | { |
2449 | presence.Appearance.DetachAttachment(itemID); | 2437 | presence.Appearance.DetachAttachment(itemID); |
2450 | IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>(); | 2438 | |
2451 | if (ava != null) | 2439 | // Save avatar attachment information |
2440 | if (m_AvatarFactory != null) | ||
2452 | { | 2441 | { |
2453 | ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | 2442 | m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", ItemID: " + itemID); |
2443 | m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
2454 | } | 2444 | } |
2455 | |||
2456 | } | 2445 | } |
2457 | 2446 | ||
2458 | m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient); | 2447 | m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient); |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 151df27..2dbc090 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -57,6 +57,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
57 | 57 | ||
58 | public partial class Scene : SceneBase | 58 | public partial class Scene : SceneBase |
59 | { | 59 | { |
60 | public enum UpdatePrioritizationSchemes { | ||
61 | Time = 0, | ||
62 | Distance = 1, | ||
63 | SimpleAngularDistance = 2, | ||
64 | } | ||
65 | |||
60 | public delegate void SynchronizeSceneHandler(Scene scene); | 66 | public delegate void SynchronizeSceneHandler(Scene scene); |
61 | public SynchronizeSceneHandler SynchronizeScene = null; | 67 | public SynchronizeSceneHandler SynchronizeScene = null; |
62 | 68 | ||
@@ -222,6 +228,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
222 | protected IXMLRPC m_xmlrpcModule; | 228 | protected IXMLRPC m_xmlrpcModule; |
223 | protected IWorldComm m_worldCommModule; | 229 | protected IWorldComm m_worldCommModule; |
224 | protected IAvatarFactory m_AvatarFactory; | 230 | protected IAvatarFactory m_AvatarFactory; |
231 | public IAvatarFactory AvatarFactory | ||
232 | { | ||
233 | get { return m_AvatarFactory; } | ||
234 | } | ||
225 | protected IConfigSource m_config; | 235 | protected IConfigSource m_config; |
226 | protected IRegionSerialiserModule m_serialiser; | 236 | protected IRegionSerialiserModule m_serialiser; |
227 | protected IInterregionCommsOut m_interregionCommsOut; | 237 | protected IInterregionCommsOut m_interregionCommsOut; |
@@ -269,9 +279,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
269 | private volatile bool shuttingdown = false; | 279 | private volatile bool shuttingdown = false; |
270 | 280 | ||
271 | private int m_lastUpdate = Environment.TickCount; | 281 | private int m_lastUpdate = Environment.TickCount; |
272 | private int m_maxPrimsPerFrame = 200; | ||
273 | private bool m_firstHeartbeat = true; | 282 | private bool m_firstHeartbeat = true; |
274 | 283 | ||
284 | private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
285 | private bool m_reprioritization_enabled = true; | ||
286 | private double m_reprioritization_interval = 2000.0; | ||
287 | private double m_root_reprioritization_distance = 5.0; | ||
288 | private double m_child_reprioritization_distance = 10.0; | ||
289 | |||
275 | private object m_deleting_scene_object = new object(); | 290 | private object m_deleting_scene_object = new object(); |
276 | 291 | ||
277 | // the minimum time that must elapse before a changed object will be considered for persisted | 292 | // the minimum time that must elapse before a changed object will be considered for persisted |
@@ -283,6 +298,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
283 | 298 | ||
284 | #region Properties | 299 | #region Properties |
285 | 300 | ||
301 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } | ||
302 | public bool IsReprioritizationEnabled { get { return m_reprioritization_enabled; } } | ||
303 | public double ReprioritizationInterval { get { return m_reprioritization_interval; } } | ||
304 | public double RootReprioritizationDistance { get { return m_root_reprioritization_distance; } } | ||
305 | public double ChildReprioritizationDistance { get { return m_child_reprioritization_distance; } } | ||
306 | |||
286 | public AgentCircuitManager AuthenticateHandler | 307 | public AgentCircuitManager AuthenticateHandler |
287 | { | 308 | { |
288 | get { return m_authenticateHandler; } | 309 | get { return m_authenticateHandler; } |
@@ -327,12 +348,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
327 | get { return m_sceneGraph.m_syncRoot; } | 348 | get { return m_sceneGraph.m_syncRoot; } |
328 | } | 349 | } |
329 | 350 | ||
330 | public int MaxPrimsPerFrame | ||
331 | { | ||
332 | get { return m_maxPrimsPerFrame; } | ||
333 | set { m_maxPrimsPerFrame = value; } | ||
334 | } | ||
335 | |||
336 | /// <summary> | 351 | /// <summary> |
337 | /// This is for llGetRegionFPS | 352 | /// This is for llGetRegionFPS |
338 | /// </summary> | 353 | /// </summary> |
@@ -346,13 +361,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
346 | get { return m_defaultScriptEngine; } | 361 | get { return m_defaultScriptEngine; } |
347 | } | 362 | } |
348 | 363 | ||
349 | // Reference to all of the agents in the scene (root and child) | ||
350 | protected Dictionary<UUID, ScenePresence> m_scenePresences | ||
351 | { | ||
352 | get { return m_sceneGraph.ScenePresences; } | ||
353 | set { m_sceneGraph.ScenePresences = value; } | ||
354 | } | ||
355 | |||
356 | public EntityManager Entities | 364 | public EntityManager Entities |
357 | { | 365 | { |
358 | get { return m_sceneGraph.Entities; } | 366 | get { return m_sceneGraph.Entities; } |
@@ -510,7 +518,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
510 | 518 | ||
511 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); | 519 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); |
512 | 520 | ||
513 | m_maxPrimsPerFrame = startupConfig.GetInt("MaxPrimsPerFrame", 200); | ||
514 | IConfig packetConfig = m_config.Configs["PacketPool"]; | 521 | IConfig packetConfig = m_config.Configs["PacketPool"]; |
515 | if (packetConfig != null) | 522 | if (packetConfig != null) |
516 | { | 523 | { |
@@ -519,6 +526,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
519 | } | 526 | } |
520 | 527 | ||
521 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); | 528 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); |
529 | |||
530 | IConfig interest_management_config = m_config.Configs["InterestManagement"]; | ||
531 | if (interest_management_config != null) | ||
532 | { | ||
533 | string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); | ||
534 | switch (update_prioritization_scheme) | ||
535 | { | ||
536 | case "time": | ||
537 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
538 | break; | ||
539 | case "distance": | ||
540 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance; | ||
541 | break; | ||
542 | case "simpleangulardistance": | ||
543 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance; | ||
544 | break; | ||
545 | default: | ||
546 | m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time"); | ||
547 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
548 | break; | ||
549 | } | ||
550 | |||
551 | m_reprioritization_enabled = interest_management_config.GetBoolean("ReprioritizationEnabled", true); | ||
552 | m_reprioritization_interval = interest_management_config.GetDouble("ReprioritizationInterval", 5000.0); | ||
553 | m_root_reprioritization_distance = interest_management_config.GetDouble("RootReprioritizationDistance", 10.0); | ||
554 | m_child_reprioritization_distance = interest_management_config.GetDouble("ChildReprioritizationDistance", 20.0); | ||
555 | } | ||
556 | |||
557 | m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); | ||
522 | } | 558 | } |
523 | catch | 559 | catch |
524 | { | 560 | { |
@@ -1144,14 +1180,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1144 | /// <param name="stats">Stats on the Simulator's performance</param> | 1180 | /// <param name="stats">Stats on the Simulator's performance</param> |
1145 | private void SendSimStatsPackets(SimStats stats) | 1181 | private void SendSimStatsPackets(SimStats stats) |
1146 | { | 1182 | { |
1147 | List<ScenePresence> StatSendAgents = GetScenePresences(); | 1183 | ForEachScenePresence( |
1148 | foreach (ScenePresence agent in StatSendAgents) | 1184 | delegate(ScenePresence agent) |
1149 | { | ||
1150 | if (!agent.IsChildAgent) | ||
1151 | { | 1185 | { |
1152 | agent.ControllingClient.SendSimStats(stats); | 1186 | if (!agent.IsChildAgent) |
1187 | agent.ControllingClient.SendSimStats(stats); | ||
1153 | } | 1188 | } |
1154 | } | 1189 | ); |
1155 | } | 1190 | } |
1156 | 1191 | ||
1157 | /// <summary> | 1192 | /// <summary> |
@@ -1200,15 +1235,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1200 | } | 1235 | } |
1201 | 1236 | ||
1202 | /// <summary> | 1237 | /// <summary> |
1203 | /// Perform delegate action on all clients subscribing to updates from this region. | ||
1204 | /// </summary> | ||
1205 | /// <returns></returns> | ||
1206 | public void Broadcast(Action<IClientAPI> whatToDo) | ||
1207 | { | ||
1208 | ForEachScenePresence(delegate(ScenePresence presence) { whatToDo(presence.ControllingClient); }); | ||
1209 | } | ||
1210 | |||
1211 | /// <summary> | ||
1212 | /// Backup the scene. This acts as the main method of the backup thread. | 1238 | /// Backup the scene. This acts as the main method of the backup thread. |
1213 | /// </summary> | 1239 | /// </summary> |
1214 | /// <returns></returns> | 1240 | /// <returns></returns> |
@@ -3054,17 +3080,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3054 | } | 3080 | } |
3055 | 3081 | ||
3056 | m_eventManager.TriggerOnRemovePresence(agentID); | 3082 | m_eventManager.TriggerOnRemovePresence(agentID); |
3057 | Broadcast(delegate(IClientAPI client) | 3083 | ForEachClient( |
3058 | { | 3084 | delegate(IClientAPI client) |
3059 | try | 3085 | { |
3060 | { | 3086 | //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway |
3061 | client.SendKillObject(avatar.RegionHandle, avatar.LocalId); | 3087 | try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } |
3062 | } | 3088 | catch (NullReferenceException) { } |
3063 | catch (NullReferenceException) | 3089 | }); |
3064 | { | ||
3065 | //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway. | ||
3066 | } | ||
3067 | }); | ||
3068 | 3090 | ||
3069 | ForEachScenePresence( | 3091 | ForEachScenePresence( |
3070 | delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); | 3092 | delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); |
@@ -3149,7 +3171,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3149 | return; | 3171 | return; |
3150 | } | 3172 | } |
3151 | } | 3173 | } |
3152 | Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); | 3174 | ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); |
3153 | } | 3175 | } |
3154 | 3176 | ||
3155 | #endregion | 3177 | #endregion |
@@ -3475,10 +3497,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3475 | { | 3497 | { |
3476 | ScenePresence presence; | 3498 | ScenePresence presence; |
3477 | 3499 | ||
3478 | lock (m_scenePresences) | 3500 | lock (m_sceneGraph.ScenePresences) |
3479 | { | 3501 | m_sceneGraph.ScenePresences.TryGetValue(agentID, out presence); |
3480 | m_scenePresences.TryGetValue(agentID, out presence); | ||
3481 | } | ||
3482 | 3502 | ||
3483 | if (presence != null) | 3503 | if (presence != null) |
3484 | { | 3504 | { |
@@ -3688,12 +3708,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3688 | public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, | 3708 | public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, Vector3 position, |
3689 | Vector3 lookAt, uint teleportFlags) | 3709 | Vector3 lookAt, uint teleportFlags) |
3690 | { | 3710 | { |
3691 | ScenePresence sp = null; | 3711 | ScenePresence sp; |
3692 | lock (m_scenePresences) | 3712 | lock (m_sceneGraph.ScenePresences) |
3693 | { | 3713 | m_sceneGraph.ScenePresences.TryGetValue(remoteClient.AgentId, out sp); |
3694 | if (m_scenePresences.ContainsKey(remoteClient.AgentId)) | ||
3695 | sp = m_scenePresences[remoteClient.AgentId]; | ||
3696 | } | ||
3697 | 3714 | ||
3698 | if (sp != null) | 3715 | if (sp != null) |
3699 | { | 3716 | { |
@@ -4142,7 +4159,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4142 | public void ForEachScenePresence(Action<ScenePresence> action) | 4159 | public void ForEachScenePresence(Action<ScenePresence> action) |
4143 | { | 4160 | { |
4144 | // We don't want to try to send messages if there are no avatars. | 4161 | // We don't want to try to send messages if there are no avatars. |
4145 | if (m_scenePresences != null) | 4162 | if (m_sceneGraph != null && m_sceneGraph.ScenePresences != null) |
4146 | { | 4163 | { |
4147 | try | 4164 | try |
4148 | { | 4165 | { |
@@ -4222,7 +4239,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4222 | 4239 | ||
4223 | public void ForEachClient(Action<IClientAPI> action) | 4240 | public void ForEachClient(Action<IClientAPI> action) |
4224 | { | 4241 | { |
4225 | m_sceneGraph.ForEachClient(action); | 4242 | ClientManager.ForEach(action); |
4226 | } | 4243 | } |
4227 | 4244 | ||
4228 | public void ForEachSOG(Action<SceneObjectGroup> action) | 4245 | public void ForEachSOG(Action<SceneObjectGroup> action) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9cd2247..e51f6ef 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -467,7 +467,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
467 | protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) | 467 | protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) |
468 | { | 468 | { |
469 | // If we can't take it, we can't attach it! | 469 | // If we can't take it, we can't attach it! |
470 | // | ||
471 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID); | 470 | SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID); |
472 | if (part == null) | 471 | if (part == null) |
473 | return; | 472 | return; |
@@ -477,9 +476,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
477 | return; | 476 | return; |
478 | 477 | ||
479 | // Calls attach with a Zero position | 478 | // Calls attach with a Zero position |
480 | // | ||
481 | AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); | 479 | AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); |
482 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | 480 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
481 | |||
482 | // Save avatar attachment information | ||
483 | ScenePresence presence; | ||
484 | if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence)) | ||
485 | { | ||
486 | m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt); | ||
487 | m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
488 | } | ||
483 | } | 489 | } |
484 | 490 | ||
485 | public SceneObjectGroup RezSingleAttachment( | 491 | public SceneObjectGroup RezSingleAttachment( |
@@ -574,7 +580,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
574 | } | 580 | } |
575 | 581 | ||
576 | 582 | ||
577 | group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); | 583 | group.SetAttachmentPoint((byte)AttachmentPt); |
578 | group.AbsolutePosition = attachPos; | 584 | group.AbsolutePosition = attachPos; |
579 | 585 | ||
580 | // Saves and gets itemID | 586 | // Saves and gets itemID |
@@ -613,7 +619,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
613 | 619 | ||
614 | newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); | 620 | newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); |
615 | newAvatar.IsChildAgent = true; | 621 | newAvatar.IsChildAgent = true; |
616 | newAvatar.MaxPrimsPerFrame = m_parentScene.MaxPrimsPerFrame; | ||
617 | 622 | ||
618 | AddScenePresence(newAvatar); | 623 | AddScenePresence(newAvatar); |
619 | 624 | ||
@@ -847,7 +852,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
847 | /// </summary> | 852 | /// </summary> |
848 | /// <param name="localID"></param> | 853 | /// <param name="localID"></param> |
849 | /// <returns>null if no scene object group containing that prim is found</returns> | 854 | /// <returns>null if no scene object group containing that prim is found</returns> |
850 | private SceneObjectGroup GetGroupByPrim(uint localID) | 855 | public SceneObjectGroup GetGroupByPrim(uint localID) |
851 | { | 856 | { |
852 | if (Entities.ContainsKey(localID)) | 857 | if (Entities.ContainsKey(localID)) |
853 | return Entities[localID] as SceneObjectGroup; | 858 | return Entities[localID] as SceneObjectGroup; |
@@ -1107,23 +1112,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1107 | return UUID.Zero; | 1112 | return UUID.Zero; |
1108 | } | 1113 | } |
1109 | 1114 | ||
1110 | protected internal void ForEachClient(Action<IClientAPI> action) | ||
1111 | { | ||
1112 | List<ScenePresence> splist = GetScenePresences(); | ||
1113 | foreach (ScenePresence presence in splist) | ||
1114 | { | ||
1115 | try | ||
1116 | { | ||
1117 | action(presence.ControllingClient); | ||
1118 | } | ||
1119 | catch (Exception e) | ||
1120 | { | ||
1121 | // Catch it and move on. This includes situations where splist has inconsistent info | ||
1122 | m_log.WarnFormat("[SCENE]: Problem processing action in ForEachClient: ", e.Message); | ||
1123 | } | ||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) | 1115 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1128 | { | 1116 | { |
1129 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | 1117 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index d4cef7d..810dfd1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -899,7 +899,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
899 | SetAttachmentPoint(Convert.ToByte(attachmentpoint)); | 899 | SetAttachmentPoint(Convert.ToByte(attachmentpoint)); |
900 | 900 | ||
901 | avatar.AddAttachment(this); | 901 | avatar.AddAttachment(this); |
902 | m_log.DebugFormat("[SOG]: Added att {0} to avie {1}", UUID, avatar.UUID); | 902 | m_log.Debug("[SOG]: Added attachment " + UUID + " to avatar " + avatar.UUID); |
903 | 903 | ||
904 | if (!silent) | 904 | if (!silent) |
905 | { | 905 | { |
@@ -1817,7 +1817,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1817 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) | 1817 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) |
1818 | { | 1818 | { |
1819 | 1819 | ||
1820 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.ObjectOwner, RootPart.GroupID, RootPart.BaseMask, | 1820 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, |
1821 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, | 1821 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, |
1822 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, | 1822 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, |
1823 | RootPart.CreatorID, RootPart.Name, RootPart.Description); | 1823 | RootPart.CreatorID, RootPart.Name, RootPart.Description); |
@@ -3343,5 +3343,77 @@ namespace OpenSim.Region.Framework.Scenes | |||
3343 | 3343 | ||
3344 | return true; | 3344 | return true; |
3345 | } | 3345 | } |
3346 | |||
3347 | public double GetUpdatePriority(IClientAPI client) | ||
3348 | { | ||
3349 | switch (Scene.UpdatePrioritizationScheme) | ||
3350 | { | ||
3351 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3352 | return GetPriorityByTime(); | ||
3353 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3354 | return GetPriorityByDistance(client); | ||
3355 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3356 | return GetPriorityBySimpleAngularDistance(client); | ||
3357 | default: | ||
3358 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3359 | } | ||
3360 | } | ||
3361 | |||
3362 | private double GetPriorityByTime() | ||
3363 | { | ||
3364 | return DateTime.Now.ToOADate(); | ||
3365 | } | ||
3366 | |||
3367 | private double GetPriorityByDistance(IClientAPI client) | ||
3368 | { | ||
3369 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3370 | if (presence != null) | ||
3371 | { | ||
3372 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3373 | presence.AbsolutePosition : presence.CameraPosition); | ||
3374 | } | ||
3375 | return double.NaN; | ||
3376 | } | ||
3377 | |||
3378 | private double GetPriorityBySimpleAngularDistance(IClientAPI client) | ||
3379 | { | ||
3380 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3381 | if (presence != null) | ||
3382 | { | ||
3383 | return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ? | ||
3384 | presence.AbsolutePosition : presence.CameraPosition); | ||
3385 | } | ||
3386 | return double.NaN; | ||
3387 | } | ||
3388 | |||
3389 | public double GetPriorityByDistance(Vector3 position) | ||
3390 | { | ||
3391 | return Vector3.Distance(AbsolutePosition, position); | ||
3392 | } | ||
3393 | |||
3394 | public double GetPriorityBySimpleAngularDistance(Vector3 position) | ||
3395 | { | ||
3396 | double distance = Vector3.Distance(position, AbsolutePosition); | ||
3397 | if (distance >= double.Epsilon) | ||
3398 | { | ||
3399 | float height; | ||
3400 | Vector3 box = GetAxisAlignedBoundingBox(out height); | ||
3401 | |||
3402 | double angle = box.X / distance; | ||
3403 | double max = angle; | ||
3404 | |||
3405 | angle = box.Y / distance; | ||
3406 | if (max < angle) | ||
3407 | max = angle; | ||
3408 | |||
3409 | angle = box.Z / distance; | ||
3410 | if (max < angle) | ||
3411 | max = angle; | ||
3412 | |||
3413 | return -max; | ||
3414 | } | ||
3415 | else | ||
3416 | return double.MinValue; | ||
3417 | } | ||
3346 | } | 3418 | } |
3347 | } | 3419 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 801a7db..a078b3d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -853,16 +853,6 @@ if (m_shape != null) { | |||
853 | return m_offsetPosition + m_groupPosition; } | 853 | return m_offsetPosition + m_groupPosition; } |
854 | } | 854 | } |
855 | 855 | ||
856 | public UUID ObjectCreator | ||
857 | { | ||
858 | get { return _creatorID; } | ||
859 | } | ||
860 | |||
861 | public UUID ObjectOwner | ||
862 | { | ||
863 | get { return _ownerID; } | ||
864 | } | ||
865 | |||
866 | public SceneObjectGroup ParentGroup | 856 | public SceneObjectGroup ParentGroup |
867 | { | 857 | { |
868 | get { return m_parentGroup; } | 858 | get { return m_parentGroup; } |
@@ -1440,7 +1430,7 @@ if (m_shape != null) { | |||
1440 | // Move afterwards ResetIDs as it clears the localID | 1430 | // Move afterwards ResetIDs as it clears the localID |
1441 | dupe.LocalId = localID; | 1431 | dupe.LocalId = localID; |
1442 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. | 1432 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. |
1443 | dupe._lastOwnerID = ObjectOwner; | 1433 | dupe._lastOwnerID = OwnerID; |
1444 | 1434 | ||
1445 | byte[] extraP = new byte[Shape.ExtraParams.Length]; | 1435 | byte[] extraP = new byte[Shape.ExtraParams.Length]; |
1446 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | 1436 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); |
@@ -2410,10 +2400,10 @@ if (m_shape != null) { | |||
2410 | //isattachment = ParentGroup.RootPart.IsAttachment; | 2400 | //isattachment = ParentGroup.RootPart.IsAttachment; |
2411 | 2401 | ||
2412 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; | 2402 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; |
2413 | remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, | 2403 | remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, |
2414 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, | 2404 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, |
2415 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, | 2405 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, |
2416 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius); | 2406 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); |
2417 | } | 2407 | } |
2418 | 2408 | ||
2419 | /// <summary> | 2409 | /// <summary> |
@@ -3801,15 +3791,15 @@ if (m_shape != null) { | |||
3801 | if (ParentGroup.RootPart == this) | 3791 | if (ParentGroup.RootPart == this) |
3802 | lPos = AbsolutePosition; | 3792 | lPos = AbsolutePosition; |
3803 | } | 3793 | } |
3804 | 3794 | ||
3805 | // Causes this thread to dig into the Client Thread Data. | 3795 | // Causes this thread to dig into the Client Thread Data. |
3806 | // Remember your locking here! | 3796 | // Remember your locking here! |
3807 | remoteClient.SendPrimTerseUpdate(m_regionHandle, | 3797 | remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, |
3808 | (ushort)(m_parentGroup.GetTimeDilation() * | 3798 | (ushort)(m_parentGroup.GetTimeDilation() * |
3809 | (float)ushort.MaxValue), LocalId, lPos, | 3799 | (float)ushort.MaxValue), LocalId, lPos, |
3810 | RotationOffset, Velocity, | 3800 | RotationOffset, Velocity, Acceleration, |
3811 | RotationalVelocity, state, FromItemID, | 3801 | RotationalVelocity, state, FromItemID, |
3812 | OwnerID, (int)AttachmentPoint); | 3802 | OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); |
3813 | } | 3803 | } |
3814 | 3804 | ||
3815 | public void AddScriptLPS(int count) | 3805 | public void AddScriptLPS(int count) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c25fa55..bdd80c6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Timers; | ||
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | using log4net; | 33 | using log4net; |
33 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
@@ -172,6 +173,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
172 | 173 | ||
173 | // Position of agent's camera in world (region cordinates) | 174 | // Position of agent's camera in world (region cordinates) |
174 | protected Vector3 m_CameraCenter = Vector3.Zero; | 175 | protected Vector3 m_CameraCenter = Vector3.Zero; |
176 | protected Vector3 m_lastCameraCenter = Vector3.Zero; | ||
177 | |||
178 | protected Timer m_reprioritization_timer; | ||
179 | protected bool m_reprioritizing = false; | ||
180 | protected bool m_reprioritization_called = false; | ||
175 | 181 | ||
176 | // Use these three vectors to figure out what the agent is looking at | 182 | // Use these three vectors to figure out what the agent is looking at |
177 | // Convert it to a Matrix and/or Quaternion | 183 | // Convert it to a Matrix and/or Quaternion |
@@ -403,12 +409,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
403 | set { m_parentPosition = value; } | 409 | set { m_parentPosition = value; } |
404 | } | 410 | } |
405 | 411 | ||
406 | public int MaxPrimsPerFrame | ||
407 | { | ||
408 | get { return m_sceneViewer.MaxPrimsPerFrame; } | ||
409 | set { m_sceneViewer.MaxPrimsPerFrame = value; } | ||
410 | } | ||
411 | |||
412 | /// <summary> | 412 | /// <summary> |
413 | /// Absolute position of this avatar in 'region cordinates' | 413 | /// Absolute position of this avatar in 'region cordinates' |
414 | /// </summary> | 414 | /// </summary> |
@@ -645,7 +645,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
645 | 645 | ||
646 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); | 646 | m_scriptEngines = m_scene.RequestModuleInterfaces<IScriptModule>(); |
647 | 647 | ||
648 | AbsolutePosition = m_controllingClient.StartPos; | 648 | AbsolutePosition = posLastSignificantMove = m_CameraCenter = |
649 | m_lastCameraCenter = m_controllingClient.StartPos; | ||
650 | |||
651 | m_reprioritization_timer = new Timer(world.ReprioritizationInterval); | ||
652 | m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); | ||
653 | m_reprioritization_timer.AutoReset = false; | ||
654 | |||
655 | |||
649 | AdjustKnownSeeds(); | 656 | AdjustKnownSeeds(); |
650 | 657 | ||
651 | TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... | 658 | TrySetMovementAnimation("STAND"); // TODO: I think, this won't send anything, as we are still a child here... |
@@ -1153,15 +1160,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1153 | /// </summary> | 1160 | /// </summary> |
1154 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) | 1161 | public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) |
1155 | { | 1162 | { |
1156 | lock (m_agentUpdates) | 1163 | const int AGENT_UPDATE_TIMEOUT_MS = 1000 * 3; |
1164 | |||
1165 | if (System.Threading.Monitor.TryEnter(m_agentUpdates, AGENT_UPDATE_TIMEOUT_MS)) | ||
1157 | { | 1166 | { |
1158 | if (m_updatesAllowed) | 1167 | try |
1159 | { | 1168 | { |
1160 | RealHandleAgentUpdate(remoteClient, agentData); | 1169 | if (m_updatesAllowed) |
1161 | return; | 1170 | { |
1171 | RealHandleAgentUpdate(remoteClient, agentData); | ||
1172 | return; | ||
1173 | } | ||
1174 | |||
1175 | m_agentUpdates.Add(agentData); | ||
1162 | } | 1176 | } |
1163 | 1177 | finally { System.Threading.Monitor.Exit(m_agentUpdates); } | |
1164 | m_agentUpdates.Add(agentData); | ||
1165 | } | 1178 | } |
1166 | } | 1179 | } |
1167 | 1180 | ||
@@ -1225,6 +1238,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1225 | // Camera location in world. We'll need to raytrace | 1238 | // Camera location in world. We'll need to raytrace |
1226 | // from this location from time to time. | 1239 | // from this location from time to time. |
1227 | m_CameraCenter = agentData.CameraCenter; | 1240 | m_CameraCenter = agentData.CameraCenter; |
1241 | if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) | ||
1242 | { | ||
1243 | ReprioritizeUpdates(); | ||
1244 | m_lastCameraCenter = m_CameraCenter; | ||
1245 | } | ||
1228 | 1246 | ||
1229 | // Use these three vectors to figure out what the agent is looking at | 1247 | // Use these three vectors to figure out what the agent is looking at |
1230 | // Convert it to a Matrix and/or Quaternion | 1248 | // Convert it to a Matrix and/or Quaternion |
@@ -2456,11 +2474,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2456 | m_perfMonMS = Environment.TickCount; | 2474 | m_perfMonMS = Environment.TickCount; |
2457 | 2475 | ||
2458 | Vector3 pos = m_pos; | 2476 | Vector3 pos = m_pos; |
2459 | Vector3 vel = Velocity; | ||
2460 | Quaternion rot = m_bodyRot; | ||
2461 | pos.Z -= m_appearance.HipOffset; | 2477 | pos.Z -= m_appearance.HipOffset; |
2462 | remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, new Vector3(pos.X, pos.Y, pos.Z), | 2478 | |
2463 | new Vector3(vel.X, vel.Y, vel.Z), rot, m_uuid); | 2479 | remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, |
2480 | pos, m_velocity, Vector3.Zero, m_rotation, Vector4.Zero, m_uuid, null, GetUpdatePriority(remoteClient))); | ||
2464 | 2481 | ||
2465 | m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); | 2482 | m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); |
2466 | m_scene.StatsReporter.AddAgentUpdates(1); | 2483 | m_scene.StatsReporter.AddAgentUpdates(1); |
@@ -2474,7 +2491,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2474 | { | 2491 | { |
2475 | m_perfMonMS = Environment.TickCount; | 2492 | m_perfMonMS = Environment.TickCount; |
2476 | 2493 | ||
2477 | m_scene.Broadcast(SendTerseUpdateToClient); | 2494 | m_scene.ForEachClient(SendTerseUpdateToClient); |
2478 | 2495 | ||
2479 | m_lastVelocity = m_velocity; | 2496 | m_lastVelocity = m_velocity; |
2480 | lastPhysPos = AbsolutePosition; | 2497 | lastPhysPos = AbsolutePosition; |
@@ -2566,9 +2583,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2566 | Vector3 pos = m_pos; | 2583 | Vector3 pos = m_pos; |
2567 | pos.Z -= m_appearance.HipOffset; | 2584 | pos.Z -= m_appearance.HipOffset; |
2568 | 2585 | ||
2569 | remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, | 2586 | remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, |
2570 | LocalId, m_pos, m_appearance.Texture.GetBytes(), | 2587 | LocalId, m_pos, m_appearance.Texture.GetBytes(), |
2571 | m_parentID, rot); | 2588 | m_parentID, rot)); |
2572 | m_scene.StatsReporter.AddAgentUpdates(1); | 2589 | m_scene.StatsReporter.AddAgentUpdates(1); |
2573 | } | 2590 | } |
2574 | 2591 | ||
@@ -2637,8 +2654,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2637 | Vector3 pos = m_pos; | 2654 | Vector3 pos = m_pos; |
2638 | pos.Z -= m_appearance.HipOffset; | 2655 | pos.Z -= m_appearance.HipOffset; |
2639 | 2656 | ||
2640 | m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2657 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, |
2641 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot); | 2658 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); |
2642 | 2659 | ||
2643 | if (!m_isChildAgent) | 2660 | if (!m_isChildAgent) |
2644 | { | 2661 | { |
@@ -2744,8 +2761,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2744 | } | 2761 | } |
2745 | 2762 | ||
2746 | Quaternion rot = m_bodyRot; | 2763 | Quaternion rot = m_bodyRot; |
2747 | m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2764 | m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, |
2748 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot); | 2765 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); |
2749 | 2766 | ||
2750 | } | 2767 | } |
2751 | 2768 | ||
@@ -2776,7 +2793,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2776 | if (m_isChildAgent) | 2793 | if (m_isChildAgent) |
2777 | return; | 2794 | return; |
2778 | 2795 | ||
2779 | m_scene.Broadcast( | 2796 | m_scene.ForEachClient( |
2780 | delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); | 2797 | delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); |
2781 | } | 2798 | } |
2782 | 2799 | ||
@@ -2830,7 +2847,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2830 | } | 2847 | } |
2831 | 2848 | ||
2832 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m | 2849 | // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m |
2833 | if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32) | 2850 | if (Util.GetDistanceTo(AbsolutePosition, m_LastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance) |
2834 | { | 2851 | { |
2835 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); | 2852 | ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); |
2836 | cadu.ActiveGroupID = UUID.Zero.Guid; | 2853 | cadu.ActiveGroupID = UUID.Zero.Guid; |
@@ -3125,6 +3142,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3125 | if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! | 3142 | if (cAgentData.Position != new Vector3(-1, -1, -1)) // UGH!! |
3126 | m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); | 3143 | m_pos = new Vector3(cAgentData.Position.X + shiftx, cAgentData.Position.Y + shifty, cAgentData.Position.Z); |
3127 | 3144 | ||
3145 | if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) | ||
3146 | { | ||
3147 | posLastSignificantMove = AbsolutePosition; | ||
3148 | ReprioritizeUpdates(); | ||
3149 | } | ||
3150 | |||
3128 | // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region | 3151 | // It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region |
3129 | m_CameraCenter = cAgentData.Center; | 3152 | m_CameraCenter = cAgentData.Center; |
3130 | 3153 | ||
@@ -3487,7 +3510,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3487 | 3510 | ||
3488 | public void Close() | 3511 | public void Close() |
3489 | { | 3512 | { |
3490 | |||
3491 | lock (m_attachments) | 3513 | lock (m_attachments) |
3492 | { | 3514 | { |
3493 | // Delete attachments from scene | 3515 | // Delete attachments from scene |
@@ -3505,10 +3527,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
3505 | { | 3527 | { |
3506 | m_knownChildRegions.Clear(); | 3528 | m_knownChildRegions.Clear(); |
3507 | } | 3529 | } |
3530 | |||
3531 | lock (m_reprioritization_timer) | ||
3532 | { | ||
3533 | m_reprioritization_timer.Enabled = false; | ||
3534 | m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); | ||
3535 | } | ||
3536 | // I don't get it but mono crashes when you try to dispose of this timer, | ||
3537 | // unsetting the elapsed callback should be enough to allow for cleanup however. | ||
3538 | //m_reprioritizationTimer.Dispose(); | ||
3539 | |||
3508 | m_sceneViewer.Close(); | 3540 | m_sceneViewer.Close(); |
3509 | 3541 | ||
3510 | RemoveFromPhysicalScene(); | 3542 | RemoveFromPhysicalScene(); |
3511 | GC.Collect(); | ||
3512 | } | 3543 | } |
3513 | 3544 | ||
3514 | public ScenePresence() | 3545 | public ScenePresence() |
@@ -3884,5 +3915,115 @@ namespace OpenSim.Region.Framework.Scenes | |||
3884 | } | 3915 | } |
3885 | } | 3916 | } |
3886 | } | 3917 | } |
3918 | |||
3919 | public double GetUpdatePriority(IClientAPI client) | ||
3920 | { | ||
3921 | switch (Scene.UpdatePrioritizationScheme) | ||
3922 | { | ||
3923 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3924 | return GetPriorityByTime(); | ||
3925 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3926 | return GetPriorityByDistance(client); | ||
3927 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3928 | return GetPriorityByDistance(client); | ||
3929 | default: | ||
3930 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | ||
3931 | } | ||
3932 | } | ||
3933 | |||
3934 | private double GetPriorityByTime() | ||
3935 | { | ||
3936 | return DateTime.Now.ToOADate(); | ||
3937 | } | ||
3938 | |||
3939 | private double GetPriorityByDistance(IClientAPI client) | ||
3940 | { | ||
3941 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3942 | if (presence != null) | ||
3943 | { | ||
3944 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3945 | presence.AbsolutePosition : presence.CameraPosition); | ||
3946 | } | ||
3947 | return double.NaN; | ||
3948 | } | ||
3949 | |||
3950 | private double GetPriorityByDistance(Vector3 position) | ||
3951 | { | ||
3952 | return Vector3.Distance(AbsolutePosition, position); | ||
3953 | } | ||
3954 | |||
3955 | private double GetSOGUpdatePriority(SceneObjectGroup sog) | ||
3956 | { | ||
3957 | switch (Scene.UpdatePrioritizationScheme) | ||
3958 | { | ||
3959 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3960 | throw new InvalidOperationException("UpdatePrioritizationScheme for time not supported for reprioritization"); | ||
3961 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3962 | return sog.GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3963 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3964 | return sog.GetPriorityBySimpleAngularDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3965 | default: | ||
3966 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3967 | } | ||
3968 | } | ||
3969 | |||
3970 | private double UpdatePriority(UpdatePriorityData data) | ||
3971 | { | ||
3972 | EntityBase entity; | ||
3973 | SceneObjectGroup group; | ||
3974 | |||
3975 | if (Scene.Entities.TryGetValue(data.localID, out entity)) | ||
3976 | { | ||
3977 | group = entity as SceneObjectGroup; | ||
3978 | if (group != null) | ||
3979 | return GetSOGUpdatePriority(group); | ||
3980 | |||
3981 | ScenePresence presence = entity as ScenePresence; | ||
3982 | if (presence == null) | ||
3983 | throw new InvalidOperationException("entity found is neither SceneObjectGroup nor ScenePresence"); | ||
3984 | switch (Scene.UpdatePrioritizationScheme) | ||
3985 | { | ||
3986 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3987 | throw new InvalidOperationException("UpdatePrioritization for time not supported for reprioritization"); | ||
3988 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3989 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3990 | return GetPriorityByDistance((IsChildAgent) ? AbsolutePosition : CameraPosition); | ||
3991 | default: | ||
3992 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3993 | } | ||
3994 | } | ||
3995 | else | ||
3996 | { | ||
3997 | group = Scene.SceneGraph.GetGroupByPrim(data.localID); | ||
3998 | if (group != null) | ||
3999 | return GetSOGUpdatePriority(group); | ||
4000 | } | ||
4001 | return double.NaN; | ||
4002 | } | ||
4003 | |||
4004 | private void ReprioritizeUpdates() | ||
4005 | { | ||
4006 | if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != Scene.UpdatePrioritizationSchemes.Time) | ||
4007 | { | ||
4008 | lock (m_reprioritization_timer) | ||
4009 | { | ||
4010 | if (!m_reprioritizing) | ||
4011 | m_reprioritization_timer.Enabled = m_reprioritizing = true; | ||
4012 | else | ||
4013 | m_reprioritization_called = true; | ||
4014 | } | ||
4015 | } | ||
4016 | } | ||
4017 | |||
4018 | private void Reprioritize(object sender, ElapsedEventArgs e) | ||
4019 | { | ||
4020 | m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); | ||
4021 | |||
4022 | lock (m_reprioritization_timer) | ||
4023 | { | ||
4024 | m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; | ||
4025 | m_reprioritization_called = false; | ||
4026 | } | ||
4027 | } | ||
3887 | } | 4028 | } |
3888 | } | 4029 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 8ab0552..e4296ef 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs | |||
@@ -45,14 +45,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
45 | 45 | ||
46 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); | 46 | protected Dictionary<UUID, ScenePartUpdate> m_updateTimes = new Dictionary<UUID, ScenePartUpdate>(); |
47 | 47 | ||
48 | protected int m_maxPrimsPerFrame = 200; | ||
49 | |||
50 | public int MaxPrimsPerFrame | ||
51 | { | ||
52 | get { return m_maxPrimsPerFrame; } | ||
53 | set { m_maxPrimsPerFrame = value; } | ||
54 | } | ||
55 | |||
56 | public SceneViewer() | 48 | public SceneViewer() |
57 | { | 49 | { |
58 | } | 50 | } |
@@ -82,16 +74,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
82 | { | 74 | { |
83 | m_pendingObjects = new Queue<SceneObjectGroup>(); | 75 | m_pendingObjects = new Queue<SceneObjectGroup>(); |
84 | 76 | ||
85 | List<EntityBase> ents = new List<EntityBase>(m_presence.Scene.Entities); | 77 | foreach (EntityBase e in m_presence.Scene.Entities) |
86 | if (!m_presence.IsChildAgent) // Proximity sort makes no sense for | ||
87 | { // Child agents | ||
88 | ents.Sort(delegate(EntityBase a, EntityBase b) | ||
89 | { | ||
90 | return Vector3.Distance(m_presence.AbsolutePosition, a.AbsolutePosition).CompareTo(Vector3.Distance(m_presence.AbsolutePosition, b.AbsolutePosition)); | ||
91 | }); | ||
92 | } | ||
93 | |||
94 | foreach (EntityBase e in ents) | ||
95 | { | 78 | { |
96 | if (e is SceneObjectGroup) | 79 | if (e is SceneObjectGroup) |
97 | m_pendingObjects.Enqueue((SceneObjectGroup)e); | 80 | m_pendingObjects.Enqueue((SceneObjectGroup)e); |
@@ -99,7 +82,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
99 | } | 82 | } |
100 | } | 83 | } |
101 | 84 | ||
102 | while (m_pendingObjects != null && m_pendingObjects.Count > 0 && m_partsUpdateQueue.Count < m_maxPrimsPerFrame) | 85 | while (m_pendingObjects != null && m_pendingObjects.Count > 0) |
103 | { | 86 | { |
104 | SceneObjectGroup g = m_pendingObjects.Dequeue(); | 87 | SceneObjectGroup g = m_pendingObjects.Dequeue(); |
105 | 88 | ||
@@ -183,8 +166,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
183 | m_presence.GenerateClientFlags(part.UUID)); | 166 | m_presence.GenerateClientFlags(part.UUID)); |
184 | } | 167 | } |
185 | } | 168 | } |
186 | |||
187 | m_presence.ControllingClient.FlushPrimUpdates(); | ||
188 | } | 169 | } |
189 | 170 | ||
190 | public void Reset() | 171 | public void Reset() |
diff --git a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs index 29c4672..f3be028 100644 --- a/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs +++ b/OpenSim/Region/Framework/Scenes/Scripting/IScriptHost.cs | |||
@@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Scenes.Scripting | |||
35 | string Description { get; set; } | 35 | string Description { get; set; } |
36 | 36 | ||
37 | UUID UUID { get; } | 37 | UUID UUID { get; } |
38 | UUID ObjectOwner { get; } | 38 | UUID OwnerID { get; } |
39 | UUID ObjectCreator { get; } | 39 | UUID CreatorID { get; } |
40 | Vector3 AbsolutePosition { get; } | 40 | Vector3 AbsolutePosition { get; } |
41 | 41 | ||
42 | string SitName { get; set; } | 42 | string SitName { get; set; } |
diff --git a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs index af18a98..d7198f0 100644 --- a/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs +++ b/OpenSim/Region/Framework/Scenes/Scripting/NullScriptHost.cs | |||
@@ -68,12 +68,12 @@ namespace OpenSim.Region.Framework.Scenes.Scripting | |||
68 | get { return UUID.Zero; } | 68 | get { return UUID.Zero; } |
69 | } | 69 | } |
70 | 70 | ||
71 | public UUID ObjectOwner | 71 | public UUID OwnerID |
72 | { | 72 | { |
73 | get { return UUID.Zero; } | 73 | get { return UUID.Zero; } |
74 | } | 74 | } |
75 | 75 | ||
76 | public UUID ObjectCreator | 76 | public UUID CreatorID |
77 | { | 77 | { |
78 | get { return UUID.Zero; } | 78 | get { return UUID.Zero; } |
79 | } | 79 | } |
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 434da0a..df03b8d 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -1013,12 +1013,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1013 | 1013 | ||
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | 1016 | public void SendAvatarData(SendAvatarData data) |
1017 | { | 1017 | { |
1018 | 1018 | ||
1019 | } | 1019 | } |
1020 | 1020 | ||
1021 | public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid) | 1021 | public void SendAvatarTerseUpdate(SendAvatarTerseData data) |
1022 | { | 1022 | { |
1023 | 1023 | ||
1024 | } | 1024 | } |
@@ -1038,19 +1038,19 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1038 | 1038 | ||
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) | 1041 | public void SendPrimitiveToClient(SendPrimitiveData data) |
1042 | { | 1042 | { |
1043 | 1043 | ||
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material) | 1046 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
1047 | { | 1047 | { |
1048 | 1048 | ||
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID owner, int attachPoint) | 1051 | public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) |
1052 | { | 1052 | { |
1053 | 1053 | ||
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems) | 1056 | public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems) |
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs index 0379180..e185351 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs | |||
@@ -188,7 +188,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement | |||
188 | // MISC COMPARISONS (UUID, Byte) | 188 | // MISC COMPARISONS (UUID, Byte) |
189 | if (first.ClickAction != second.ClickAction) | 189 | if (first.ClickAction != second.ClickAction) |
190 | result |= Diff.CLICKACTION; | 190 | result |= Diff.CLICKACTION; |
191 | if (first.ObjectOwner != second.ObjectOwner) | 191 | if (first.OwnerID != second.OwnerID) |
192 | result |= Diff.OBJECTOWNER; | 192 | result |= Diff.OBJECTOWNER; |
193 | 193 | ||
194 | 194 | ||
diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs index ce50f9e..4521f8e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs | |||
@@ -259,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
259 | if (e.InnerException != null) | 259 | if (e.InnerException != null) |
260 | m_log.Error("[MRM] " + e.InnerException); | 260 | m_log.Error("[MRM] " + e.InnerException); |
261 | 261 | ||
262 | m_scene.Broadcast(delegate(IClientAPI user) | 262 | m_scene.ForEachClient(delegate(IClientAPI user) |
263 | { | 263 | { |
264 | user.SendAlertMessage( | 264 | user.SendAlertMessage( |
265 | "MRM UnAuthorizedAccess: " + e); | 265 | "MRM UnAuthorizedAccess: " + e); |
@@ -268,7 +268,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule | |||
268 | catch (Exception e) | 268 | catch (Exception e) |
269 | { | 269 | { |
270 | m_log.Info("[MRM] Error: " + e); | 270 | m_log.Info("[MRM] Error: " + e); |
271 | m_scene.Broadcast(delegate(IClientAPI user) | 271 | m_scene.ForEachClient(delegate(IClientAPI user) |
272 | { | 272 | { |
273 | user.SendAlertMessage( | 273 | user.SendAlertMessage( |
274 | "Compile error while building MRM script, check OpenSim console for more information."); | 274 | "Compile error while building MRM script, check OpenSim console for more information."); |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index f7c63ac..f7cadaa 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | |||
@@ -588,13 +588,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
588 | { | 588 | { |
589 | } | 589 | } |
590 | 590 | ||
591 | public virtual void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | 591 | public virtual void SendAvatarData(SendAvatarData data) |
592 | uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
593 | { | 592 | { |
594 | } | 593 | } |
595 | 594 | ||
596 | public virtual void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | 595 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) |
597 | Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentId) | ||
598 | { | 596 | { |
599 | } | 597 | } |
600 | 598 | ||
@@ -610,26 +608,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC | |||
610 | { | 608 | { |
611 | } | 609 | } |
612 | 610 | ||
613 | public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, | 611 | public virtual void SendPrimitiveToClient(SendPrimitiveData data) |
614 | PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, | ||
615 | Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, | ||
616 | UUID objectID, UUID ownerID, string text, byte[] color, | ||
617 | uint parentID, | ||
618 | byte[] particleSystem, byte clickAction, byte material) | ||
619 | { | 612 | { |
620 | } | 613 | } |
621 | public virtual void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, | 614 | |
622 | PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, | 615 | public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
623 | Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, | ||
624 | UUID objectID, UUID ownerID, string text, byte[] color, | ||
625 | uint parentID, | ||
626 | byte[] particleSystem, byte clickAction, byte material, byte[] textureanimation, | ||
627 | bool attachment, uint AttachmentPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius) | ||
628 | { | 616 | { |
629 | } | 617 | } |
630 | public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | 618 | |
631 | Vector3 position, Quaternion rotation, Vector3 velocity, | 619 | public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) |
632 | Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) | ||
633 | { | 620 | { |
634 | } | 621 | } |
635 | 622 | ||
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 1ea08e2..f609e73 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -289,6 +289,9 @@ namespace OpenSim.Region.Physics.Meshing | |||
289 | ManagedImage managedImage; // we never use this | 289 | ManagedImage managedImage; // we never use this |
290 | OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata); | 290 | OpenJPEG.DecodeToImage(primShape.SculptData, out managedImage, out idata); |
291 | 291 | ||
292 | // Remove the reference to the encoded JPEG2000 data so it can be GCed | ||
293 | primShape.SculptData = Utils.EmptyBytes; | ||
294 | |||
292 | if (cacheSculptMaps) | 295 | if (cacheSculptMaps) |
293 | { | 296 | { |
294 | try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } | 297 | try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } |
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 1fff846..ef0e56e 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | |||
@@ -139,8 +139,14 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
139 | public int m_eventsubscription = 0; | 139 | public int m_eventsubscription = 0; |
140 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); | 140 | private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); |
141 | 141 | ||
142 | // unique UUID of this character object | ||
143 | public UUID m_uuid; | ||
144 | public bool bad = false; | ||
145 | |||
142 | public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos, CollisionLocker dode, PhysicsVector size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) | 146 | public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos, CollisionLocker dode, PhysicsVector size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) |
143 | { | 147 | { |
148 | m_uuid = UUID.Random(); | ||
149 | |||
144 | // ode = dode; | 150 | // ode = dode; |
145 | _velocity = new PhysicsVector(); | 151 | _velocity = new PhysicsVector(); |
146 | _target_velocity = new PhysicsVector(); | 152 | _target_velocity = new PhysicsVector(); |
@@ -1112,10 +1118,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1112 | } | 1118 | } |
1113 | catch (NullReferenceException) | 1119 | catch (NullReferenceException) |
1114 | { | 1120 | { |
1121 | bad = true; | ||
1115 | _parent_scene.BadCharacter(this); | 1122 | _parent_scene.BadCharacter(this); |
1116 | vec = new d.Vector3(_position.X, _position.Y, _position.Z); | 1123 | vec = new d.Vector3(_position.X, _position.Y, _position.Z); |
1117 | base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! | 1124 | base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! |
1118 | m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar: {0}", m_name); | 1125 | m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar {0}, physical actor {1}", m_name, m_uuid); |
1119 | } | 1126 | } |
1120 | 1127 | ||
1121 | 1128 | ||
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 92afe39..0c94fb6 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | |||
@@ -1664,6 +1664,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
1664 | if (!_characters.Contains(chr)) | 1664 | if (!_characters.Contains(chr)) |
1665 | { | 1665 | { |
1666 | _characters.Add(chr); | 1666 | _characters.Add(chr); |
1667 | if (chr.bad) | ||
1668 | m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid); | ||
1667 | } | 1669 | } |
1668 | } | 1670 | } |
1669 | } | 1671 | } |
@@ -2581,7 +2583,11 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2581 | lock (_taintedActors) | 2583 | lock (_taintedActors) |
2582 | { | 2584 | { |
2583 | if (!(_taintedActors.Contains(taintedchar))) | 2585 | if (!(_taintedActors.Contains(taintedchar))) |
2586 | { | ||
2584 | _taintedActors.Add(taintedchar); | 2587 | _taintedActors.Add(taintedchar); |
2588 | if (taintedchar.bad) | ||
2589 | m_log.DebugFormat("[PHYSICS]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid); | ||
2590 | } | ||
2585 | } | 2591 | } |
2586 | } | 2592 | } |
2587 | } | 2593 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e10e612..57b14f7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2875,7 +2875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2875 | { | 2875 | { |
2876 | m_host.AddScriptLPS(1); | 2876 | m_host.AddScriptLPS(1); |
2877 | 2877 | ||
2878 | return m_host.ObjectOwner.ToString(); | 2878 | return m_host.OwnerID.ToString(); |
2879 | } | 2879 | } |
2880 | 2880 | ||
2881 | public void llInstantMessage(string user, string message) | 2881 | public void llInstantMessage(string user, string message) |
@@ -5634,7 +5634,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5634 | ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); | 5634 | ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); |
5635 | if (parcel != null) | 5635 | if (parcel != null) |
5636 | { | 5636 | { |
5637 | if (m_host.ObjectOwner == parcel.LandData.OwnerID || | 5637 | if (m_host.OwnerID == parcel.LandData.OwnerID || |
5638 | (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID | 5638 | (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID |
5639 | && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) | 5639 | && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) |
5640 | { | 5640 | { |
@@ -7157,7 +7157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7157 | 7157 | ||
7158 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 7158 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
7159 | 7159 | ||
7160 | if (land.LandData.OwnerID != m_host.ObjectOwner) | 7160 | if (land.LandData.OwnerID != m_host.OwnerID) |
7161 | return; | 7161 | return; |
7162 | 7162 | ||
7163 | land.SetMusicUrl(url); | 7163 | land.SetMusicUrl(url); |
@@ -7215,7 +7215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7215 | public LSL_String llGetCreator() | 7215 | public LSL_String llGetCreator() |
7216 | { | 7216 | { |
7217 | m_host.AddScriptLPS(1); | 7217 | m_host.AddScriptLPS(1); |
7218 | return m_host.ObjectCreator.ToString(); | 7218 | return m_host.CreatorID.ToString(); |
7219 | } | 7219 | } |
7220 | 7220 | ||
7221 | public LSL_String llGetTimestamp() | 7221 | public LSL_String llGetTimestamp() |
@@ -8396,7 +8396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8396 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); | 8396 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); |
8397 | if (null != dm) | 8397 | if (null != dm) |
8398 | dm.SendUrlToUser( | 8398 | dm.SendUrlToUser( |
8399 | new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.ObjectOwner, false, message, url); | 8399 | new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url); |
8400 | 8400 | ||
8401 | ConditionalScriptSleep(10000); | 8401 | ConditionalScriptSleep(10000); |
8402 | } | 8402 | } |
@@ -8411,7 +8411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8411 | // according to the docs, this command only works if script owner and land owner are the same | 8411 | // according to the docs, this command only works if script owner and land owner are the same |
8412 | // lets add estate owners and gods, too, and use the generic permission check. | 8412 | // lets add estate owners and gods, too, and use the generic permission check. |
8413 | ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 8413 | ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
8414 | if (!World.Permissions.CanEditParcel(m_host.ObjectOwner, landObject)) return; | 8414 | if (!World.Permissions.CanEditParcel(m_host.OwnerID, landObject)) return; |
8415 | 8415 | ||
8416 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? | 8416 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? |
8417 | byte loop = 0; | 8417 | byte loop = 0; |
@@ -9081,9 +9081,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9081 | Vector3 velocity = m_host.Velocity; | 9081 | Vector3 velocity = m_host.Velocity; |
9082 | Quaternion rotation = m_host.RotationOffset; | 9082 | Quaternion rotation = m_host.RotationOffset; |
9083 | string ownerName = String.Empty; | 9083 | string ownerName = String.Empty; |
9084 | ScenePresence scenePresence = World.GetScenePresence(m_host.ObjectOwner); | 9084 | ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID); |
9085 | if (scenePresence == null) | 9085 | if (scenePresence == null) |
9086 | ownerName = resolveName(m_host.ObjectOwner); | 9086 | ownerName = resolveName(m_host.OwnerID); |
9087 | else | 9087 | else |
9088 | ownerName = scenePresence.Name; | 9088 | ownerName = scenePresence.Name; |
9089 | 9089 | ||
@@ -9108,7 +9108,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9108 | httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); | 9108 | httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); |
9109 | httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W); | 9109 | httpHeaders["X-SecondLife-Local-Rotation"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000})", rotation.X, rotation.Y, rotation.Z, rotation.W); |
9110 | httpHeaders["X-SecondLife-Owner-Name"] = ownerName; | 9110 | httpHeaders["X-SecondLife-Owner-Name"] = ownerName; |
9111 | httpHeaders["X-SecondLife-Owner-Key"] = m_host.ObjectOwner.ToString(); | 9111 | httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString(); |
9112 | string userAgent = config.Configs["Network"].GetString("user_agent", null); | 9112 | string userAgent = config.Configs["Network"].GetString("user_agent", null); |
9113 | if (userAgent != null) | 9113 | if (userAgent != null) |
9114 | httpHeaders["User-Agent"] = userAgent; | 9114 | httpHeaders["User-Agent"] = userAgent; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 4cb4b61..52396b6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | |||
@@ -1164,7 +1164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1164 | ILandObject land | 1164 | ILandObject land |
1165 | = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 1165 | = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
1166 | 1166 | ||
1167 | if (land.LandData.OwnerID != m_host.ObjectOwner) | 1167 | if (land.LandData.OwnerID != m_host.OwnerID) |
1168 | return; | 1168 | return; |
1169 | 1169 | ||
1170 | land.SetMediaUrl(url); | 1170 | land.SetMediaUrl(url); |
@@ -1182,7 +1182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
1182 | ILandObject land | 1182 | ILandObject land |
1183 | = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 1183 | = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
1184 | 1184 | ||
1185 | if (land.LandData.OwnerID != m_host.ObjectOwner) | 1185 | if (land.LandData.OwnerID != m_host.OwnerID) |
1186 | { | 1186 | { |
1187 | OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function"); | 1187 | OSSLError("osSetParcelSIPAddress: Sorry, you need to own the land to use this function"); |
1188 | return; | 1188 | return; |