diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index e754522f44..55de1920ae 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -62,7 +62,7 @@ namespace OpenSim.Data.MySQL /// private object m_dbLock = new object(); - protected virtual Assembly Assembly + protected Assembly Assembly { get { return GetType().Assembly; } } @@ -76,7 +76,7 @@ namespace OpenSim.Data.MySQL Initialise(connectionString); } - public virtual void Initialise(string connectionString) + public void Initialise(string connectionString) { m_connectionString = connectionString; @@ -189,7 +189,7 @@ namespace OpenSim.Data.MySQL "AttachedPosY, AttachedPosZ, " + "PhysicsShapeType, Density, GravityModifier, " + "Friction, Restitution, Vehicle, PhysInertia, DynAttrs, " + - "RotationAxisLocks" + + "RotationAxisLocks, sopanims" + ") values (" + "?UUID, " + "?CreationDate, ?Name, ?Text, " + "?Description, ?SitName, ?TouchName, " + @@ -226,7 +226,7 @@ namespace OpenSim.Data.MySQL "?AttachedPosY, ?AttachedPosZ, " + "?PhysicsShapeType, ?Density, ?GravityModifier, " + "?Friction, ?Restitution, ?Vehicle, ?PhysInertia, ?DynAttrs," + - "?RotationAxisLocks)"; + "?RotationAxisLocks, ?sopanims)"; FillPrimCommand(cmd, prim, obj.UUID, regionUUID); @@ -1499,6 +1499,19 @@ namespace OpenSim.Data.MySQL pdata = PhysicsInertiaData.FromXml2(row["PhysInertia"].ToString()); prim.PhysicsInertia = pdata; + if (!(row["sopanims"] is DBNull)) + { + Byte[] data = (byte[])row["sopanims"]; + if (data.Length > 0) + prim.DeSerializeAnimations(data); + else + prim.Animations = null; + } + else + { + prim.Animations = null; + } + return prim; } @@ -1878,6 +1891,11 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("Friction", (double)prim.Friction); cmd.Parameters.AddWithValue("Restitution", (double)prim.Restitution); cmd.Parameters.AddWithValue("RotationAxisLocks", prim.RotationAxisLocks); + + if (prim.Animations!= null) + cmd.Parameters.AddWithValue("sopanims", prim.SerializeAnimations()); + else + cmd.Parameters.AddWithValue("sopanims", null); } /// diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations index 0577392184..7333df7e26 100644 --- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations +++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations @@ -467,3 +467,10 @@ COMMIT; BEGIN; ALTER TABLE `prims` ADD COLUMN `PhysInertia` TEXT default NULL; COMMIT; + +:VERSION 58 #----- Add sop animations + +BEGIN; +ALTER TABLE `prims` ADD COLUMN `sopanims` blob default NULL; +COMMIT; + diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 794162ecb5..cbe2324014 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2424,8 +2424,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } /// - /// Send an alert message to the client. On the Linden client (tested 1.19.1.4), this pops up a brief duration - /// blue information box in the bottom right hand corner. + /// Send an alert message to the client. This pops up a brief duration information box at a corner /// /// public void SendAlertMessage(string message) @@ -2463,17 +2462,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// middle of the window. If false, the message is displayed in a brief duration blue information box (as for /// the AlertMessage packet). public void SendAgentAlertMessage(string message, bool modal) - { - OutPacket(BuildAgentAlertPacket(message, modal), ThrottleOutPacketType.Task); - } - - /// - /// Construct an agent alert packet - /// - /// - /// - /// - public AgentAlertMessagePacket BuildAgentAlertPacket(string message, bool modal) { // Prepend a slash to make the message come up in the top right // again. @@ -2484,8 +2472,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP alertPack.AgentData.AgentID = AgentId; alertPack.AlertData.Message = Util.StringToBytes256(message); alertPack.AlertData.Modal = modal; - - return alertPack; + OutPacket(alertPack, ThrottleOutPacketType.Task); } public void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e5aa21e953..c32e01bdba 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -64,21 +64,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate void SynchronizeSceneHandler(Scene scene); - protected static int m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0x5fffafL); - public int NextObjectAnimationSequenceNumber - { - get - { - int ret = Interlocked.Increment(ref m_animationSequenceNumber); - if (ret <= 0 ) - { - m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0xafff5fL); - ret = Interlocked.Increment(ref m_animationSequenceNumber); - } - return ret; - } - } #region Fields /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index fd3a96bcbf..479fb91eb6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -32,6 +32,8 @@ using System.IO; using System.Reflection; using System.Runtime.Serialization; using System.Security.Permissions; +using System.Threading; +using System.Text; using System.Xml; using System.Xml.Serialization; using log4net; @@ -5657,13 +5659,29 @@ namespace OpenSim.Region.Framework.Scenes UpdatePrimFlags(wasUsingPhysics,wasTemporary,wasPhantom,makeVolumeDetect,false); } + protected static int m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0x5fffafL); + public static int NextObjectAnimationSequenceNumber + { + get + { + int ret = Interlocked.Increment(ref m_animationSequenceNumber); + if (ret <= 0) + { + m_animationSequenceNumber = (int)(Util.GetTimeStampTicks() & 0xafff5fL); + ret = Interlocked.Increment(ref m_animationSequenceNumber); + } + return ret; + } + } + private object animsLock = new object(); public Dictionary Animations = null; public Dictionary AnimationsNames = null; public bool AddAnimation(UUID animId, string animName) { - if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) + if (animId == UUID.Zero || string.IsNullOrEmpty(animName) || + ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) return false; lock (animsLock) @@ -5676,7 +5694,7 @@ namespace OpenSim.Region.Framework.Scenes if (Animations.ContainsKey(animId)) return false; - Animations[animId] = ParentGroup.Scene.NextObjectAnimationSequenceNumber; + Animations[animId] = NextObjectAnimationSequenceNumber; AnimationsNames[animId] = animName; ScheduleUpdate(PrimUpdateFlags.Animations); } @@ -5685,7 +5703,7 @@ namespace OpenSim.Region.Framework.Scenes public bool RemoveAnimation(UUID animId) { - if (ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) + if (animId == UUID.Zero || ParentGroup == null || ParentGroup.IsDeleted || ParentGroup.inTransit) return false; lock (animsLock) @@ -5726,5 +5744,87 @@ namespace OpenSim.Region.Framework.Scenes return Animations.Count; } } + + public Byte[] SerializeAnimations() + { + if (AnimationsNames == null) + return null; + + + lock (animsLock) + { + if (AnimationsNames.Count == 0) + return new byte[] { 0 }; + + using (MemoryStream ms = new MemoryStream()) + { + byte[] tmp = Utils.UInt16ToBytes((ushort)Animations.Count); + ms.Write(tmp, 0, 2); + + foreach(KeyValuePair kvp in AnimationsNames) + { + tmp = kvp.Key.GetBytes(); + ms.Write(tmp, 0, 16); + if(string.IsNullOrEmpty(kvp.Value)) + ms.WriteByte(0); + else + { + byte[] str = Util.StringToBytes(kvp.Value, 64); + int len = str.Length - 1; + ms.WriteByte((byte)len); + ms.Write(str, 0 , len); + } + } + return ms.ToArray(); + } + } + } + + public void DeSerializeAnimations(Byte[] data) + { + if(data == null) + { + Animations = null; + AnimationsNames = null; + return; + } + + if (data.Length < 2) + { + Animations = new Dictionary(); + AnimationsNames = new Dictionary(); + return; + } + + try + { + int count = (int)Utils.BytesToUInt16(data, 0); + if(count == 0) + return; + + Animations = new Dictionary(count); + AnimationsNames = new Dictionary(count); + int pos = 2; + while(--count >= 0) + { + UUID id = new UUID(data, pos); + if(id == UUID.Zero) + break; + pos += 16; + int strlen = data[pos++]; + string name = UTF8Encoding.UTF8.GetString(data, pos, strlen); + if(string.IsNullOrEmpty(name)) + break; + pos += strlen; + Animations[id] = NextObjectAnimationSequenceNumber; + AnimationsNames[id] = name; + } + return; + } + catch { } + + Animations = null; + AnimationsNames = null; + } } }