aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs47
-rw-r--r--OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs20
-rw-r--r--OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs16
-rw-r--r--OpenSim/Framework/IClientAPI.cs258
-rw-r--r--OpenSim/Framework/ISceneEntity.cs37
-rw-r--r--OpenSim/Framework/Lazy.cs236
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs626
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs18
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandChannel.cs16
-rw-r--r--OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs10
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs14
-rw-r--r--OpenSim/Region/Framework/Interfaces/ILandChannel.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs36
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs29
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs34
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs14
-rw-r--r--OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs82
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs15
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs14
-rw-r--r--OpenSim/Tests/Common/Mock/TestLandChannel.cs4
22 files changed, 847 insertions, 696 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index 1d6d4c1..a62d897 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -1026,23 +1026,6 @@ namespace OpenSim.Client.MXP.ClientStack
1026 // Need to translate to MXP somehow 1026 // Need to translate to MXP somehow
1027 } 1027 }
1028 1028
1029 public void SendAvatarData(SendAvatarData data)
1030 {
1031 //ScenePresence presence=((Scene)this.Scene).GetScenePresence(avatarID);
1032 UUID ownerID = data.AvatarID;
1033 MXPSendAvatarData(data.FirstName + " " + data.LastName, ownerID, UUID.Zero, data.AvatarID, data.AvatarLocalID, data.Position, data.Rotation);
1034 }
1035
1036 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
1037 {
1038 MovementEventMessage me = new MovementEventMessage();
1039 me.ObjectIndex = data.LocalID;
1040 me.Location = ToOmVector(data.Position);
1041 me.Orientation = ToOmQuaternion(data.Rotation);
1042
1043 Session.Send(me);
1044 }
1045
1046 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 1029 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
1047 { 1030 {
1048 // Minimap function, not used. 1031 // Minimap function, not used.
@@ -1058,23 +1041,31 @@ namespace OpenSim.Client.MXP.ClientStack
1058 // Need to translate to MXP somehow 1041 // Need to translate to MXP somehow
1059 } 1042 }
1060 1043
1061 public void SendPrimitiveToClient(SendPrimitiveData data) 1044 public void SendAvatarDataImmediate(ISceneEntity avatar)
1062 { 1045 {
1063 MXPSendPrimitive(data.localID, data.ownerID, data.acc, data.rvel, data.primShape, data.pos, data.objectID, data.vel, 1046 //ScenePresence presence=((Scene)this.Scene).GetScenePresence(avatarID);
1064 data.rotation, (uint)data.flags, data.text, data.color, data.parentID, data.particleSystem, data.clickAction, 1047 ScenePresence presence = (ScenePresence)avatar;
1065 data.material, data.textureanim); 1048 UUID ownerID = presence.UUID;
1049 MXPSendAvatarData(presence.Firstname + " " + presence.Lastname, ownerID, UUID.Zero, presence.UUID, presence.LocalId, presence.AbsolutePosition, presence.Rotation);
1066 } 1050 }
1067 1051
1068 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 1052 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
1069 { 1053 {
1070 MovementEventMessage me = new MovementEventMessage(); 1054 //MovementEventMessage me = new MovementEventMessage();
1071 me.ObjectIndex = data.LocalID; 1055 //me.ObjectIndex = data.LocalID;
1072 me.Location = ToOmVector(data.Position); 1056 //me.Location = ToOmVector(data.Position);
1073 me.Orientation = ToOmQuaternion(data.Rotation); 1057 //me.Orientation = ToOmQuaternion(data.Rotation);
1074 Session.Send(me); 1058
1059 //MXPSendPrimitive(data.localID, data.ownerID, data.acc, data.rvel, data.primShape, data.pos, data.objectID, data.vel,
1060 // data.rotation, (uint)data.flags, data.text, data.color, data.parentID, data.particleSystem, data.clickAction,
1061 // data.material, data.textureanim);
1062
1063 //Session.Send(me);
1064
1065 throw new System.NotImplementedException();
1075 } 1066 }
1076 1067
1077 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 1068 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
1078 { 1069 {
1079 } 1070 }
1080 1071
diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs
index 43c64e9..d1f0988 100644
--- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs
+++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs
@@ -584,16 +584,6 @@ namespace OpenSim.Client.Sirikata.ClientStack
584 throw new System.NotImplementedException(); 584 throw new System.NotImplementedException();
585 } 585 }
586 586
587 public void SendAvatarData(SendAvatarData data)
588 {
589 throw new System.NotImplementedException();
590 }
591
592 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
593 {
594 throw new System.NotImplementedException();
595 }
596
597 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 587 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
598 { 588 {
599 throw new System.NotImplementedException(); 589 throw new System.NotImplementedException();
@@ -609,27 +599,27 @@ namespace OpenSim.Client.Sirikata.ClientStack
609 throw new System.NotImplementedException(); 599 throw new System.NotImplementedException();
610 } 600 }
611 601
612 public void SendPrimitiveToClient(SendPrimitiveData data) 602 public void SendAvatarDataImmediate(ISceneEntity avatar)
613 { 603 {
614 throw new System.NotImplementedException(); 604 throw new System.NotImplementedException();
615 } 605 }
616 606
617 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 607 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
618 { 608 {
619 throw new System.NotImplementedException(); 609 throw new System.NotImplementedException();
620 } 610 }
621 611
622 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 612 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
623 { 613 {
624 throw new System.NotImplementedException(); 614 throw new System.NotImplementedException();
625 } 615 }
626 616
627 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems) 617 public void FlushPrimUpdates()
628 { 618 {
629 throw new System.NotImplementedException(); 619 throw new System.NotImplementedException();
630 } 620 }
631 621
632 public void FlushPrimUpdates() 622 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems)
633 { 623 {
634 throw new System.NotImplementedException(); 624 throw new System.NotImplementedException();
635 } 625 }
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index 864b4f1..c0da326 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -590,16 +590,6 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
590 throw new System.NotImplementedException(); 590 throw new System.NotImplementedException();
591 } 591 }
592 592
593 public void SendAvatarData(SendAvatarData data)
594 {
595 throw new System.NotImplementedException();
596 }
597
598 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
599 {
600 throw new System.NotImplementedException();
601 }
602
603 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 593 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
604 { 594 {
605 throw new System.NotImplementedException(); 595 throw new System.NotImplementedException();
@@ -615,17 +605,17 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
615 throw new System.NotImplementedException(); 605 throw new System.NotImplementedException();
616 } 606 }
617 607
618 public void SendPrimitiveToClient(SendPrimitiveData data) 608 public void SendAvatarDataImmediate(ISceneEntity avatar)
619 { 609 {
620 throw new System.NotImplementedException(); 610 throw new System.NotImplementedException();
621 } 611 }
622 612
623 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 613 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
624 { 614 {
625 throw new System.NotImplementedException(); 615 throw new System.NotImplementedException();
626 } 616 }
627 617
628 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 618 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
629 { 619 {
630 throw new System.NotImplementedException(); 620 throw new System.NotImplementedException();
631 } 621 }
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 01daeb1..00681cf 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -571,207 +571,6 @@ namespace OpenSim.Framework
571 public float dwell; 571 public float dwell;
572 } 572 }
573 573
574 public struct SendAvatarData
575 {
576 public readonly ulong RegionHandle;
577 public readonly string FirstName;
578 public readonly string LastName;
579 public readonly string GroupTitle;
580 public readonly UUID AvatarID;
581 public readonly uint AvatarLocalID;
582 public readonly Vector3 Position;
583 public readonly byte[] TextureEntry;
584 public readonly uint ParentID;
585 public readonly Quaternion Rotation;
586
587 public SendAvatarData(ulong regionHandle, string firstName, string lastName, string groupTitle, UUID avatarID,
588 uint avatarLocalID, Vector3 position, byte[] textureEntry, uint parentID, Quaternion rotation)
589 {
590 RegionHandle = regionHandle;
591 FirstName = firstName;
592 LastName = lastName;
593 GroupTitle = groupTitle;
594 AvatarID = avatarID;
595 AvatarLocalID = avatarLocalID;
596 Position = position;
597 TextureEntry = textureEntry;
598 ParentID = parentID;
599 Rotation = rotation;
600 }
601 }
602
603 public struct SendAvatarTerseData
604 {
605 public readonly ulong RegionHandle;
606 public readonly ushort TimeDilation;
607 public readonly uint LocalID;
608 public readonly Vector3 Position;
609 public readonly Vector3 Velocity;
610 public readonly Vector3 Acceleration;
611 public readonly Quaternion Rotation;
612 public readonly Vector4 CollisionPlane;
613 public readonly UUID AgentID;
614 public readonly byte[] TextureEntry;
615 public readonly double Priority;
616
617 public SendAvatarTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity,
618 Vector3 acceleration, Quaternion rotation, Vector4 collisionPlane, UUID agentid, byte[] textureEntry, double priority)
619 {
620 RegionHandle = regionHandle;
621 TimeDilation = timeDilation;
622 LocalID = localID;
623 Position = position;
624 Velocity = velocity;
625 Acceleration = acceleration;
626 Rotation = rotation;
627 CollisionPlane = collisionPlane;
628 AgentID = agentid;
629 TextureEntry = textureEntry;
630 Priority = priority;
631 }
632 }
633
634 public struct SendPrimitiveTerseData
635 {
636 public readonly ulong RegionHandle;
637 public readonly ushort TimeDilation;
638 public readonly uint LocalID;
639 public readonly Vector3 Position;
640 public readonly Quaternion Rotation;
641 public readonly Vector3 Velocity;
642 public readonly Vector3 Acceleration;
643 public readonly Vector3 AngularVelocity;
644 public readonly UUID AssetID;
645 public readonly UUID OwnerID;
646 public readonly int AttachPoint;
647 public readonly byte[] TextureEntry;
648 public readonly double Priority;
649
650 public SendPrimitiveTerseData(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
651 Quaternion rotation, Vector3 velocity, Vector3 acceleration, Vector3 rotationalvelocity,
652 UUID assetID, UUID ownerID, int attachPoint, byte[] textureEntry, double priority)
653 {
654 RegionHandle = regionHandle;
655 TimeDilation = timeDilation;
656 LocalID = localID;
657 Position = position;
658 Rotation = rotation;
659 Velocity = velocity;
660 Acceleration = acceleration;
661 AngularVelocity = rotationalvelocity;
662 AssetID = assetID;
663 OwnerID = ownerID;
664 AttachPoint = attachPoint;
665 TextureEntry = textureEntry;
666 Priority = priority;
667 }
668 }
669
670 public struct SendPrimitiveData
671 {
672 private ulong m_regionHandle;
673 private ushort m_timeDilation;
674 private uint m_localID;
675 private PrimitiveBaseShape m_primShape;
676 private Vector3 m_pos;
677 private Vector3 m_vel;
678 private Vector3 m_acc;
679 private Quaternion m_rotation;
680 private Vector3 m_rvel;
681 private PrimFlags m_flags;
682 private UUID m_objectID;
683 private UUID m_ownerID;
684 private string m_text;
685 private byte[] m_color;
686 private uint m_parentID;
687 private byte[] m_particleSystem;
688 private byte m_clickAction;
689 private byte m_material;
690 private byte[] m_textureanim;
691 private bool m_attachment;
692 private uint m_AttachPoint;
693 private UUID m_AssetId;
694 private UUID m_SoundId;
695 private double m_SoundVolume;
696 private byte m_SoundFlags;
697 private double m_SoundRadius;
698 private double m_priority;
699
700 public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
701 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
702 uint flags, UUID objectID, UUID ownerID, string text, byte[] color,
703 uint parentID, byte[] particleSystem, byte clickAction, byte material, double priority) :
704 this(regionHandle, timeDilation, localID, primShape, pos, vel, acc, rotation, rvel, flags, objectID,
705 ownerID, text, color, parentID, particleSystem, clickAction, material, new byte[0], false, 0, UUID.Zero,
706 UUID.Zero, 0, 0, 0, priority) { }
707
708 public SendPrimitiveData(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
709 Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel,
710 uint flags,
711 UUID objectID, UUID ownerID, string text, byte[] color, uint parentID,
712 byte[] particleSystem,
713 byte clickAction, byte material, byte[] textureanim, bool attachment,
714 uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags,
715 double SoundRadius, double priority)
716 {
717 this.m_regionHandle = regionHandle;
718 this.m_timeDilation = timeDilation;
719 this.m_localID = localID;
720 this.m_primShape = primShape;
721 this.m_pos = pos;
722 this.m_vel = vel;
723 this.m_acc = acc;
724 this.m_rotation = rotation;
725 this.m_rvel = rvel;
726 this.m_flags = (PrimFlags)flags;
727 this.m_objectID = objectID;
728 this.m_ownerID = ownerID;
729 this.m_text = text;
730 this.m_color = color;
731 this.m_parentID = parentID;
732 this.m_particleSystem = particleSystem;
733 this.m_clickAction = clickAction;
734 this.m_material = material;
735 this.m_textureanim = textureanim;
736 this.m_attachment = attachment;
737 this.m_AttachPoint = AttachPoint;
738 this.m_AssetId = AssetId;
739 this.m_SoundId = SoundId;
740 this.m_SoundVolume = SoundVolume;
741 this.m_SoundFlags = SoundFlags;
742 this.m_SoundRadius = SoundRadius;
743 this.m_priority = priority;
744 }
745
746 public ulong regionHandle { get { return this.m_regionHandle; } }
747 public ushort timeDilation { get { return this.m_timeDilation; } }
748 public uint localID { get { return this.m_localID; } }
749 public PrimitiveBaseShape primShape { get { return this.m_primShape; } }
750 public Vector3 pos { get { return this.m_pos; } }
751 public Vector3 vel { get { return this.m_vel; } }
752 public Vector3 acc { get { return this.m_acc; } }
753 public Quaternion rotation { get { return this.m_rotation; } }
754 public Vector3 rvel { get { return this.m_rvel; } }
755 public PrimFlags flags { get { return this.m_flags; } }
756 public UUID objectID { get { return this.m_objectID; } }
757 public UUID ownerID { get { return this.m_ownerID; } }
758 public string text { get { return this.m_text; } }
759 public byte[] color { get { return this.m_color; } }
760 public uint parentID { get { return this.m_parentID; } }
761 public byte[] particleSystem { get { return this.m_particleSystem; } }
762 public byte clickAction { get { return this.m_clickAction; } }
763 public byte material { get { return this.m_material; } }
764 public byte[] textureanim { get { return this.m_textureanim; } }
765 public bool attachment { get { return this.m_attachment; } }
766 public uint AttachPoint { get { return this.m_AttachPoint; } }
767 public UUID AssetId { get { return this.m_AssetId; } }
768 public UUID SoundId { get { return this.m_SoundId; } }
769 public double SoundVolume { get { return this.m_SoundVolume; } }
770 public byte SoundFlags { get { return this.m_SoundFlags; } }
771 public double SoundRadius { get { return this.m_SoundRadius; } }
772 public double priority { get { return this.m_priority; } }
773 }
774
775 public struct UpdatePriorityData { 574 public struct UpdatePriorityData {
776 private double m_priority; 575 private double m_priority;
777 private uint m_localID; 576 private uint m_localID;
@@ -785,14 +584,46 @@ namespace OpenSim.Framework
785 public uint localID { get { return this.m_localID; } } 584 public uint localID { get { return this.m_localID; } }
786 } 585 }
787 586
587 /// <summary>
588 /// Specifies the fields that have been changed when sending a prim or
589 /// avatar update
590 /// </summary>
788 [Flags] 591 [Flags]
789 public enum StateUpdateTypes 592 public enum PrimUpdateFlags : uint
790 { 593 {
791 None = 0, 594 None = 0,
792 AvatarTerse = 1, 595 AttachmentPoint = 1 << 0,
793 PrimitiveTerse = AvatarTerse << 1, 596 Material = 1 << 1,
794 PrimitiveFull = PrimitiveTerse << 1, 597 ClickAction = 1 << 2,
795 All = AvatarTerse | PrimitiveTerse | PrimitiveFull, 598 Scale = 1 << 3,
599 ParentID = 1 << 4,
600 PrimFlags = 1 << 5,
601 PrimData = 1 << 6,
602 MediaURL = 1 << 7,
603 ScratchPad = 1 << 8,
604 Textures = 1 << 9,
605 TextureAnim = 1 << 10,
606 NameValue = 1 << 11,
607 Position = 1 << 12,
608 Rotation = 1 << 13,
609 Velocity = 1 << 14,
610 Acceleration = 1 << 15,
611 AngularVelocity = 1 << 16,
612 CollisionPlane = 1 << 17,
613 Text = 1 << 18,
614 Particles = 1 << 19,
615 ExtraData = 1 << 20,
616 Sound = 1 << 21,
617 Joint = 1 << 22,
618 FullUpdate = UInt32.MaxValue
619 }
620
621 public static class PrimUpdateFlagsExtensions
622 {
623 public static bool HasFlag(this PrimUpdateFlags updateFlags, PrimUpdateFlags flag)
624 {
625 return (updateFlags & flag) == flag;
626 }
796 } 627 }
797 628
798 public interface IClientAPI 629 public interface IClientAPI
@@ -1186,27 +1017,20 @@ namespace OpenSim.Framework
1186 void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance); 1017 void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance);
1187 void SendPayPrice(UUID objectID, int[] payPrice); 1018 void SendPayPrice(UUID objectID, int[] payPrice);
1188 1019
1189 void SendAvatarData(SendAvatarData data);
1190
1191 void SendAvatarTerseUpdate(SendAvatarTerseData data);
1192
1193 void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations); 1020 void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations);
1194 1021
1195 void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID); 1022 void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID);
1196 void SetChildAgentThrottle(byte[] throttle); 1023 void SetChildAgentThrottle(byte[] throttle);
1197 1024
1198 void SendPrimitiveToClient(SendPrimitiveData data); 1025 void SendAvatarDataImmediate(ISceneEntity avatar);
1199 1026 void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags);
1200 void SendPrimTerseUpdate(SendPrimitiveTerseData data); 1027 void ReprioritizeUpdates(UpdatePriorityHandler handler);
1201 1028 void FlushPrimUpdates();
1202 void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler);
1203 1029
1204 void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, 1030 void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items,
1205 List<InventoryFolderBase> folders, int version, bool fetchFolders, 1031 List<InventoryFolderBase> folders, int version, bool fetchFolders,
1206 bool fetchItems); 1032 bool fetchItems);
1207 1033
1208 void FlushPrimUpdates();
1209
1210 void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item); 1034 void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item);
1211 1035
1212 /// <summary> 1036 /// <summary>
diff --git a/OpenSim/Framework/ISceneEntity.cs b/OpenSim/Framework/ISceneEntity.cs
new file mode 100644
index 0000000..fa3c514
--- /dev/null
+++ b/OpenSim/Framework/ISceneEntity.cs
@@ -0,0 +1,37 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Framework
31{
32 public interface ISceneEntity
33 {
34 UUID UUID { get; }
35 uint LocalId { get; }
36 }
37}
diff --git a/OpenSim/Framework/Lazy.cs b/OpenSim/Framework/Lazy.cs
new file mode 100644
index 0000000..8a417ac
--- /dev/null
+++ b/OpenSim/Framework/Lazy.cs
@@ -0,0 +1,236 @@
1//
2// Lazy.cs
3//
4// Authors:
5// Zoltan Varga (vargaz@gmail.com)
6// Marek Safar (marek.safar@gmail.com)
7//
8// Copyright (C) 2009 Novell
9//
10// Permission is hereby granted, free of charge, to any person obtaining
11// a copy of this software and associated documentation files (the
12// "Software"), to deal in the Software without restriction, including
13// without limitation the rights to use, copy, modify, merge, publish,
14// distribute, sublicense, and/or sell copies of the Software, and to
15// permit persons to whom the Software is furnished to do so, subject to
16// the following conditions:
17//
18// The above copyright notice and this permission notice shall be
19// included in all copies or substantial portions of the Software.
20//
21// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28//
29
30using System;
31using System.Runtime.Serialization;
32using System.Runtime.InteropServices;
33using System.Security.Permissions;
34using System.Threading;
35using System.Diagnostics;
36
37namespace OpenSim.Framework
38{
39 public enum LazyThreadSafetyMode
40 {
41 None,
42 PublicationOnly,
43 ExecutionAndPublication
44 }
45
46 [SerializableAttribute]
47 [ComVisibleAttribute(false)]
48 [HostProtectionAttribute(SecurityAction.LinkDemand, Synchronization = true, ExternalThreading = true)]
49 public class Lazy<T>
50 {
51 T value;
52 bool inited;
53 LazyThreadSafetyMode mode;
54 Func<T> factory;
55 object monitor;
56 Exception exception;
57
58 public Lazy()
59 : this(LazyThreadSafetyMode.ExecutionAndPublication)
60 {
61 }
62
63 public Lazy(Func<T> valueFactory)
64 : this(valueFactory, LazyThreadSafetyMode.ExecutionAndPublication)
65 {
66 }
67
68 public Lazy(bool isThreadSafe)
69 : this(() => Activator.CreateInstance<T>(), isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None)
70 {
71 }
72
73 public Lazy(Func<T> valueFactory, bool isThreadSafe)
74 : this(valueFactory, isThreadSafe ? LazyThreadSafetyMode.ExecutionAndPublication : LazyThreadSafetyMode.None)
75 {
76 }
77
78 public Lazy(LazyThreadSafetyMode mode)
79 : this(() => Activator.CreateInstance<T>(), mode)
80 {
81 }
82
83 public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode)
84 {
85 if (valueFactory == null)
86 throw new ArgumentNullException("valueFactory");
87 this.factory = valueFactory;
88 if (mode != LazyThreadSafetyMode.None)
89 monitor = new object();
90 this.mode = mode;
91 }
92
93 // Don't trigger expensive initialization
94 [DebuggerBrowsable(DebuggerBrowsableState.Never)]
95 public T Value
96 {
97 get
98 {
99 if (inited)
100 return value;
101 if (exception != null)
102 throw exception;
103
104 return InitValue();
105 }
106 }
107
108 T InitValue()
109 {
110 switch (mode)
111 {
112 case LazyThreadSafetyMode.None:
113 {
114 var init_factory = factory;
115 if (init_factory == null)
116 throw exception = new InvalidOperationException("The initialization function tries to access Value on this instance");
117 try
118 {
119 factory = null;
120 T v = init_factory();
121 value = v;
122 Thread.MemoryBarrier();
123 inited = true;
124 }
125 catch (Exception ex)
126 {
127 exception = ex;
128 throw;
129 }
130 break;
131 }
132 case LazyThreadSafetyMode.PublicationOnly:
133 {
134 var init_factory = factory;
135 T v;
136
137 //exceptions are ignored
138 if (init_factory != null)
139 v = init_factory();
140 else
141 v = default(T);
142
143 lock (monitor)
144 {
145 if (inited)
146 return value;
147 value = v;
148 Thread.MemoryBarrier();
149 inited = true;
150 factory = null;
151 }
152 break;
153 }
154 case LazyThreadSafetyMode.ExecutionAndPublication:
155 {
156 lock (monitor)
157 {
158 if (inited)
159 return value;
160
161 if (factory == null)
162 throw exception = new InvalidOperationException("The initialization function tries to access Value on this instance");
163
164 var init_factory = factory;
165 try
166 {
167 factory = null;
168 T v = init_factory();
169 value = v;
170 Thread.MemoryBarrier();
171 inited = true;
172 }
173 catch (Exception ex)
174 {
175 exception = ex;
176 throw;
177 }
178 }
179 break;
180 }
181 default:
182 throw new InvalidOperationException("Invalid LazyThreadSafetyMode " + mode);
183 }
184
185 if (monitor == null)
186 {
187 value = factory();
188 inited = true;
189 }
190 else
191 {
192 lock (monitor)
193 {
194 if (inited)
195 return value;
196
197 if (factory == null)
198 throw new InvalidOperationException("The initialization function tries to access Value on this instance");
199
200 var init_factory = factory;
201 try
202 {
203 factory = null;
204 T v = init_factory();
205 value = v;
206 Thread.MemoryBarrier();
207 inited = true;
208 }
209 catch
210 {
211 factory = init_factory;
212 throw;
213 }
214 }
215 }
216
217 return value;
218 }
219
220 public bool IsValueCreated
221 {
222 get
223 {
224 return inited;
225 }
226 }
227
228 public override string ToString()
229 {
230 if (inited)
231 return value.ToString();
232 else
233 return "Value is not created";
234 }
235 }
236}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 1f3582c..11dca8d 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -50,43 +50,17 @@ using Nini.Config;
50 50
51namespace OpenSim.Region.ClientStack.LindenUDP 51namespace OpenSim.Region.ClientStack.LindenUDP
52{ 52{
53 #region Enums 53 public class EntityUpdate
54
55 /// <summary>
56 /// Specifies the fields that have been changed when sending a prim or
57 /// avatar update
58 /// </summary>
59 [Flags]
60 public enum PrimUpdateFlags : uint
61 { 54 {
62 None = 0, 55 public ISceneEntity Entity;
63 AttachmentPoint = 1 << 0, 56 public PrimUpdateFlags Flags;
64 Material = 1 << 1,
65 ClickAction = 1 << 2,
66 Scale = 1 << 3,
67 ParentID = 1 << 4,
68 PrimFlags = 1 << 5,
69 PrimData = 1 << 6,
70 MediaURL = 1 << 7,
71 ScratchPad = 1 << 8,
72 Textures = 1 << 9,
73 TextureAnim = 1 << 10,
74 NameValue = 1 << 11,
75 Position = 1 << 12,
76 Rotation = 1 << 13,
77 Velocity = 1 << 14,
78 Acceleration = 1 << 15,
79 AngularVelocity = 1 << 16,
80 CollisionPlane = 1 << 17,
81 Text = 1 << 18,
82 Particles = 1 << 19,
83 ExtraData = 1 << 20,
84 Sound = 1 << 21,
85 Joint = 1 << 22,
86 FullUpdate = UInt32.MaxValue
87 }
88 57
89 #endregion Enums 58 public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags)
59 {
60 Entity = entity;
61 Flags = flags;
62 }
63 }
90 64
91 public delegate bool PacketMethod(IClientAPI simClient, Packet packet); 65 public delegate bool PacketMethod(IClientAPI simClient, Packet packet);
92 66
@@ -350,9 +324,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
350 private readonly IGroupsModule m_GroupsModule; 324 private readonly IGroupsModule m_GroupsModule;
351 325
352 private int m_cachedTextureSerial; 326 private int m_cachedTextureSerial;
353 protected PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates; 327 private PriorityQueue<double, EntityUpdate> m_entityUpdates;
354 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates;
355 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates;
356 328
357 /// <value> 329 /// <value>
358 /// List used in construction of data blocks for an object update packet. This is to stop us having to 330 /// List used in construction of data blocks for an object update packet. This is to stop us having to
@@ -463,9 +435,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
463 435
464 m_scene = scene; 436 m_scene = scene;
465 437
466 m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 438 m_entityUpdates = new PriorityQueue<double, EntityUpdate>(m_scene.Entities.Count);
467 m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
468 m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count);
469 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>(); 439 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
470 m_killRecord = new HashSet<uint>(); 440 m_killRecord = new HashSet<uint>();
471 441
@@ -1519,7 +1489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1519 kill.Header.Reliable = true; 1489 kill.Header.Reliable = true;
1520 kill.Header.Zerocoded = true; 1490 kill.Header.Zerocoded = true;
1521 1491
1522 lock (m_primFullUpdates.SyncRoot) 1492 lock (m_entityUpdates.SyncRoot)
1523 { 1493 {
1524 m_killRecord.Add(localID); 1494 m_killRecord.Add(localID);
1525 OutPacket(kill, ThrottleOutPacketType.State); 1495 OutPacket(kill, ThrottleOutPacketType.State);
@@ -3419,71 +3389,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3419 /// <summary> 3389 /// <summary>
3420 /// Send an ObjectUpdate packet with information about an avatar 3390 /// Send an ObjectUpdate packet with information about an avatar
3421 /// </summary> 3391 /// </summary>
3422 public void SendAvatarData(SendAvatarData data) 3392 public void SendAvatarDataImmediate(ISceneEntity avatar)
3423 { 3393 {
3394 ScenePresence presence = avatar as ScenePresence;
3395 if (presence == null)
3396 return;
3397
3424 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3398 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3425 objupdate.Header.Zerocoded = true; 3399 objupdate.Header.Zerocoded = true;
3426 3400
3427 objupdate.RegionData.RegionHandle = data.RegionHandle; 3401 objupdate.RegionData.RegionHandle = presence.RegionHandle;
3428 objupdate.RegionData.TimeDilation = ushort.MaxValue; 3402 objupdate.RegionData.TimeDilation = ushort.MaxValue;
3429 3403
3430 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3404 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3431 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); 3405 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
3432 3406
3433 OutPacket(objupdate, ThrottleOutPacketType.Task); 3407 OutPacket(objupdate, ThrottleOutPacketType.Task);
3434 } 3408 }
3435 3409
3436 /// <summary>
3437 /// Send a terse positional/rotation/velocity update about an avatar
3438 /// to the client. This avatar can be that of the client itself.
3439 /// </summary>
3440 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
3441 {
3442 if (data.Priority == double.NaN)
3443 {
3444 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update");
3445 return;
3446 }
3447
3448 Quaternion rotation = data.Rotation;
3449 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3450 rotation = Quaternion.Identity;
3451
3452 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data);
3453
3454 lock (m_avatarTerseUpdates.SyncRoot)
3455 m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID);
3456
3457 // If we received an update about our own avatar, process the avatar update priority queue immediately
3458 if (data.AgentID == m_agentId)
3459 ProcessAvatarTerseUpdates();
3460 }
3461
3462 protected void ProcessAvatarTerseUpdates()
3463 {
3464 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3465 terse.Header.Reliable = false;
3466 terse.Header.Zerocoded = true;
3467
3468 //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
3469 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3470 terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3471
3472 lock (m_avatarTerseUpdates.SyncRoot)
3473 {
3474 int count = Math.Min(m_avatarTerseUpdates.Count, m_udpServer.AvatarTerseUpdatesPerPacket);
3475 if (count == 0)
3476 return;
3477
3478 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3479 for (int i = 0; i < count; i++)
3480 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3481 }
3482
3483 // HACK: Using the task category until the tiered reprioritization code is in
3484 OutPacket(terse, ThrottleOutPacketType.Task);
3485 }
3486
3487 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3410 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
3488 { 3411 {
3489 if (!IsActive) return; // We don't need to update inactive clients. 3412 if (!IsActive) return; // We don't need to update inactive clients.
@@ -3528,172 +3451,187 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3528 3451
3529 #region Primitive Packet/Data Sending Methods 3452 #region Primitive Packet/Data Sending Methods
3530 3453
3531 public void SendPrimitiveToClient(SendPrimitiveData data) 3454 /// <summary>
3455 /// Generate one of the object update packets based on PrimUpdateFlags
3456 /// and broadcast the packet to clients
3457 /// </summary>
3458 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
3532 { 3459 {
3533// string text = data.text; 3460 double priority;
3534// if (text.IndexOf("\n") >= 0)
3535// text = text.Remove(text.IndexOf("\n"));
3536// m_log.DebugFormat(
3537// "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}",
3538// data.localID, text, Name);
3539
3540 if (data.priority == double.NaN)
3541 {
3542 m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update");
3543 return;
3544 }
3545
3546 Quaternion rotation = data.rotation;
3547 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3548 rotation = Quaternion.Identity;
3549
3550 if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD
3551 return;
3552 if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9)
3553 return;
3554 3461
3555 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); 3462 if (entity is SceneObjectPart)
3463 priority = ((SceneObjectPart)entity).ParentGroup.GetUpdatePriority(this);
3464 else if (entity is ScenePresence)
3465 priority = ((ScenePresence)entity).GetUpdatePriority(this);
3466 else
3467 priority = 0.0d;
3556 3468
3557 lock (m_primFullUpdates.SyncRoot) 3469 lock (m_entityUpdates.SyncRoot)
3558 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); 3470 m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId);
3559 } 3471 }
3560 3472
3561 void ProcessPrimFullUpdates() 3473 private void ProcessEntityUpdates(int maxUpdates)
3562 { 3474 {
3563 ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3475 Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
3564 outPacket.Header.Zerocoded = true; 3476 Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
3477 Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
3565 3478
3566 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3479 if (maxUpdates <= 0) maxUpdates = Int32.MaxValue;
3567 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); 3480 int updatesThisCall = 0;
3568 3481
3569 lock (m_primFullUpdates.SyncRoot) 3482 lock (m_entityUpdates.SyncRoot)
3570 { 3483 {
3571 int count = Math.Min(m_primFullUpdates.Count, m_udpServer.PrimFullUpdatesPerPacket); 3484 EntityUpdate update;
3572 if (count == 0) 3485 while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update))
3573 return;
3574
3575 m_fullUpdateDataBlocksBuilder.Clear();
3576
3577 for (int i = 0; i < count; i++)
3578 { 3486 {
3579 ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue(); 3487 ++updatesThisCall;
3488
3489 #region UpdateFlags to packet type conversion
3580 3490
3581 if (!m_killRecord.Contains(block.ID)) 3491 PrimUpdateFlags updateFlags = update.Flags;
3492
3493 bool canUseCompressed = true;
3494 bool canUseImproved = true;
3495
3496 // Compressed object updates only make sense for LL primitives
3497 if (!(update.Entity is SceneObjectPart))
3498 canUseCompressed = false;
3499
3500 if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate))
3582 { 3501 {
3583 m_fullUpdateDataBlocksBuilder.Add(block); 3502 canUseCompressed = false;
3584 3503 canUseImproved = false;
3585// string text = Util.FieldToString(outPacket.ObjectData[i].Text);
3586// if (text.IndexOf("\n") >= 0)
3587// text = text.Remove(text.IndexOf("\n"));
3588// m_log.DebugFormat(
3589// "[CLIENT]: Sending full info about prim {0} text {1} to client {2}",
3590// outPacket.ObjectData[i].ID, text, Name);
3591 } 3504 }
3592// else 3505 else
3593// { 3506 {
3594// m_log.WarnFormat( 3507 if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) ||
3595// "[CLIENT]: Preventing full update for {0} after kill to {1}", block.ID, Name); 3508 updateFlags.HasFlag(PrimUpdateFlags.Acceleration) ||
3596// } 3509 updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) ||
3510 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3511 {
3512 canUseCompressed = false;
3513 }
3514
3515 if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) ||
3516 updateFlags.HasFlag(PrimUpdateFlags.ParentID) ||
3517 updateFlags.HasFlag(PrimUpdateFlags.Scale) ||
3518 updateFlags.HasFlag(PrimUpdateFlags.PrimData) ||
3519 updateFlags.HasFlag(PrimUpdateFlags.Text) ||
3520 updateFlags.HasFlag(PrimUpdateFlags.NameValue) ||
3521 updateFlags.HasFlag(PrimUpdateFlags.ExtraData) ||
3522 updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) ||
3523 updateFlags.HasFlag(PrimUpdateFlags.Sound) ||
3524 updateFlags.HasFlag(PrimUpdateFlags.Particles) ||
3525 updateFlags.HasFlag(PrimUpdateFlags.Material) ||
3526 updateFlags.HasFlag(PrimUpdateFlags.ClickAction) ||
3527 updateFlags.HasFlag(PrimUpdateFlags.MediaURL) ||
3528 updateFlags.HasFlag(PrimUpdateFlags.Joint))
3529 {
3530 canUseImproved = false;
3531 }
3532 }
3533
3534 #endregion UpdateFlags to packet type conversion
3535
3536 #region Block Construction
3537
3538 // TODO: Remove this once we can build compressed updates
3539 canUseCompressed = false;
3540
3541 if (!canUseImproved && !canUseCompressed)
3542 {
3543 if (update.Entity is ScenePresence)
3544 objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
3545 else
3546 objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
3547 }
3548 else if (!canUseImproved)
3549 {
3550 compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags));
3551 }
3552 else
3553 {
3554 terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
3555 }
3556
3557 #endregion Block Construction
3597 } 3558 }
3559 }
3598 3560
3599 outPacket.ObjectData = m_fullUpdateDataBlocksBuilder.ToArray(); 3561 #region Packet Sending
3600
3601 OutPacket(outPacket, ThrottleOutPacketType.State);
3602 }
3603 }
3604 3562
3605 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 3563 const float TIME_DILATION = 1.0f;
3606 { 3564 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
3607 if (data.Priority == double.NaN) 3565
3566 if (objectUpdateBlocks.IsValueCreated)
3608 { 3567 {
3609 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); 3568 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
3610 return;
3611 }
3612 3569
3613 Quaternion rotation = data.Rotation; 3570 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3614 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) 3571 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3615 rotation = Quaternion.Identity; 3572 packet.RegionData.TimeDilation = timeDilation;
3573 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3616 3574
3617 if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD 3575 for (int i = 0; i < blocks.Count; i++)
3618 return; 3576 packet.ObjectData[i] = blocks[i];
3577
3578 OutPacket(packet, ThrottleOutPacketType.Task, true);
3579 }
3619 3580
3620 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); 3581 if (compressedUpdateBlocks.IsValueCreated)
3582 {
3583 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
3621 3584
3622 lock (m_primTerseUpdates.SyncRoot) 3585 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
3623 m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID); 3586 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3624 } 3587 packet.RegionData.TimeDilation = timeDilation;
3588 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count];
3625 3589
3626 void ProcessPrimTerseUpdates() 3590 for (int i = 0; i < blocks.Count; i++)
3627 { 3591 packet.ObjectData[i] = blocks[i];
3628 ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3629 outPacket.Header.Reliable = false;
3630 outPacket.Header.Zerocoded = true;
3631 3592
3632 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3593 OutPacket(packet, ThrottleOutPacketType.Task, true);
3633 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); 3594 }
3634 3595
3635 lock (m_primTerseUpdates.SyncRoot) 3596 if (terseUpdateBlocks.IsValueCreated)
3636 { 3597 {
3637 int count = Math.Min(m_primTerseUpdates.Count, m_udpServer.PrimTerseUpdatesPerPacket); 3598 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3638 if (count == 0) 3599
3639 return; 3600 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
3601 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3602 packet.RegionData.TimeDilation = timeDilation;
3603 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
3640 3604
3641 outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3605 for (int i = 0; i < blocks.Count; i++)
3642 for (int i = 0; i < count; i++) 3606 packet.ObjectData[i] = blocks[i];
3643 outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); 3607
3608 OutPacket(packet, ThrottleOutPacketType.Task, true);
3644 } 3609 }
3645 3610
3646 OutPacket(outPacket, ThrottleOutPacketType.State); 3611 #endregion Packet Sending
3647 } 3612 }
3648 3613
3649 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 3614 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
3650 { 3615 {
3651 PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler = 3616 //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName);
3652 delegate(ref double priority, uint local_id) 3617
3653 { 3618 PriorityQueue<double, EntityUpdate>.UpdatePriorityHandler update_priority_handler =
3654 priority = handler(new UpdatePriorityData(priority, local_id));
3655 return priority != double.NaN;
3656 };
3657 PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler =
3658 delegate(ref double priority, uint local_id) 3619 delegate(ref double priority, uint local_id)
3659 { 3620 {
3660 priority = handler(new UpdatePriorityData(priority, local_id)); 3621 priority = handler(new UpdatePriorityData(priority, local_id));
3661 return priority != double.NaN; 3622 return priority != double.NaN;
3662 }; 3623 };
3663 3624
3664 if ((type & StateUpdateTypes.AvatarTerse) != 0) 3625 lock (m_entityUpdates.SyncRoot)
3665 { 3626 m_entityUpdates.Reprioritize(update_priority_handler);
3666 lock (m_avatarTerseUpdates.SyncRoot)
3667 m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler);
3668 }
3669
3670 if ((type & StateUpdateTypes.PrimitiveFull) != 0)
3671 {
3672 lock (m_primFullUpdates.SyncRoot)
3673 m_primFullUpdates.Reprioritize(update_priority_handler);
3674 }
3675
3676 if ((type & StateUpdateTypes.PrimitiveTerse) != 0)
3677 {
3678 lock (m_primTerseUpdates.SyncRoot)
3679 m_primTerseUpdates.Reprioritize(terse_update_priority_handler);
3680 }
3681 } 3627 }
3682 3628
3683 public void FlushPrimUpdates() 3629 public void FlushPrimUpdates()
3684 { 3630 {
3685 while (m_primFullUpdates.Count > 0) 3631 m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
3686 { 3632
3687 ProcessPrimFullUpdates(); 3633 while (m_entityUpdates.Count > 0)
3688 } 3634 ProcessEntityUpdates(-1);
3689 while (m_primTerseUpdates.Count > 0)
3690 {
3691 ProcessPrimTerseUpdates();
3692 }
3693 while (m_avatarTerseUpdates.Count > 0)
3694 {
3695 ProcessAvatarTerseUpdates();
3696 }
3697 } 3635 }
3698 3636
3699 #endregion Primitive Packet/Data Sending Methods 3637 #endregion Primitive Packet/Data Sending Methods
@@ -3726,26 +3664,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3726 { 3664 {
3727 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) 3665 if ((categories & ThrottleOutPacketTypeFlags.Task) != 0)
3728 { 3666 {
3729 lock (m_avatarTerseUpdates.SyncRoot) 3667 if (m_entityUpdates.Count > 0)
3730 { 3668 ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback);
3731 if (m_avatarTerseUpdates.Count > 0)
3732 ProcessAvatarTerseUpdates();
3733 }
3734 }
3735
3736 if ((categories & ThrottleOutPacketTypeFlags.State) != 0)
3737 {
3738 lock (m_primFullUpdates.SyncRoot)
3739 {
3740 if (m_primFullUpdates.Count > 0)
3741 ProcessPrimFullUpdates();
3742 }
3743
3744 lock (m_primTerseUpdates.SyncRoot)
3745 {
3746 if (m_primTerseUpdates.Count > 0)
3747 ProcessPrimTerseUpdates();
3748 }
3749 } 3669 }
3750 3670
3751 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) 3671 if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
@@ -4403,22 +4323,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4403 4323
4404 #region Helper Methods 4324 #region Helper Methods
4405 4325
4406 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data) 4326 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture)
4407 { 4327 {
4408 return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity, 4328 #region ScenePresence/SOP Handling
4409 data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry);
4410 }
4411 4329
4412 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) 4330 bool avatar = (entity is ScenePresence);
4413 { 4331 uint localID = entity.LocalId;
4414 return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity, 4332 uint attachPoint;
4415 data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); 4333 Vector4 collisionPlane;
4416 } 4334 Vector3 position, velocity, acceleration, angularVelocity;
4335 Quaternion rotation;
4336 byte[] textureEntry;
4337
4338 if (entity is ScenePresence)
4339 {
4340 ScenePresence presence = (ScenePresence)entity;
4341
4342 attachPoint = 0;
4343 collisionPlane = presence.CollisionPlane;
4344 position = presence.OffsetPosition;
4345 velocity = presence.Velocity;
4346 acceleration = Vector3.Zero;
4347 angularVelocity = Vector3.Zero;
4348 rotation = presence.Rotation;
4349
4350 if (sendTexture)
4351 textureEntry = presence.Appearance.Texture.GetBytes();
4352 else
4353 textureEntry = null;
4354 }
4355 else
4356 {
4357 SceneObjectPart part = (SceneObjectPart)entity;
4358
4359 attachPoint = part.AttachmentPoint;
4360 collisionPlane = Vector4.Zero;
4361 position = part.RelativePosition;
4362 velocity = part.Velocity;
4363 acceleration = part.Acceleration;
4364 angularVelocity = part.AngularVelocity;
4365 rotation = part.RotationOffset;
4366 textureEntry = part.Shape.TextureEntry;
4367 }
4368
4369 #endregion ScenePresence/SOP Handling
4417 4370
4418 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint,
4419 Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation,
4420 Vector3 angularVelocity, byte[] textureEntry)
4421 {
4422 int pos = 0; 4371 int pos = 0;
4423 byte[] data = new byte[(avatar ? 60 : 44)]; 4372 byte[] data = new byte[(avatar ? 60 : 44)];
4424 4373
@@ -4490,12 +4439,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4490 return block; 4439 return block;
4491 } 4440 }
4492 4441
4493 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data) 4442 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data)
4494 { 4443 {
4495 byte[] objectData = new byte[76]; 4444 byte[] objectData = new byte[76];
4496 4445
4497 Vector4.UnitW.ToBytes(objectData, 0); // TODO: Collision plane support 4446 data.CollisionPlane.ToBytes(objectData, 0);
4498 data.Position.ToBytes(objectData, 16); 4447 data.OffsetPosition.ToBytes(objectData, 16);
4499 //data.Velocity.ToBytes(objectData, 28); 4448 //data.Velocity.ToBytes(objectData, 28);
4500 //data.Acceleration.ToBytes(objectData, 40); 4449 //data.Acceleration.ToBytes(objectData, 40);
4501 data.Rotation.ToBytes(objectData, 52); 4450 data.Rotation.ToBytes(objectData, 52);
@@ -4505,12 +4454,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4505 4454
4506 update.Data = Utils.EmptyBytes; 4455 update.Data = Utils.EmptyBytes;
4507 update.ExtraParams = new byte[1]; 4456 update.ExtraParams = new byte[1];
4508 update.FullID = data.AvatarID; 4457 update.FullID = data.UUID;
4509 update.ID = data.AvatarLocalID; 4458 update.ID = data.LocalId;
4510 update.Material = (byte)Material.Flesh; 4459 update.Material = (byte)Material.Flesh;
4511 update.MediaURL = Utils.EmptyBytes; 4460 update.MediaURL = Utils.EmptyBytes;
4512 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " + 4461 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " +
4513 data.LastName + "\nTitle STRING RW SV " + data.GroupTitle); 4462 data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle);
4514 update.ObjectData = objectData; 4463 update.ObjectData = objectData;
4515 update.ParentID = data.ParentID; 4464 update.ParentID = data.ParentID;
4516 update.PathCurve = 16; 4465 update.PathCurve = 16;
@@ -4519,102 +4468,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4519 update.PCode = (byte)PCode.Avatar; 4468 update.PCode = (byte)PCode.Avatar;
4520 update.ProfileCurve = 1; 4469 update.ProfileCurve = 1;
4521 update.PSBlock = Utils.EmptyBytes; 4470 update.PSBlock = Utils.EmptyBytes;
4522 update.Scale = new Vector3(0.45f,0.6f,1.9f); 4471 update.Scale = new Vector3(0.45f, 0.6f, 1.9f);
4523 update.Text = Utils.EmptyBytes; 4472 update.Text = Utils.EmptyBytes;
4524 update.TextColor = new byte[4]; 4473 update.TextColor = new byte[4];
4525 update.TextureAnim = Utils.EmptyBytes; 4474 update.TextureAnim = Utils.EmptyBytes;
4526 update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes; 4475 update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes;
4527 update.UpdateFlags = (uint)(PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | PrimFlags.ObjectOwnerModify);//61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags 4476 update.UpdateFlags = (uint)(
4477 PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner |
4478 PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer |
4479 PrimFlags.ObjectOwnerModify);
4528 4480
4529 return update; 4481 return update;
4530 } 4482 }
4531 4483
4532 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) 4484 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID)
4533 { 4485 {
4534 byte[] objectData = new byte[60]; 4486 byte[] objectData = new byte[60];
4535 data.pos.ToBytes(objectData, 0); 4487 data.RelativePosition.ToBytes(objectData, 0);
4536 data.vel.ToBytes(objectData, 12); 4488 data.Velocity.ToBytes(objectData, 12);
4537 data.acc.ToBytes(objectData, 24); 4489 data.Acceleration.ToBytes(objectData, 24);
4538 data.rotation.ToBytes(objectData, 36); 4490 data.RotationOffset.ToBytes(objectData, 36);
4539 data.rvel.ToBytes(objectData, 48); 4491 data.AngularVelocity.ToBytes(objectData, 48);
4540 4492
4541 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); 4493 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
4542 update.ClickAction = (byte)data.clickAction; 4494 update.ClickAction = (byte)data.ClickAction;
4543 update.CRC = 0; 4495 update.CRC = 0;
4544 update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes; 4496 update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes;
4545 update.FullID = data.objectID; 4497 update.FullID = data.UUID;
4546 update.ID = data.localID; 4498 update.ID = data.LocalId;
4547 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated 4499 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
4548 //update.JointPivot = Vector3.Zero; 4500 //update.JointPivot = Vector3.Zero;
4549 //update.JointType = 0; 4501 //update.JointType = 0;
4550 update.Material = data.material; 4502 update.Material = data.Material;
4551 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim 4503 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
4552 if (data.attachment) 4504 if (data.IsAttachment)
4553 { 4505 {
4554 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId); 4506 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID);
4555 update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); 4507 update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16));
4556 } 4508 }
4557 else 4509 else
4558 { 4510 {
4559 update.NameValue = Utils.EmptyBytes; 4511 update.NameValue = Utils.EmptyBytes;
4560 update.State = data.primShape.State; 4512 update.State = data.Shape.State;
4561 } 4513 }
4514
4562 update.ObjectData = objectData; 4515 update.ObjectData = objectData;
4563 update.ParentID = data.parentID; 4516 update.ParentID = data.ParentID;
4564 update.PathBegin = data.primShape.PathBegin; 4517 update.PathBegin = data.Shape.PathBegin;
4565 update.PathCurve = data.primShape.PathCurve; 4518 update.PathCurve = data.Shape.PathCurve;
4566 update.PathEnd = data.primShape.PathEnd; 4519 update.PathEnd = data.Shape.PathEnd;
4567 update.PathRadiusOffset = data.primShape.PathRadiusOffset; 4520 update.PathRadiusOffset = data.Shape.PathRadiusOffset;
4568 update.PathRevolutions = data.primShape.PathRevolutions; 4521 update.PathRevolutions = data.Shape.PathRevolutions;
4569 update.PathScaleX = data.primShape.PathScaleX; 4522 update.PathScaleX = data.Shape.PathScaleX;
4570 update.PathScaleY = data.primShape.PathScaleY; 4523 update.PathScaleY = data.Shape.PathScaleY;
4571 update.PathShearX = data.primShape.PathShearX; 4524 update.PathShearX = data.Shape.PathShearX;
4572 update.PathShearY = data.primShape.PathShearY; 4525 update.PathShearY = data.Shape.PathShearY;
4573 update.PathSkew = data.primShape.PathSkew; 4526 update.PathSkew = data.Shape.PathSkew;
4574 update.PathTaperX = data.primShape.PathTaperX; 4527 update.PathTaperX = data.Shape.PathTaperX;
4575 update.PathTaperY = data.primShape.PathTaperY; 4528 update.PathTaperY = data.Shape.PathTaperY;
4576 update.PathTwist = data.primShape.PathTwist; 4529 update.PathTwist = data.Shape.PathTwist;
4577 update.PathTwistBegin = data.primShape.PathTwistBegin; 4530 update.PathTwistBegin = data.Shape.PathTwistBegin;
4578 update.PCode = data.primShape.PCode; 4531 update.PCode = data.Shape.PCode;
4579 update.ProfileBegin = data.primShape.ProfileBegin; 4532 update.ProfileBegin = data.Shape.ProfileBegin;
4580 update.ProfileCurve = data.primShape.ProfileCurve; 4533 update.ProfileCurve = data.Shape.ProfileCurve;
4581 update.ProfileEnd = data.primShape.ProfileEnd; 4534 update.ProfileEnd = data.Shape.ProfileEnd;
4582 update.ProfileHollow = data.primShape.ProfileHollow; 4535 update.ProfileHollow = data.Shape.ProfileHollow;
4583 update.PSBlock = data.particleSystem ?? Utils.EmptyBytes; 4536 update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes;
4584 update.TextColor = data.color ?? Color4.Black.GetBytes(true); 4537 update.TextColor = data.GetTextColor().GetBytes(false);
4585 update.TextureAnim = data.textureanim ?? Utils.EmptyBytes; 4538 update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes;
4586 update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes; 4539 update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes;
4587 update.Scale = data.primShape.Scale; 4540 update.Scale = data.Shape.Scale;
4588 update.Text = Util.StringToBytes256(data.text); 4541 update.Text = Util.StringToBytes256(data.Text);
4589 update.UpdateFlags = (uint)data.flags; 4542
4590 4543 #region PrimFlags
4591 if (data.SoundId != UUID.Zero) 4544
4592 { 4545 PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID);
4593 update.Sound = data.SoundId; 4546
4594 update.OwnerID = data.ownerID; 4547 // Don't send the CreateSelected flag to everyone
4595 update.Gain = (float)data.SoundVolume; 4548 flags &= ~PrimFlags.CreateSelected;
4549
4550 if (recipientID == data.OwnerID)
4551 {
4552 if ((data.Flags & PrimFlags.CreateSelected) != 0)
4553 {
4554 // Only send this flag once, then unset it
4555 flags |= PrimFlags.CreateSelected;
4556 data.Flags &= ~PrimFlags.CreateSelected;
4557 }
4558 }
4559
4560 update.UpdateFlags = (uint)flags;
4561
4562 #endregion PrimFlags
4563
4564 if (data.Sound != UUID.Zero)
4565 {
4566 update.Sound = data.Sound;
4567 update.OwnerID = data.OwnerID;
4568 update.Gain = (float)data.SoundGain;
4596 update.Radius = (float)data.SoundRadius; 4569 update.Radius = (float)data.SoundRadius;
4597 update.Flags = data.SoundFlags; 4570 update.Flags = data.SoundFlags;
4598 } 4571 }
4599 4572
4600 switch ((PCode)data.primShape.PCode) 4573 switch ((PCode)data.Shape.PCode)
4601 { 4574 {
4602 case PCode.Grass: 4575 case PCode.Grass:
4603 case PCode.Tree: 4576 case PCode.Tree:
4604 case PCode.NewTree: 4577 case PCode.NewTree:
4605 update.Data = new byte[] { data.primShape.State }; 4578 update.Data = new byte[] { data.Shape.State };
4606 break; 4579 break;
4607 default: 4580 default:
4608 // TODO: Support ScratchPad
4609 //if (prim.ScratchPad != null)
4610 //{
4611 // update.Data = new byte[prim.ScratchPad.Length];
4612 // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
4613 //}
4614 //else
4615 //{
4616 // update.Data = Utils.EmptyBytes;
4617 //}
4618 update.Data = Utils.EmptyBytes; 4581 update.Data = Utils.EmptyBytes;
4619 break; 4582 break;
4620 } 4583 }
@@ -4622,6 +4585,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4622 return update; 4585 return update;
4623 } 4586 }
4624 4587
4588 protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags)
4589 {
4590 // TODO: Implement this
4591 return null;
4592 }
4593
4625 public void SendNameReply(UUID profileId, string firstname, string lastname) 4594 public void SendNameReply(UUID profileId, string firstname, string lastname)
4626 { 4595 {
4627 UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply); 4596 UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply);
@@ -11644,7 +11613,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11644 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 11613 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
11645 } 11614 }
11646 11615
11647 internal TValue Dequeue() 11616 internal bool TryDequeue(out TValue value)
11648 { 11617 {
11649 for (int i = 0; i < m_heaps.Length; ++i) 11618 for (int i = 0; i < m_heaps.Length; ++i)
11650 { 11619 {
@@ -11652,10 +11621,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11652 { 11621 {
11653 MinHeapItem item = m_heaps[i].RemoveMin(); 11622 MinHeapItem item = m_heaps[i].RemoveMin();
11654 m_lookupTable.Remove(item.LocalID); 11623 m_lookupTable.Remove(item.LocalID);
11655 return item.Value; 11624 value = item.Value;
11625 return true;
11656 } 11626 }
11657 } 11627 }
11658 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 11628
11629 value = default(TValue);
11630 return false;
11659 } 11631 }
11660 11632
11661 internal void Reprioritize(UpdatePriorityHandler handler) 11633 internal void Reprioritize(UpdatePriorityHandler handler)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 41e41e4..1b81105 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -99,15 +99,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
99 99
100 /// <summary>The measured resolution of Environment.TickCount</summary> 100 /// <summary>The measured resolution of Environment.TickCount</summary>
101 public readonly float TickCountResolution; 101 public readonly float TickCountResolution;
102 /// <summary>Number of terse prim updates to put on the queue each time the 102 /// <summary>Number of prim updates to put on the queue each time the
103 /// OnQueueEmpty event is triggered for updates</summary> 103 /// OnQueueEmpty event is triggered for updates</summary>
104 public readonly int PrimTerseUpdatesPerPacket; 104 public readonly int PrimUpdatesPerCallback;
105 /// <summary>Number of terse avatar updates to put on the queue each time the
106 /// OnQueueEmpty event is triggered for updates</summary>
107 public readonly int AvatarTerseUpdatesPerPacket;
108 /// <summary>Number of full prim updates to put on the queue each time the
109 /// OnQueueEmpty event is triggered for updates</summary>
110 public readonly int PrimFullUpdatesPerPacket;
111 /// <summary>Number of texture packets to put on the queue each time the 105 /// <summary>Number of texture packets to put on the queue each time the
112 /// OnQueueEmpty event is triggered for textures</summary> 106 /// OnQueueEmpty event is triggered for textures</summary>
113 public readonly int TextureSendLimit; 107 public readonly int TextureSendLimit;
@@ -191,9 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
191 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); 185 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
192 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); 186 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
193 187
194 PrimTerseUpdatesPerPacket = config.GetInt("PrimTerseUpdatesPerPacket", 25); 188 PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100);
195 AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10);
196 PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100);
197 TextureSendLimit = config.GetInt("TextureSendLimit", 20); 189 TextureSendLimit = config.GetInt("TextureSendLimit", 20);
198 190
199 m_defaultRTO = config.GetInt("DefaultRTO", 0); 191 m_defaultRTO = config.GetInt("DefaultRTO", 0);
@@ -201,9 +193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
201 } 193 }
202 else 194 else
203 { 195 {
204 PrimTerseUpdatesPerPacket = 25; 196 PrimUpdatesPerCallback = 100;
205 AvatarTerseUpdatesPerPacket = 10;
206 PrimFullUpdatesPerPacket = 100;
207 TextureSendLimit = 20; 197 TextureSendLimit = 20;
208 } 198 }
209 199
diff --git a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
index 1fbc733..1ad4db2 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandChannel.cs
@@ -154,6 +154,22 @@ namespace OpenSim.Region.CoreModules.World.Land
154 m_landManagementModule.UpdateLandObject(localID, data); 154 m_landManagementModule.UpdateLandObject(localID, data);
155 } 155 }
156 } 156 }
157
158 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
159 {
160 if (m_landManagementModule != null)
161 {
162 m_landManagementModule.Join(start_x, start_y, end_x, end_y, attempting_user_id);
163 }
164 }
165
166 public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
167 {
168 if (m_landManagementModule != null)
169 {
170 m_landManagementModule.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
171 }
172 }
157 173
158 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 174 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
159 { 175 {
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
index 139e6ff..4ccd0f0 100644
--- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs
@@ -948,6 +948,16 @@ namespace OpenSim.Region.CoreModules.World.Land
948 masterLandObject.SendLandUpdateToAvatarsOverMe(); 948 masterLandObject.SendLandUpdateToAvatarsOverMe();
949 } 949 }
950 950
951 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
952 {
953 join(start_x, start_y, end_x, end_y, attempting_user_id);
954 }
955
956 public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
957 {
958 subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
959 }
960
951 #endregion 961 #endregion
952 962
953 #region Parcel Updating 963 #region Parcel Updating
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 09611af..aac47d1 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -528,14 +528,6 @@ namespace OpenSim.Region.Examples.SimpleModule
528 { 528 {
529 } 529 }
530 530
531 public virtual void SendAvatarData(SendAvatarData data)
532 {
533 }
534
535 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
536 {
537 }
538
539 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 531 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
540 { 532 {
541 } 533 }
@@ -548,15 +540,15 @@ namespace OpenSim.Region.Examples.SimpleModule
548 { 540 {
549 } 541 }
550 542
551 public virtual void SendPrimitiveToClient(SendPrimitiveData data) 543 public void SendAvatarDataImmediate(ISceneEntity avatar)
552 { 544 {
553 } 545 }
554 546
555 public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) 547 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
556 { 548 {
557 } 549 }
558 550
559 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 551 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
560 { 552 {
561 } 553 }
562 554
diff --git a/OpenSim/Region/Framework/Interfaces/ILandChannel.cs b/OpenSim/Region/Framework/Interfaces/ILandChannel.cs
index f71e31d..20b8ab6 100644
--- a/OpenSim/Region/Framework/Interfaces/ILandChannel.cs
+++ b/OpenSim/Region/Framework/Interfaces/ILandChannel.cs
@@ -76,5 +76,8 @@ namespace OpenSim.Region.Framework.Interfaces
76 void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel); 76 void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel);
77 void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel); 77 void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel);
78 void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime); 78 void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime);
79
80 void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
81 void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id);
79 } 82 }
80} 83}
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 46eadee..71c8018 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -104,7 +104,7 @@ namespace OpenSim.Region.Framework.Scenes
104 104
105 #endregion Enumerations 105 #endregion Enumerations
106 106
107 public class SceneObjectPart : IScriptHost 107 public class SceneObjectPart : IScriptHost, ISceneEntity
108 { 108 {
109 /// <value> 109 /// <value>
110 /// Denote all sides of the prim 110 /// Denote all sides of the prim
@@ -712,6 +712,24 @@ namespace OpenSim.Region.Framework.Scenes
712 } 712 }
713 } 713 }
714 714
715 public Vector3 RelativePosition
716 {
717 get
718 {
719 if (IsRoot)
720 {
721 if (IsAttachment)
722 return AttachedPos;
723 else
724 return AbsolutePosition;
725 }
726 else
727 {
728 return OffsetPosition;
729 }
730 }
731 }
732
715 public Quaternion RotationOffset 733 public Quaternion RotationOffset
716 { 734 {
717 get 735 get
@@ -973,7 +991,6 @@ namespace OpenSim.Region.Framework.Scenes
973 get { return AggregateScriptEvents; } 991 get { return AggregateScriptEvents; }
974 } 992 }
975 993
976
977 public Quaternion SitTargetOrientation 994 public Quaternion SitTargetOrientation
978 { 995 {
979 get { return m_sitTargetOrientation; } 996 get { return m_sitTargetOrientation; }
@@ -2925,11 +2942,7 @@ namespace OpenSim.Region.Framework.Scenes
2925 //if (LocalId != ParentGroup.RootPart.LocalId) 2942 //if (LocalId != ParentGroup.RootPart.LocalId)
2926 //isattachment = ParentGroup.RootPart.IsAttachment; 2943 //isattachment = ParentGroup.RootPart.IsAttachment;
2927 2944
2928 byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; 2945 remoteClient.SendPrimUpdate(this, PrimUpdateFlags.FullUpdate);
2929 remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape,
2930 lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID,
2931 m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment,
2932 AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient)));
2933 } 2946 }
2934 2947
2935 /// <summary> 2948 /// <summary>
@@ -4640,11 +4653,7 @@ namespace OpenSim.Region.Framework.Scenes
4640 4653
4641 // Causes this thread to dig into the Client Thread Data. 4654 // Causes this thread to dig into the Client Thread Data.
4642 // Remember your locking here! 4655 // Remember your locking here!
4643 remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, 4656 remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
4644 m_parentGroup.GetTimeDilation(), LocalId, lPos,
4645 RotationOffset, Velocity, Acceleration,
4646 AngularVelocity, FromItemID,
4647 OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient)));
4648 } 4657 }
4649 4658
4650 public void AddScriptLPS(int count) 4659 public void AddScriptLPS(int count)
@@ -4694,7 +4703,8 @@ namespace OpenSim.Region.Framework.Scenes
4694 4703
4695 public Color4 GetTextColor() 4704 public Color4 GetTextColor()
4696 { 4705 {
4697 return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A)); 4706 Color color = Color;
4707 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4698 } 4708 }
4699 } 4709 }
4700} 4710}
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 30eafd7..ee0eb07 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -67,7 +67,7 @@ namespace OpenSim.Region.Framework.Scenes
67 67
68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence); 68 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence);
69 69
70 public class ScenePresence : EntityBase 70 public class ScenePresence : EntityBase, ISceneEntity
71 { 71 {
72// ~ScenePresence() 72// ~ScenePresence()
73// { 73// {
@@ -478,6 +478,12 @@ namespace OpenSim.Region.Framework.Scenes
478 } 478 }
479 } 479 }
480 480
481 public Vector3 OffsetPosition
482 {
483 get { return m_pos; }
484 set { m_pos = value; }
485 }
486
481 /// <summary> 487 /// <summary>
482 /// Current velocity of the avatar. 488 /// Current velocity of the avatar.
483 /// </summary> 489 /// </summary>
@@ -1036,8 +1042,9 @@ namespace OpenSim.Region.Framework.Scenes
1036 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); 1042 AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f));
1037 } 1043 }
1038 1044
1039 ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 1045 ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position);
1040 AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); 1046 //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
1047 // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient)));
1041 } 1048 }
1042 1049
1043 public void AddNeighbourRegion(ulong regionHandle, string cap) 1050 public void AddNeighbourRegion(ulong regionHandle, string cap)
@@ -2360,8 +2367,7 @@ namespace OpenSim.Region.Framework.Scenes
2360 2367
2361 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); 2368 //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity);
2362 2369
2363 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 2370 remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity);
2364 pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient)));
2365 2371
2366 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2372 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2367 m_scene.StatsReporter.AddAgentUpdates(1); 2373 m_scene.StatsReporter.AddAgentUpdates(1);
@@ -2457,9 +2463,7 @@ namespace OpenSim.Region.Framework.Scenes
2457 Vector3 pos = m_pos; 2463 Vector3 pos = m_pos;
2458 pos.Z += m_appearance.HipOffset; 2464 pos.Z += m_appearance.HipOffset;
2459 2465
2460 remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, 2466 remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this);
2461 LocalId, pos, m_appearance.Texture.GetBytes(),
2462 m_parentID, m_bodyRot));
2463 m_scene.StatsReporter.AddAgentUpdates(1); 2467 m_scene.StatsReporter.AddAgentUpdates(1);
2464 } 2468 }
2465 2469
@@ -2527,8 +2531,7 @@ namespace OpenSim.Region.Framework.Scenes
2527 Vector3 pos = m_pos; 2531 Vector3 pos = m_pos;
2528 pos.Z += m_appearance.HipOffset; 2532 pos.Z += m_appearance.HipOffset;
2529 2533
2530 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2534 m_controllingClient.SendAvatarDataImmediate(this);
2531 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
2532 2535
2533 SendInitialFullUpdateToAllClients(); 2536 SendInitialFullUpdateToAllClients();
2534 SendAppearanceToAllOtherAgents(); 2537 SendAppearanceToAllOtherAgents();
@@ -2638,9 +2641,7 @@ namespace OpenSim.Region.Framework.Scenes
2638 Vector3 pos = m_pos; 2641 Vector3 pos = m_pos;
2639 pos.Z += m_appearance.HipOffset; 2642 pos.Z += m_appearance.HipOffset;
2640 2643
2641 m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, 2644 m_controllingClient.SendAvatarDataImmediate(this);
2642 pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot));
2643
2644 } 2645 }
2645 2646
2646 public void SetWearable(int wearableId, AvatarWearable wearable) 2647 public void SetWearable(int wearableId, AvatarWearable wearable)
@@ -3906,7 +3907,7 @@ namespace OpenSim.Region.Framework.Scenes
3906 3907
3907 private void Reprioritize(object sender, ElapsedEventArgs e) 3908 private void Reprioritize(object sender, ElapsedEventArgs e)
3908 { 3909 {
3909 m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); 3910 m_controllingClient.ReprioritizeUpdates(UpdatePriority);
3910 3911
3911 lock (m_reprioritization_timer) 3912 lock (m_reprioritization_timer)
3912 { 3913 {
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 69e78b3..84faac0 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1045,16 +1045,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1045 1045
1046 } 1046 }
1047 1047
1048 public void SendAvatarData(SendAvatarData data)
1049 {
1050
1051 }
1052
1053 public void SendAvatarTerseUpdate(SendAvatarTerseData data)
1054 {
1055
1056 }
1057
1058 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 1048 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
1059 { 1049 {
1060 1050
@@ -1065,32 +1055,27 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1065 1055
1066 } 1056 }
1067 1057
1068 public void SetChildAgentThrottle(byte[] throttle) 1058 public void SendAvatarDataImmediate(ISceneEntity avatar)
1069 { 1059 {
1070
1071 }
1072 1060
1073 public void SendPrimitiveToClient(SendPrimitiveData data)
1074 {
1075
1076 } 1061 }
1077 1062
1078 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 1063 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
1079 { 1064 {
1080 1065
1081 } 1066 }
1082 1067
1083 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 1068 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
1084 { 1069 {
1085 1070
1086 } 1071 }
1087 1072
1088 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems) 1073 public void FlushPrimUpdates()
1089 { 1074 {
1090 1075
1091 } 1076 }
1092 1077
1093 public void FlushPrimUpdates() 1078 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, int version, bool fetchFolders, bool fetchItems)
1094 { 1079 {
1095 1080
1096 } 1081 }
@@ -1420,6 +1405,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1420 1405
1421 } 1406 }
1422 1407
1408 public virtual void SetChildAgentThrottle(byte[] throttle)
1409 {
1410
1411 }
1412
1423 public byte[] GetThrottlesPacked(float multiplier) 1413 public byte[] GetThrottlesPacked(float multiplier)
1424 { 1414 {
1425 return new byte[0]; 1415 return new byte[0];
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 6360c99..9066691 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -618,14 +618,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
618 { 618 {
619 } 619 }
620 620
621 public virtual void SendAvatarData(SendAvatarData data)
622 {
623 }
624
625 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
626 {
627 }
628
629 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 621 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
630 { 622 {
631 } 623 }
@@ -638,15 +630,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
638 { 630 {
639 } 631 }
640 632
641 public virtual void SendPrimitiveToClient(SendPrimitiveData data) 633 public void SendAvatarDataImmediate(ISceneEntity avatar)
642 { 634 {
643 } 635 }
644 636
645 public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) 637 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
646 { 638 {
647 } 639 }
648 640
649 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 641 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
650 { 642 {
651 } 643 }
652 644
diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
index 9da818a..33ff707 100644
--- a/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
+++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerLargeLandChannel.cs
@@ -140,6 +140,16 @@ public class RegionCombinerLargeLandChannel : ILandChannel
140 RootRegionLandChannel.UpdateLandObject(localID, data); 140 RootRegionLandChannel.UpdateLandObject(localID, data);
141 } 141 }
142 142
143 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
144 {
145 RootRegionLandChannel.Join(start_x, start_y, end_x, end_y, attempting_user_id);
146 }
147
148 public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id)
149 {
150 RootRegionLandChannel.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id);
151 }
152
143 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 153 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
144 { 154 {
145 RootRegionLandChannel.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient); 155 RootRegionLandChannel.ReturnObjectsInParcel(localID, returnType, agentIDs, taskIDs, remoteClient);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 7e68cc7..15469db 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -1129,7 +1129,89 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1129 return 0.0f; 1129 return 0.0f;
1130 } 1130 }
1131 1131
1132 // Routines for creating and managing parcels programmatically
1133 public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2)
1134 {
1135 CheckThreatLevel(ThreatLevel.High, "osParcelJoin");
1136 m_host.AddScriptLPS(1);
1137
1138 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
1139 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
1140 int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x);
1141 int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y);
1142
1143 World.LandChannel.Join(startx,starty,endx,endy,m_host.OwnerID);
1144 }
1145
1146 public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2)
1147 {
1148 CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide");
1149 m_host.AddScriptLPS(1);
1150
1151 int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x);
1152 int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y);
1153 int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x);
1154 int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y);
1132 1155
1156 World.LandChannel.Subdivide(startx,starty,endx,endy,m_host.OwnerID);
1157 }
1158
1159 public void osParcelSetDetails(LSL_Vector pos, LSL_List rules)
1160 {
1161 CheckThreatLevel(ThreatLevel.High, "osParcelSetDetails");
1162 m_host.AddScriptLPS(1);
1163
1164 // Get a reference to the land data and make sure the owner of the script
1165 // can modify it
1166
1167 ILandObject startLandObject = World.LandChannel.GetLandObject((int)pos.x, (int)pos.y);
1168 if (startLandObject == null)
1169 {
1170 OSSLShoutError("There is no land at that location");
1171 return;
1172 }
1173
1174 if (! World.Permissions.CanEditParcel(m_host.OwnerID, startLandObject))
1175 {
1176 OSSLShoutError("You do not have permission to modify the parcel");
1177 return;
1178 }
1179
1180 // Create a new land data object we can modify
1181 LandData newLand = startLandObject.LandData.Copy();
1182 UUID uuid;
1183
1184 // Process the rules, not sure what the impact would be of changing owner or group
1185 for (int idx = 0; idx < rules.Length; )
1186 {
1187 int code = rules.GetLSLIntegerItem(idx++);
1188 string arg = rules.GetLSLStringItem(idx++);
1189 switch (code)
1190 {
1191 case 0:
1192 newLand.Name = arg;
1193 break;
1194
1195 case 1:
1196 newLand.Description = arg;
1197 break;
1198
1199 case 2:
1200 CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails");
1201 if (UUID.TryParse(arg , out uuid))
1202 newLand.OwnerID = uuid;
1203 break;
1204
1205 case 3:
1206 CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails");
1207 if (UUID.TryParse(arg , out uuid))
1208 newLand.GroupID = uuid;
1209 break;
1210 }
1211 }
1212
1213 World.LandChannel.UpdateLandObject(newLand.LocalID,newLand);
1214 }
1133 1215
1134 public double osList2Double(LSL_Types.list src, int index) 1216 public double osList2Double(LSL_Types.list src, int index)
1135 { 1217 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 60b8050..7a8f469 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -123,6 +123,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
123 void osWindParamSet(string plugin, string param, float value); 123 void osWindParamSet(string plugin, string param, float value);
124 float osWindParamGet(string plugin, string param); 124 float osWindParamGet(string plugin, string param);
125 125
126 // Parcel commands
127 void osParcelJoin(vector pos1, vector pos2);
128 void osParcelSubdivide(vector pos1, vector pos2);
129 void osParcelSetDetails(vector pos, LSL_List rules);
126 130
127 string osGetScriptEngineName(); 131 string osGetScriptEngineName();
128 string osGetSimulatorVersion(); 132 string osGetSimulatorVersion();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 3870af3..fd9309a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -106,6 +106,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
106// return m_OSSL_Functions.osWindParamGet(plugin, param); 106// return m_OSSL_Functions.osWindParamGet(plugin, param);
107// } 107// }
108 108
109 public void osParcelJoin(vector pos1, vector pos2)
110 {
111 m_OSSL_Functions.osParcelJoin(pos1,pos2);
112 }
113
114 public void osParcelSubdivide(vector pos1, vector pos2)
115 {
116 m_OSSL_Functions.osParcelSubdivide(pos1, pos2);
117 }
118
119 public void osParcelSetDetails(vector pos, LSL_List rules)
120 {
121 m_OSSL_Functions.osParcelSetDetails(pos,rules);
122 }
123
109 public double osList2Double(LSL_Types.list src, int index) 124 public double osList2Double(LSL_Types.list src, int index)
110 { 125 {
111 return m_OSSL_Functions.osList2Double(src, index); 126 return m_OSSL_Functions.osList2Double(src, index);
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index b07a072..edb7642 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -621,14 +621,6 @@ namespace OpenSim.Tests.Common.Mock
621 { 621 {
622 } 622 }
623 623
624 public virtual void SendAvatarData(SendAvatarData data)
625 {
626 }
627
628 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
629 {
630 }
631
632 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 624 public virtual void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
633 { 625 {
634 } 626 }
@@ -641,15 +633,15 @@ namespace OpenSim.Tests.Common.Mock
641 { 633 {
642 } 634 }
643 635
644 public virtual void SendPrimitiveToClient(SendPrimitiveData data) 636 public void SendAvatarDataImmediate(ISceneEntity avatar)
645 { 637 {
646 } 638 }
647 639
648 public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) 640 public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags)
649 { 641 {
650 } 642 }
651 643
652 public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) 644 public void ReprioritizeUpdates(UpdatePriorityHandler handler)
653 { 645 {
654 } 646 }
655 647
diff --git a/OpenSim/Tests/Common/Mock/TestLandChannel.cs b/OpenSim/Tests/Common/Mock/TestLandChannel.cs
index be28c27..159764c 100644
--- a/OpenSim/Tests/Common/Mock/TestLandChannel.cs
+++ b/OpenSim/Tests/Common/Mock/TestLandChannel.cs
@@ -85,5 +85,9 @@ namespace OpenSim.Tests.Common.Mock
85 public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) {} 85 public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) {}
86 public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) {} 86 public void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) {}
87 public void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) {} 87 public void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime) {}
88
89 public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) {}
90 public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) {}
91
88 } 92 }
89} 93}