From bf5c81d77e492cd6df5517ecab32cd64168b01c2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 May 2010 15:59:48 -0700 Subject: * Initial commit of the slimupdates2 rewrite. This pass maintains the original behavior of avatar update sending and has a simplified set of IClientAPI methods for sending avatar/prim updates --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 627 ++++++++++----------- .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 18 +- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 14 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 36 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 29 +- .../Server/IRCClientView.cs | 34 +- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 14 +- 7 files changed, 360 insertions(+), 412 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 1f3582c..6154da4 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -50,43 +50,17 @@ using Nini.Config; namespace OpenSim.Region.ClientStack.LindenUDP { - #region Enums - - /// - /// Specifies the fields that have been changed when sending a prim or - /// avatar update - /// - [Flags] - public enum PrimUpdateFlags : uint + public class EntityUpdate { - None = 0, - AttachmentPoint = 1 << 0, - Material = 1 << 1, - ClickAction = 1 << 2, - Scale = 1 << 3, - ParentID = 1 << 4, - PrimFlags = 1 << 5, - PrimData = 1 << 6, - MediaURL = 1 << 7, - ScratchPad = 1 << 8, - Textures = 1 << 9, - TextureAnim = 1 << 10, - NameValue = 1 << 11, - Position = 1 << 12, - Rotation = 1 << 13, - Velocity = 1 << 14, - Acceleration = 1 << 15, - AngularVelocity = 1 << 16, - CollisionPlane = 1 << 17, - Text = 1 << 18, - Particles = 1 << 19, - ExtraData = 1 << 20, - Sound = 1 << 21, - Joint = 1 << 22, - FullUpdate = UInt32.MaxValue - } + public ISceneEntity Entity; + public PrimUpdateFlags Flags; - #endregion Enums + public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags) + { + Entity = entity; + Flags = flags; + } + } public delegate bool PacketMethod(IClientAPI simClient, Packet packet); @@ -350,9 +324,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private readonly IGroupsModule m_GroupsModule; private int m_cachedTextureSerial; - protected PriorityQueue m_avatarTerseUpdates; - private PriorityQueue m_primTerseUpdates; - private PriorityQueue m_primFullUpdates; + private PriorityQueue m_entityUpdates; /// /// 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 m_scene = scene; - m_avatarTerseUpdates = new PriorityQueue(); - m_primTerseUpdates = new PriorityQueue(); - m_primFullUpdates = new PriorityQueue(m_scene.Entities.Count); + m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); m_fullUpdateDataBlocksBuilder = new List(); m_killRecord = new HashSet(); @@ -1519,7 +1489,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP kill.Header.Reliable = true; kill.Header.Zerocoded = true; - lock (m_primFullUpdates.SyncRoot) + lock (m_entityUpdates.SyncRoot) { m_killRecord.Add(localID); OutPacket(kill, ThrottleOutPacketType.State); @@ -3419,71 +3389,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Send an ObjectUpdate packet with information about an avatar /// - public void SendAvatarData(SendAvatarData data) + public void SendAvatarDataImmediate(ISceneEntity avatar) { + ScenePresence presence = avatar as ScenePresence; + if (presence == null) + return; + ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); objupdate.Header.Zerocoded = true; - objupdate.RegionData.RegionHandle = data.RegionHandle; + objupdate.RegionData.RegionHandle = presence.RegionHandle; objupdate.RegionData.TimeDilation = ushort.MaxValue; objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; - objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); + objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); OutPacket(objupdate, ThrottleOutPacketType.Task); } - /// - /// Send a terse positional/rotation/velocity update about an avatar - /// to the client. This avatar can be that of the client itself. - /// - public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) - { - if (data.Priority == double.NaN) - { - m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); - return; - } - - Quaternion rotation = data.Rotation; - if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) - rotation = Quaternion.Identity; - - ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data); - - lock (m_avatarTerseUpdates.SyncRoot) - m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID); - - // If we received an update about our own avatar, process the avatar update priority queue immediately - if (data.AgentID == m_agentId) - ProcessAvatarTerseUpdates(); - } - - protected void ProcessAvatarTerseUpdates() - { - ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); - terse.Header.Reliable = false; - terse.Header.Zerocoded = true; - - //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock(); - terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; - terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); - - lock (m_avatarTerseUpdates.SyncRoot) - { - int count = Math.Min(m_avatarTerseUpdates.Count, m_udpServer.AvatarTerseUpdatesPerPacket); - if (count == 0) - return; - - terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; - for (int i = 0; i < count; i++) - terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); - } - - // HACK: Using the task category until the tiered reprioritization code is in - OutPacket(terse, ThrottleOutPacketType.Task); - } - public void SendCoarseLocationUpdate(List users, List CoarseLocations) { if (!IsActive) return; // We don't need to update inactive clients. @@ -3528,172 +3451,188 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Primitive Packet/Data Sending Methods - public void SendPrimitiveToClient(SendPrimitiveData data) + /// + /// Generate one of the object update packets based on PrimUpdateFlags + /// and broadcast the packet to clients + /// + public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) { -// string text = data.text; -// if (text.IndexOf("\n") >= 0) -// text = text.Remove(text.IndexOf("\n")); -// m_log.DebugFormat( -// "[CLIENT]: Placing request to send full info about prim {0} text {1} to client {2}", -// data.localID, text, Name); - - if (data.priority == double.NaN) - { - m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); - return; - } - - Quaternion rotation = data.rotation; - if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) - rotation = Quaternion.Identity; - - if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD - return; - if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9) - return; + double priority; - ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); + if (entity is SceneObjectPart) + priority = ((SceneObjectPart)entity).ParentGroup.GetUpdatePriority(this); + else if (entity is ScenePresence) + priority = ((ScenePresence)entity).GetUpdatePriority(this); + else + priority = 0.0d; - lock (m_primFullUpdates.SyncRoot) - m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); + lock (m_entityUpdates.SyncRoot) + m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); } - void ProcessPrimFullUpdates() + private void ProcessEntityUpdates(int maxUpdates) { - ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); - outPacket.Header.Zerocoded = true; + Lazy> objectUpdateBlocks = new Lazy>(); + Lazy> compressedUpdateBlocks = new Lazy>(); + Lazy> terseUpdateBlocks = new Lazy>(); - outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; - outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); + int updatesThisCall = 0; - lock (m_primFullUpdates.SyncRoot) + lock (m_entityUpdates.SyncRoot) { - int count = Math.Min(m_primFullUpdates.Count, m_udpServer.PrimFullUpdatesPerPacket); - if (count == 0) - return; - - m_fullUpdateDataBlocksBuilder.Clear(); - - for (int i = 0; i < count; i++) + EntityUpdate update; + while (m_entityUpdates.TryDequeue(out update)) { - ObjectUpdatePacket.ObjectDataBlock block = m_primFullUpdates.Dequeue(); + #region UpdateFlags to packet type conversion + + PrimUpdateFlags updateFlags = update.Flags; - if (!m_killRecord.Contains(block.ID)) + bool canUseCompressed = true; + bool canUseImproved = true; + + // Compressed object updates only make sense for LL primitives + if (!(update.Entity is SceneObjectPart)) + canUseCompressed = false; + + if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) { - m_fullUpdateDataBlocksBuilder.Add(block); - -// string text = Util.FieldToString(outPacket.ObjectData[i].Text); -// if (text.IndexOf("\n") >= 0) -// text = text.Remove(text.IndexOf("\n")); -// m_log.DebugFormat( -// "[CLIENT]: Sending full info about prim {0} text {1} to client {2}", -// outPacket.ObjectData[i].ID, text, Name); + canUseCompressed = false; + canUseImproved = false; + } + else + { + if (updateFlags.HasFlag(PrimUpdateFlags.Velocity) || + updateFlags.HasFlag(PrimUpdateFlags.Acceleration) || + updateFlags.HasFlag(PrimUpdateFlags.CollisionPlane) || + updateFlags.HasFlag(PrimUpdateFlags.Joint)) + { + canUseCompressed = false; + } + + if (updateFlags.HasFlag(PrimUpdateFlags.PrimFlags) || + updateFlags.HasFlag(PrimUpdateFlags.ParentID) || + updateFlags.HasFlag(PrimUpdateFlags.Scale) || + updateFlags.HasFlag(PrimUpdateFlags.PrimData) || + updateFlags.HasFlag(PrimUpdateFlags.Text) || + updateFlags.HasFlag(PrimUpdateFlags.NameValue) || + updateFlags.HasFlag(PrimUpdateFlags.ExtraData) || + updateFlags.HasFlag(PrimUpdateFlags.TextureAnim) || + updateFlags.HasFlag(PrimUpdateFlags.Sound) || + updateFlags.HasFlag(PrimUpdateFlags.Particles) || + updateFlags.HasFlag(PrimUpdateFlags.Material) || + updateFlags.HasFlag(PrimUpdateFlags.ClickAction) || + updateFlags.HasFlag(PrimUpdateFlags.MediaURL) || + updateFlags.HasFlag(PrimUpdateFlags.Joint)) + { + canUseImproved = false; + } + } + + #endregion UpdateFlags to packet type conversion + + #region Block Construction + + // TODO: Remove this once we can build compressed updates + canUseCompressed = false; + + if (!canUseImproved && !canUseCompressed) + { + if (update.Entity is ScenePresence) + objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity)); + else + objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId)); } -// else -// { -// m_log.WarnFormat( -// "[CLIENT]: Preventing full update for {0} after kill to {1}", block.ID, Name); -// } + else if (!canUseImproved) + { + compressedUpdateBlocks.Value.Add(CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags)); + } + else + { + terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures))); + } + + #endregion Block Construction + + ++updatesThisCall; + if (maxUpdates > 0 && updatesThisCall >= maxUpdates) + break; } + } - outPacket.ObjectData = m_fullUpdateDataBlocksBuilder.ToArray(); - - OutPacket(outPacket, ThrottleOutPacketType.State); - } - } + #region Packet Sending - public void SendPrimTerseUpdate(SendPrimitiveTerseData data) - { - if (data.Priority == double.NaN) + const float TIME_DILATION = 1.0f; + ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); + + if (objectUpdateBlocks.IsValueCreated) { - m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); - return; - } + List blocks = objectUpdateBlocks.Value; - Quaternion rotation = data.Rotation; - if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f) - rotation = Quaternion.Identity; + ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + packet.RegionData.TimeDilation = timeDilation; + packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; - if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD - return; + for (int i = 0; i < blocks.Count; i++) + packet.ObjectData[i] = blocks[i]; + + OutPacket(packet, ThrottleOutPacketType.Task, true); + } - ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); + if (compressedUpdateBlocks.IsValueCreated) + { + List blocks = compressedUpdateBlocks.Value; - lock (m_primTerseUpdates.SyncRoot) - m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID); - } + ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + packet.RegionData.TimeDilation = timeDilation; + packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; - void ProcessPrimTerseUpdates() - { - ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); - outPacket.Header.Reliable = false; - outPacket.Header.Zerocoded = true; + for (int i = 0; i < blocks.Count; i++) + packet.ObjectData[i] = blocks[i]; - outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; - outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); + OutPacket(packet, ThrottleOutPacketType.Task, true); + } - lock (m_primTerseUpdates.SyncRoot) + if (terseUpdateBlocks.IsValueCreated) { - int count = Math.Min(m_primTerseUpdates.Count, m_udpServer.PrimTerseUpdatesPerPacket); - if (count == 0) - return; + List blocks = terseUpdateBlocks.Value; + + ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); + packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; + packet.RegionData.TimeDilation = timeDilation; + packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; - outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; - for (int i = 0; i < count; i++) - outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); + for (int i = 0; i < blocks.Count; i++) + packet.ObjectData[i] = blocks[i]; + + OutPacket(packet, ThrottleOutPacketType.Task, true); } - OutPacket(outPacket, ThrottleOutPacketType.State); + #endregion Packet Sending } - public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) + public void ReprioritizeUpdates(UpdatePriorityHandler handler) { - PriorityQueue.UpdatePriorityHandler terse_update_priority_handler = - delegate(ref double priority, uint local_id) - { - priority = handler(new UpdatePriorityData(priority, local_id)); - return priority != double.NaN; - }; - PriorityQueue.UpdatePriorityHandler update_priority_handler = + //m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName); + + PriorityQueue.UpdatePriorityHandler update_priority_handler = delegate(ref double priority, uint local_id) { priority = handler(new UpdatePriorityData(priority, local_id)); return priority != double.NaN; }; - if ((type & StateUpdateTypes.AvatarTerse) != 0) - { - lock (m_avatarTerseUpdates.SyncRoot) - m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler); - } - - if ((type & StateUpdateTypes.PrimitiveFull) != 0) - { - lock (m_primFullUpdates.SyncRoot) - m_primFullUpdates.Reprioritize(update_priority_handler); - } - - if ((type & StateUpdateTypes.PrimitiveTerse) != 0) - { - lock (m_primTerseUpdates.SyncRoot) - m_primTerseUpdates.Reprioritize(terse_update_priority_handler); - } + lock (m_entityUpdates.SyncRoot) + m_entityUpdates.Reprioritize(update_priority_handler); } public void FlushPrimUpdates() { - while (m_primFullUpdates.Count > 0) - { - ProcessPrimFullUpdates(); - } - while (m_primTerseUpdates.Count > 0) - { - ProcessPrimTerseUpdates(); - } - while (m_avatarTerseUpdates.Count > 0) - { - ProcessAvatarTerseUpdates(); - } + m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName); + + while (m_entityUpdates.Count > 0) + ProcessEntityUpdates(-1); } #endregion Primitive Packet/Data Sending Methods @@ -3726,26 +3665,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) { - lock (m_avatarTerseUpdates.SyncRoot) - { - if (m_avatarTerseUpdates.Count > 0) - ProcessAvatarTerseUpdates(); - } - } - - if ((categories & ThrottleOutPacketTypeFlags.State) != 0) - { - lock (m_primFullUpdates.SyncRoot) - { - if (m_primFullUpdates.Count > 0) - ProcessPrimFullUpdates(); - } - - lock (m_primTerseUpdates.SyncRoot) - { - if (m_primTerseUpdates.Count > 0) - ProcessPrimTerseUpdates(); - } + if (m_entityUpdates.Count > 0) + ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback); } if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) @@ -4403,22 +4324,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Helper Methods - protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data) + protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture) { - return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity, - data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry); - } + #region ScenePresence/SOP Handling - protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data) - { - return CreateImprovedTerseBlock(false, data.LocalID, data.AttachPoint, Vector4.Zero, data.Position, data.Velocity, - data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry); - } + bool avatar = (entity is ScenePresence); + uint localID = entity.LocalId; + uint attachPoint; + Vector4 collisionPlane; + Vector3 position, velocity, acceleration, angularVelocity; + Quaternion rotation; + byte[] textureEntry; + + if (entity is ScenePresence) + { + ScenePresence presence = (ScenePresence)entity; + + attachPoint = 0; + collisionPlane = presence.CollisionPlane; + position = presence.OffsetPosition; + velocity = presence.Velocity; + acceleration = Vector3.Zero; + angularVelocity = Vector3.Zero; + rotation = presence.Rotation; + + if (sendTexture) + textureEntry = presence.Appearance.Texture.GetBytes(); + else + textureEntry = null; + } + else + { + SceneObjectPart part = (SceneObjectPart)entity; + + attachPoint = part.AttachmentPoint; + collisionPlane = Vector4.Zero; + position = part.RelativePosition; + velocity = part.Velocity; + acceleration = part.Acceleration; + angularVelocity = part.AngularVelocity; + rotation = part.RotationOffset; + textureEntry = part.Shape.TextureEntry; + } + + #endregion ScenePresence/SOP Handling - protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, int attachPoint, - Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation, - Vector3 angularVelocity, byte[] textureEntry) - { int pos = 0; byte[] data = new byte[(avatar ? 60 : 44)]; @@ -4490,12 +4440,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP return block; } - protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data) + protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(ScenePresence data) { byte[] objectData = new byte[76]; - Vector4.UnitW.ToBytes(objectData, 0); // TODO: Collision plane support - data.Position.ToBytes(objectData, 16); + data.CollisionPlane.ToBytes(objectData, 0); + data.OffsetPosition.ToBytes(objectData, 16); //data.Velocity.ToBytes(objectData, 28); //data.Acceleration.ToBytes(objectData, 40); data.Rotation.ToBytes(objectData, 52); @@ -4505,12 +4455,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP update.Data = Utils.EmptyBytes; update.ExtraParams = new byte[1]; - update.FullID = data.AvatarID; - update.ID = data.AvatarLocalID; + update.FullID = data.UUID; + update.ID = data.LocalId; update.Material = (byte)Material.Flesh; update.MediaURL = Utils.EmptyBytes; - update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " + - data.LastName + "\nTitle STRING RW SV " + data.GroupTitle); + update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.Firstname + "\nLastName STRING RW SV " + + data.Lastname + "\nTitle STRING RW SV " + data.Grouptitle); update.ObjectData = objectData; update.ParentID = data.ParentID; update.PathCurve = 16; @@ -4519,102 +4469,116 @@ namespace OpenSim.Region.ClientStack.LindenUDP update.PCode = (byte)PCode.Avatar; update.ProfileCurve = 1; update.PSBlock = Utils.EmptyBytes; - update.Scale = new Vector3(0.45f,0.6f,1.9f); + update.Scale = new Vector3(0.45f, 0.6f, 1.9f); update.Text = Utils.EmptyBytes; update.TextColor = new byte[4]; update.TextureAnim = Utils.EmptyBytes; - update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes; - 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 + update.TextureEntry = (data.Appearance.Texture != null) ? data.Appearance.Texture.GetBytes() : Utils.EmptyBytes; + update.UpdateFlags = (uint)( + PrimFlags.Physics | PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectAnyOwner | + PrimFlags.ObjectYouOwner | PrimFlags.ObjectMove | PrimFlags.InventoryEmpty | PrimFlags.ObjectTransfer | + PrimFlags.ObjectOwnerModify); return update; } - protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data) + protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) { byte[] objectData = new byte[60]; - data.pos.ToBytes(objectData, 0); - data.vel.ToBytes(objectData, 12); - data.acc.ToBytes(objectData, 24); - data.rotation.ToBytes(objectData, 36); - data.rvel.ToBytes(objectData, 48); + data.RelativePosition.ToBytes(objectData, 0); + data.Velocity.ToBytes(objectData, 12); + data.Acceleration.ToBytes(objectData, 24); + data.RotationOffset.ToBytes(objectData, 36); + data.AngularVelocity.ToBytes(objectData, 48); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); - update.ClickAction = (byte)data.clickAction; + update.ClickAction = (byte)data.ClickAction; update.CRC = 0; - update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes; - update.FullID = data.objectID; - update.ID = data.localID; + update.ExtraParams = data.Shape.ExtraParams ?? Utils.EmptyBytes; + update.FullID = data.UUID; + update.ID = data.LocalId; //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated //update.JointPivot = Vector3.Zero; //update.JointType = 0; - update.Material = data.material; + update.Material = data.Material; update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim - if (data.attachment) + if (data.IsAttachment) { - update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId); - update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); + update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.FromItemID); + update.State = (byte)((data.AttachmentPoint % 16) * 16 + (data.AttachmentPoint / 16)); } else { update.NameValue = Utils.EmptyBytes; - update.State = data.primShape.State; + update.State = data.Shape.State; } + update.ObjectData = objectData; - update.ParentID = data.parentID; - update.PathBegin = data.primShape.PathBegin; - update.PathCurve = data.primShape.PathCurve; - update.PathEnd = data.primShape.PathEnd; - update.PathRadiusOffset = data.primShape.PathRadiusOffset; - update.PathRevolutions = data.primShape.PathRevolutions; - update.PathScaleX = data.primShape.PathScaleX; - update.PathScaleY = data.primShape.PathScaleY; - update.PathShearX = data.primShape.PathShearX; - update.PathShearY = data.primShape.PathShearY; - update.PathSkew = data.primShape.PathSkew; - update.PathTaperX = data.primShape.PathTaperX; - update.PathTaperY = data.primShape.PathTaperY; - update.PathTwist = data.primShape.PathTwist; - update.PathTwistBegin = data.primShape.PathTwistBegin; - update.PCode = data.primShape.PCode; - update.ProfileBegin = data.primShape.ProfileBegin; - update.ProfileCurve = data.primShape.ProfileCurve; - update.ProfileEnd = data.primShape.ProfileEnd; - update.ProfileHollow = data.primShape.ProfileHollow; - update.PSBlock = data.particleSystem ?? Utils.EmptyBytes; - update.TextColor = data.color ?? Color4.Black.GetBytes(true); - update.TextureAnim = data.textureanim ?? Utils.EmptyBytes; - update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes; - update.Scale = data.primShape.Scale; - update.Text = Util.StringToBytes256(data.text); - update.UpdateFlags = (uint)data.flags; - - if (data.SoundId != UUID.Zero) - { - update.Sound = data.SoundId; - update.OwnerID = data.ownerID; - update.Gain = (float)data.SoundVolume; + update.ParentID = data.ParentID; + update.PathBegin = data.Shape.PathBegin; + update.PathCurve = data.Shape.PathCurve; + update.PathEnd = data.Shape.PathEnd; + update.PathRadiusOffset = data.Shape.PathRadiusOffset; + update.PathRevolutions = data.Shape.PathRevolutions; + update.PathScaleX = data.Shape.PathScaleX; + update.PathScaleY = data.Shape.PathScaleY; + update.PathShearX = data.Shape.PathShearX; + update.PathShearY = data.Shape.PathShearY; + update.PathSkew = data.Shape.PathSkew; + update.PathTaperX = data.Shape.PathTaperX; + update.PathTaperY = data.Shape.PathTaperY; + update.PathTwist = data.Shape.PathTwist; + update.PathTwistBegin = data.Shape.PathTwistBegin; + update.PCode = data.Shape.PCode; + update.ProfileBegin = data.Shape.ProfileBegin; + update.ProfileCurve = data.Shape.ProfileCurve; + update.ProfileEnd = data.Shape.ProfileEnd; + update.ProfileHollow = data.Shape.ProfileHollow; + update.PSBlock = data.ParticleSystem ?? Utils.EmptyBytes; + update.TextColor = data.GetTextColor().GetBytes(false); + update.TextureAnim = data.TextureAnimation ?? Utils.EmptyBytes; + update.TextureEntry = data.Shape.TextureEntry ?? Utils.EmptyBytes; + update.Scale = data.Shape.Scale; + update.Text = Util.StringToBytes256(data.Text); + + #region PrimFlags + + PrimFlags flags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(recipientID, data.UUID); + + // Don't send the CreateSelected flag to everyone + flags &= ~PrimFlags.CreateSelected; + + if (recipientID == data.OwnerID) + { + if ((data.Flags & PrimFlags.CreateSelected) != 0) + { + // Only send this flag once, then unset it + flags |= PrimFlags.CreateSelected; + data.Flags &= ~PrimFlags.CreateSelected; + } + } + + update.UpdateFlags = (uint)flags; + + #endregion PrimFlags + + if (data.Sound != UUID.Zero) + { + update.Sound = data.Sound; + update.OwnerID = data.OwnerID; + update.Gain = (float)data.SoundGain; update.Radius = (float)data.SoundRadius; update.Flags = data.SoundFlags; } - switch ((PCode)data.primShape.PCode) + switch ((PCode)data.Shape.PCode) { case PCode.Grass: case PCode.Tree: case PCode.NewTree: - update.Data = new byte[] { data.primShape.State }; + update.Data = new byte[] { data.Shape.State }; break; default: - // TODO: Support ScratchPad - //if (prim.ScratchPad != null) - //{ - // update.Data = new byte[prim.ScratchPad.Length]; - // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); - //} - //else - //{ - // update.Data = Utils.EmptyBytes; - //} update.Data = Utils.EmptyBytes; break; } @@ -4622,6 +4586,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP return update; } + protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags) + { + // TODO: Implement this + return null; + } + public void SendNameReply(UUID profileId, string firstname, string lastname) { UUIDNameReplyPacket packet = (UUIDNameReplyPacket)PacketPool.Instance.GetPacket(PacketType.UUIDNameReply); @@ -11644,7 +11614,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); } - internal TValue Dequeue() + internal bool TryDequeue(out TValue value) { for (int i = 0; i < m_heaps.Length; ++i) { @@ -11652,10 +11622,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP { MinHeapItem item = m_heaps[i].RemoveMin(); m_lookupTable.Remove(item.LocalID); - return item.Value; + value = item.Value; + return true; } } - throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); + + value = default(TValue); + return false; } 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 /// The measured resolution of Environment.TickCount public readonly float TickCountResolution; - /// Number of terse prim updates to put on the queue each time the + /// Number of prim updates to put on the queue each time the /// OnQueueEmpty event is triggered for updates - public readonly int PrimTerseUpdatesPerPacket; - /// Number of terse avatar updates to put on the queue each time the - /// OnQueueEmpty event is triggered for updates - public readonly int AvatarTerseUpdatesPerPacket; - /// Number of full prim updates to put on the queue each time the - /// OnQueueEmpty event is triggered for updates - public readonly int PrimFullUpdatesPerPacket; + public readonly int PrimUpdatesPerCallback; /// Number of texture packets to put on the queue each time the /// OnQueueEmpty event is triggered for textures public readonly int TextureSendLimit; @@ -191,9 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); - PrimTerseUpdatesPerPacket = config.GetInt("PrimTerseUpdatesPerPacket", 25); - AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10); - PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100); + PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100); TextureSendLimit = config.GetInt("TextureSendLimit", 20); m_defaultRTO = config.GetInt("DefaultRTO", 0); @@ -201,9 +193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } else { - PrimTerseUpdatesPerPacket = 25; - AvatarTerseUpdatesPerPacket = 10; - PrimFullUpdatesPerPacket = 100; + PrimUpdatesPerCallback = 100; TextureSendLimit = 20; } 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 { } - public virtual void SendAvatarData(SendAvatarData data) - { - } - - public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) - { - } - public virtual void SendCoarseLocationUpdate(List users, List CoarseLocations) { } @@ -548,15 +540,15 @@ namespace OpenSim.Region.Examples.SimpleModule { } - public virtual void SendPrimitiveToClient(SendPrimitiveData data) + public void SendAvatarDataImmediate(ISceneEntity avatar) { } - public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) + public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) { } - public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) + public void ReprioritizeUpdates(UpdatePriorityHandler handler) { } 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 #endregion Enumerations - public class SceneObjectPart : IScriptHost + public class SceneObjectPart : IScriptHost, ISceneEntity { /// /// Denote all sides of the prim @@ -712,6 +712,24 @@ namespace OpenSim.Region.Framework.Scenes } } + public Vector3 RelativePosition + { + get + { + if (IsRoot) + { + if (IsAttachment) + return AttachedPos; + else + return AbsolutePosition; + } + else + { + return OffsetPosition; + } + } + } + public Quaternion RotationOffset { get @@ -973,7 +991,6 @@ namespace OpenSim.Region.Framework.Scenes get { return AggregateScriptEvents; } } - public Quaternion SitTargetOrientation { get { return m_sitTargetOrientation; } @@ -2925,11 +2942,7 @@ namespace OpenSim.Region.Framework.Scenes //if (LocalId != ParentGroup.RootPart.LocalId) //isattachment = ParentGroup.RootPart.IsAttachment; - byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; - remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, m_parentGroup.GetTimeDilation(), LocalId, m_shape, - lPos, Velocity, Acceleration, RotationOffset, AngularVelocity, clientFlags, m_uuid, _ownerID, - m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, - AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); + remoteClient.SendPrimUpdate(this, PrimUpdateFlags.FullUpdate); } /// @@ -4640,11 +4653,7 @@ namespace OpenSim.Region.Framework.Scenes // Causes this thread to dig into the Client Thread Data. // Remember your locking here! - remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, - m_parentGroup.GetTimeDilation(), LocalId, lPos, - RotationOffset, Velocity, Acceleration, - AngularVelocity, FromItemID, - OwnerID, (int)AttachmentPoint, null, ParentGroup.GetUpdatePriority(remoteClient))); + remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); } public void AddScriptLPS(int count) @@ -4694,7 +4703,8 @@ namespace OpenSim.Region.Framework.Scenes public Color4 GetTextColor() { - return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A)); + Color color = Color; + return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); } } } 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 public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence); - public class ScenePresence : EntityBase + public class ScenePresence : EntityBase, ISceneEntity { // ~ScenePresence() // { @@ -478,6 +478,12 @@ namespace OpenSim.Region.Framework.Scenes } } + public Vector3 OffsetPosition + { + get { return m_pos; } + set { m_pos = value; } + } + /// /// Current velocity of the avatar. /// @@ -1036,8 +1042,9 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); } - ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, - AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); + ControllingClient.SendPrimUpdate(this, PrimUpdateFlags.Position); + //ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, + // AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); } public void AddNeighbourRegion(ulong regionHandle, string cap) @@ -2360,8 +2367,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); - remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, - pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); + remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); m_scene.StatsReporter.AddAgentUpdates(1); @@ -2457,9 +2463,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 pos = m_pos; pos.Z += m_appearance.HipOffset; - remoteAvatar.m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, - LocalId, pos, m_appearance.Texture.GetBytes(), - m_parentID, m_bodyRot)); + remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); m_scene.StatsReporter.AddAgentUpdates(1); } @@ -2527,8 +2531,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 pos = m_pos; pos.Z += m_appearance.HipOffset; - m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, - pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); + m_controllingClient.SendAvatarDataImmediate(this); SendInitialFullUpdateToAllClients(); SendAppearanceToAllOtherAgents(); @@ -2638,9 +2641,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 pos = m_pos; pos.Z += m_appearance.HipOffset; - m_controllingClient.SendAvatarData(new SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, - pos, m_appearance.Texture.GetBytes(), m_parentID, m_bodyRot)); - + m_controllingClient.SendAvatarDataImmediate(this); } public void SetWearable(int wearableId, AvatarWearable wearable) @@ -3906,7 +3907,7 @@ namespace OpenSim.Region.Framework.Scenes private void Reprioritize(object sender, ElapsedEventArgs e) { - m_controllingClient.ReprioritizeUpdates(StateUpdateTypes.All, UpdatePriority); + m_controllingClient.ReprioritizeUpdates(UpdatePriority); lock (m_reprioritization_timer) { 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 } - public void SendAvatarData(SendAvatarData data) - { - - } - - public void SendAvatarTerseUpdate(SendAvatarTerseData data) - { - - } - public void SendCoarseLocationUpdate(List users, List CoarseLocations) { @@ -1065,32 +1055,27 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void SetChildAgentThrottle(byte[] throttle) + public void SendAvatarDataImmediate(ISceneEntity avatar) { - - } - public void SendPrimitiveToClient(SendPrimitiveData data) - { - } - public void SendPrimTerseUpdate(SendPrimitiveTerseData data) + public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) { - + } - public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) + public void ReprioritizeUpdates(UpdatePriorityHandler handler) { } - public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, int version, bool fetchFolders, bool fetchItems) + public void FlushPrimUpdates() { - + } - public void FlushPrimUpdates() + public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List items, List folders, int version, bool fetchFolders, bool fetchItems) { } @@ -1420,6 +1405,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } + public virtual void SetChildAgentThrottle(byte[] throttle) + { + + } + public byte[] GetThrottlesPacked(float multiplier) { 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 { } - public virtual void SendAvatarData(SendAvatarData data) - { - } - - public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) - { - } - public virtual void SendCoarseLocationUpdate(List users, List CoarseLocations) { } @@ -638,15 +630,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public virtual void SendPrimitiveToClient(SendPrimitiveData data) + public void SendAvatarDataImmediate(ISceneEntity avatar) { } - public virtual void SendPrimTerseUpdate(SendPrimitiveTerseData data) + public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) { } - public virtual void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) + public void ReprioritizeUpdates(UpdatePriorityHandler handler) { } -- cgit v1.1 From 5d8638ed882681bdfac6c79015089bcaaedfc3ab Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 May 2010 16:05:48 -0700 Subject: Minor tweak in ProcessEntityUpdates (mostly just confirming the git push is working) --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 6154da4..11dca8d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3476,13 +3476,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP Lazy> compressedUpdateBlocks = new Lazy>(); Lazy> terseUpdateBlocks = new Lazy>(); + if (maxUpdates <= 0) maxUpdates = Int32.MaxValue; int updatesThisCall = 0; lock (m_entityUpdates.SyncRoot) { EntityUpdate update; - while (m_entityUpdates.TryDequeue(out update)) + while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) { + ++updatesThisCall; + #region UpdateFlags to packet type conversion PrimUpdateFlags updateFlags = update.Flags; @@ -3552,10 +3555,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion Block Construction - - ++updatesThisCall; - if (maxUpdates > 0 && updatesThisCall >= maxUpdates) - break; } } -- cgit v1.1 From 4c740e1717f8071d48e34c584728fddcf05afdb2 Mon Sep 17 00:00:00 2001 From: OpenSim Master Date: Thu, 29 Apr 2010 11:57:30 -0700 Subject: Implements three new OSSL functions for parcel management: osParcelJoin joins parcels in an area, osParcelSubdivide splits parcels in an area, osParcelSetDetails sets parcel name, description, owner and group owner. Join and Subdivide methods in LandChannel are exposed. --- .../Region/CoreModules/World/Land/LandChannel.cs | 16 +++++ .../CoreModules/World/Land/LandManagementModule.cs | 10 +++ .../Region/Framework/Interfaces/ILandChannel.cs | 3 + .../RegionCombinerLargeLandChannel.cs | 10 +++ .../Shared/Api/Implementation/OSSL_Api.cs | 82 ++++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 4 ++ .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 15 ++++ 7 files changed, 140 insertions(+) (limited to 'OpenSim/Region') 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 m_landManagementModule.UpdateLandObject(localID, data); } } + + public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) + { + if (m_landManagementModule != null) + { + m_landManagementModule.Join(start_x, start_y, end_x, end_y, attempting_user_id); + } + } + + public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) + { + if (m_landManagementModule != null) + { + m_landManagementModule.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id); + } + } public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) { 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 masterLandObject.SendLandUpdateToAvatarsOverMe(); } + public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) + { + join(start_x, start_y, end_x, end_y, attempting_user_id); + } + + public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) + { + subdivide(start_x, start_y, end_x, end_y, attempting_user_id); + } + #endregion #region Parcel Updating 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 void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel); void setSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel); void SetParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime); + + void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); + void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id); } } 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 RootRegionLandChannel.UpdateLandObject(localID, data); } + public void Join(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) + { + RootRegionLandChannel.Join(start_x, start_y, end_x, end_y, attempting_user_id); + } + + public void Subdivide(int start_x, int start_y, int end_x, int end_y, UUID attempting_user_id) + { + RootRegionLandChannel.Subdivide(start_x, start_y, end_x, end_y, attempting_user_id); + } + public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) { 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 return 0.0f; } + // Routines for creating and managing parcels programmatically + public void osParcelJoin(LSL_Vector pos1, LSL_Vector pos2) + { + CheckThreatLevel(ThreatLevel.High, "osParcelJoin"); + m_host.AddScriptLPS(1); + + int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); + int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); + int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x); + int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y); + + World.LandChannel.Join(startx,starty,endx,endy,m_host.OwnerID); + } + + public void osParcelSubdivide(LSL_Vector pos1, LSL_Vector pos2) + { + CheckThreatLevel(ThreatLevel.High, "osParcelSubdivide"); + m_host.AddScriptLPS(1); + + int startx = (int)(pos1.x < pos2.x ? pos1.x : pos2.x); + int starty = (int)(pos1.y < pos2.y ? pos1.y : pos2.y); + int endx = (int)(pos1.x > pos2.x ? pos1.x : pos2.x); + int endy = (int)(pos1.y > pos2.y ? pos1.y : pos2.y); + World.LandChannel.Subdivide(startx,starty,endx,endy,m_host.OwnerID); + } + + public void osParcelSetDetails(LSL_Vector pos, LSL_List rules) + { + CheckThreatLevel(ThreatLevel.High, "osParcelSetDetails"); + m_host.AddScriptLPS(1); + + // Get a reference to the land data and make sure the owner of the script + // can modify it + + ILandObject startLandObject = World.LandChannel.GetLandObject((int)pos.x, (int)pos.y); + if (startLandObject == null) + { + OSSLShoutError("There is no land at that location"); + return; + } + + if (! World.Permissions.CanEditParcel(m_host.OwnerID, startLandObject)) + { + OSSLShoutError("You do not have permission to modify the parcel"); + return; + } + + // Create a new land data object we can modify + LandData newLand = startLandObject.LandData.Copy(); + UUID uuid; + + // Process the rules, not sure what the impact would be of changing owner or group + for (int idx = 0; idx < rules.Length; ) + { + int code = rules.GetLSLIntegerItem(idx++); + string arg = rules.GetLSLStringItem(idx++); + switch (code) + { + case 0: + newLand.Name = arg; + break; + + case 1: + newLand.Description = arg; + break; + + case 2: + CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails"); + if (UUID.TryParse(arg , out uuid)) + newLand.OwnerID = uuid; + break; + + case 3: + CheckThreatLevel(ThreatLevel.VeryHigh, "osParcelSetDetails"); + if (UUID.TryParse(arg , out uuid)) + newLand.GroupID = uuid; + break; + } + } + + World.LandChannel.UpdateLandObject(newLand.LocalID,newLand); + } public double osList2Double(LSL_Types.list src, int index) { 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 void osWindParamSet(string plugin, string param, float value); float osWindParamGet(string plugin, string param); + // Parcel commands + void osParcelJoin(vector pos1, vector pos2); + void osParcelSubdivide(vector pos1, vector pos2); + void osParcelSetDetails(vector pos, LSL_List rules); string osGetScriptEngineName(); 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 // return m_OSSL_Functions.osWindParamGet(plugin, param); // } + public void osParcelJoin(vector pos1, vector pos2) + { + m_OSSL_Functions.osParcelJoin(pos1,pos2); + } + + public void osParcelSubdivide(vector pos1, vector pos2) + { + m_OSSL_Functions.osParcelSubdivide(pos1, pos2); + } + + public void osParcelSetDetails(vector pos, LSL_List rules) + { + m_OSSL_Functions.osParcelSetDetails(pos,rules); + } + public double osList2Double(LSL_Types.list src, int index) { return m_OSSL_Functions.osList2Double(src, index); -- cgit v1.1 From 36bcab5f075089f18a5c80f3f988c1e6605c16e5 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Tue, 4 May 2010 16:49:46 -0700 Subject: Refactor scene presence list for lockless iteration. Lock contention will now only be for simultaneous add/removes of scene presences from the scene. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 114 ++++++++++++-------------- 1 file changed, 53 insertions(+), 61 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index ce11267..ef13c98 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -68,8 +68,9 @@ namespace OpenSim.Region.Framework.Scenes #region Fields - protected Dictionary m_scenePresences = new Dictionary(); - protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; + protected object m_presenceLock = new object(); + protected Dictionary m_scenePresenceMap = new Dictionary(); + protected List m_scenePresenceArray = new List(); // SceneObjects is not currently populated or used. //public Dictionary SceneObjects; @@ -132,10 +133,12 @@ namespace OpenSim.Region.Framework.Scenes protected internal void Close() { - lock (m_scenePresences) + lock (m_presenceLock) { - m_scenePresences.Clear(); - m_scenePresenceArray = new ScenePresence[0]; + Dictionary newmap = new Dictionary(); + List newlist = new List(); + m_scenePresenceMap = newmap; + m_scenePresenceArray = newlist; } lock (m_dictionary_lock) @@ -518,34 +521,29 @@ namespace OpenSim.Region.Framework.Scenes Entities[presence.UUID] = presence; - lock (m_scenePresences) + lock (m_presenceLock) { - if (!m_scenePresences.ContainsKey(presence.UUID)) + Dictionary newmap = new Dictionary(m_scenePresenceMap); + List newlist = new List(m_scenePresenceArray); + + if (!newmap.ContainsKey(presence.UUID)) { - m_scenePresences.Add(presence.UUID, presence); - - // Create a new array of ScenePresence references - int oldLength = m_scenePresenceArray.Length; - ScenePresence[] newArray = new ScenePresence[oldLength + 1]; - Array.Copy(m_scenePresenceArray, newArray, oldLength); - newArray[oldLength] = presence; - m_scenePresenceArray = newArray; + newmap.Add(presence.UUID, presence); + newlist.Add(presence); } else { - m_scenePresences[presence.UUID] = presence; - - // Do a linear search through the array of ScenePresence references - // and update the modified entry - for (int i = 0; i < m_scenePresenceArray.Length; i++) - { - if (m_scenePresenceArray[i].UUID == presence.UUID) - { - m_scenePresenceArray[i] = presence; - break; - } - } + // Remember the old presene reference from the dictionary + ScenePresence oldref = newmap[presence.UUID]; + // Replace the presence reference in the dictionary with the new value + newmap[presence.UUID] = presence; + // Find the index in the list where the old ref was stored and update the reference + newlist[newlist.IndexOf(oldref)] = presence; } + + // Swap out the dictionary and list with new references + m_scenePresenceMap = newmap; + m_scenePresenceArray = newlist; } } @@ -561,25 +559,21 @@ namespace OpenSim.Region.Framework.Scenes agentID); } - lock (m_scenePresences) + lock (m_presenceLock) { - if (m_scenePresences.Remove(agentID)) + Dictionary newmap = new Dictionary(m_scenePresenceMap); + List newlist = new List(m_scenePresenceArray); + + // Remember the old presene reference from the dictionary + ScenePresence oldref = newmap[agentID]; + // Remove the presence reference from the dictionary + if (newmap.Remove(agentID)) { - // Copy all of the elements from the previous array - // into the new array except the removed element - int oldLength = m_scenePresenceArray.Length; - ScenePresence[] newArray = new ScenePresence[oldLength - 1]; - int j = 0; - for (int i = 0; i < m_scenePresenceArray.Length; i++) - { - ScenePresence presence = m_scenePresenceArray[i]; - if (presence.UUID != agentID) - { - newArray[j] = presence; - ++j; - } - } - m_scenePresenceArray = newArray; + // Find the index in the list where the old ref was stored and remove the reference + newlist.RemoveAt(newlist.IndexOf(oldref)); + // Swap out the dictionary and list with new references + m_scenePresenceMap = newmap; + m_scenePresenceArray = newlist; } else { @@ -698,7 +692,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Request a copy of m_scenePresences in this World + /// Get a reference to the scene presence list. Changes to the list will be done in a copy /// There is no guarantee that presences will remain in the scene after the list is returned. /// This list should remain private to SceneGraph. Callers wishing to iterate should instead /// pass a delegate to ForEachScenePresence. @@ -706,8 +700,7 @@ namespace OpenSim.Region.Framework.Scenes /// private List GetScenePresences() { - lock (m_scenePresences) - return new List(m_scenePresenceArray); + return m_scenePresenceArray; } /// @@ -717,12 +710,10 @@ namespace OpenSim.Region.Framework.Scenes /// null if the presence was not found protected internal ScenePresence GetScenePresence(UUID agentID) { - ScenePresence sp; - lock (m_scenePresences) - { - m_scenePresences.TryGetValue(agentID, out sp); - } - return sp; + Dictionary presences = m_scenePresenceMap; + ScenePresence presence; + presences.TryGetValue(agentID, out presence); + return presence; } /// @@ -733,7 +724,8 @@ namespace OpenSim.Region.Framework.Scenes /// null if the presence was not found protected internal ScenePresence GetScenePresence(string firstName, string lastName) { - foreach (ScenePresence presence in GetScenePresences()) + List presences = GetScenePresences(); + foreach (ScenePresence presence in presences) { if (presence.Firstname == firstName && presence.Lastname == lastName) return presence; @@ -748,7 +740,8 @@ namespace OpenSim.Region.Framework.Scenes /// null if the presence was not found protected internal ScenePresence GetScenePresence(uint localID) { - foreach (ScenePresence presence in GetScenePresences()) + List presences = GetScenePresences(); + foreach (ScenePresence presence in presences) if (presence.LocalId == localID) return presence; return null; @@ -756,10 +749,8 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) { - lock (m_scenePresences) - { - m_scenePresences.TryGetValue(agentID, out avatar); - } + Dictionary presences = m_scenePresenceMap; + presences.TryGetValue(agentID, out avatar); return (avatar != null); } @@ -1036,8 +1027,9 @@ namespace OpenSim.Region.Framework.Scenes }); Parallel.ForEach(GetScenePresences(), protectedAction); */ - // For now, perform actiona serially - foreach (ScenePresence sp in GetScenePresences()) + // For now, perform actions serially + List presences = GetScenePresences(); + foreach (ScenePresence sp in presences) { try { -- cgit v1.1 From 59dec2f989474158c94a2383b150c25d132777aa Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 May 2010 11:51:57 -0700 Subject: * Added sessionID to IGridUserService.SetLastPosition(), as some connectors will want to track position against sessionID instead of userID * Updated SimianPresenceServiceConnector to use the new LoggedOut/SetHome/etc methods and only update session position on parcel crossing --- .../CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs | 4 ++-- .../ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs | 4 ++-- .../ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs index 6c01927..7d2dc5a 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/ActivityDetector.cs @@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser { m_log.DebugFormat("[ACTIVITY DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName); - m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); + m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); } public void OnNewClient(IClientAPI client) @@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser { // TODO: grab the parcel ID from ILandModule // and send that along - m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); + m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs index d914a57..76e030f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/LocalGridUserServiceConnector.cs @@ -162,9 +162,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser return m_GridUserService.SetHome(userID, homeID, homePosition, homeLookAt); } - public bool SetLastPosition(string userID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) + public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) { - return m_GridUserService.SetLastPosition(userID, regionID, lastPosition, lastLookAt); + return m_GridUserService.SetLastPosition(userID, sessionID, regionID, lastPosition, lastLookAt); } public GridUserInfo GetGridUserInfo(string userID) diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs index e3e2e61..fb11e9a 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/GridUser/RemoteGridUserServiceConnector.cs @@ -137,9 +137,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser return m_RemoteConnector.SetHome(userID, regionID, position, lookAt); } - public bool SetLastPosition(string userID, UUID regionID, Vector3 position, Vector3 lookAt) + public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt) { - return m_RemoteConnector.SetLastPosition(userID, regionID, position, lookAt); + return m_RemoteConnector.SetLastPosition(userID, sessionID, regionID, position, lookAt); } public GridUserInfo GetGridUserInfo(string userID) -- cgit v1.1 From 56f3cb6da0ff48a9af0e11c5b1769788cc0a1a22 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 20 May 2010 12:04:12 -0700 Subject: * Don't send texture data for prims in ImprovedTerseObjectUpdate packets unless we were asked to --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 11dca8d..07c3a6a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4363,7 +4363,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP acceleration = part.Acceleration; angularVelocity = part.AngularVelocity; rotation = part.RotationOffset; - textureEntry = part.Shape.TextureEntry; + + if (sendTexture) + textureEntry = part.Shape.TextureEntry; + else + textureEntry = null; } #endregion ScenePresence/SOP Handling -- cgit v1.1