From 06147d0492e91c06a7d8f3a19c20897033f560a3 Mon Sep 17 00:00:00 2001
From: Charles Krinke
Date: Wed, 28 May 2008 14:03:08 +0000
Subject: Mantis#1406. Thank you kindly, Xantor for a patch that: llLoopSound
 sends out one packet to clients in view, so it doesn't work anymore when
 clients enter later on, or the prim is modified in any way. Solution: Stored
 sound data on prim, send full update instead. llStartSound and llLoopSound
 now accept both LLUUIDs to a sound as well as object inventory sound names.
 llStopSound clears prim data and sends full update.

---
 OpenSim/Framework/IClientAPI.cs                    |  2 +-
 .../Region/ClientStack/LindenUDP/LLClientView.cs   | 18 +++++--
 .../Environment/Modules/World/NPC/NPCAvatar.cs     |  2 +-
 .../Region/Environment/Scenes/SceneObjectPart.cs   | 16 ++++++-
 .../Region/Examples/SimpleModule/MyNpcCharacter.cs |  2 +-
 .../ScriptEngine/Common/LSL_BuiltIn_Commands.cs    | 56 +++++++++++++++++++++-
 6 files changed, 85 insertions(+), 11 deletions(-)

diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 48b4eb3..f5e98c8 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -892,7 +892,7 @@ namespace OpenSim.Framework
                                    LLVector3 pos, LLVector3 vel, LLVector3 acc, LLQuaternion rotation, LLVector3 rvel,
                                    uint flags,
                                    LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem,
-                                   byte clickAction, byte[] textureanim, bool attachment, uint AttachPoint, LLUUID AssetId);
+                                   byte clickAction, byte[] textureanim, bool attachment, uint AttachPoint, LLUUID AssetId, LLUUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius);
 
 
         void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape,
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 853d550..440392a 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -2194,7 +2194,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel,
                                   acc, rotation, rvel, flags,
                                   objectID, ownerID, text, color, parentID, particleSystem,
-                                  clickAction, textureanim, false,(uint)0, LLUUID.Zero);
+                                  clickAction, textureanim, false,(uint)0, LLUUID.Zero, LLUUID.Zero,0,0,0);
         }
 
         public void SendPrimitiveToClient(
@@ -2202,12 +2202,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             LLVector3 pos, LLVector3 velocity, LLVector3 acceleration, LLQuaternion rotation, LLVector3 rotational_velocity,
             uint flags,
             LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem,
-            byte clickAction, byte[] textureanim, bool attachment, uint AttachPoint, LLUUID AssetId)
+            byte clickAction, byte[] textureanim, bool attachment, uint AttachPoint, LLUUID AssetId, LLUUID SoundId, double SoundGain, byte SoundFlags, double SoundRadius)
         {
             if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0)
                 rotation = LLQuaternion.Identity;
 
             ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
+
+            
+
             // TODO: don't create new blocks if recycling an old packet
             outPacket.RegionData.RegionHandle = regionHandle;
             outPacket.RegionData.TimeDilation = timeDilation;
@@ -2234,7 +2237,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             outPacket.ObjectData[0].ParentID = parentID;
             outPacket.ObjectData[0].PSBlock = particleSystem;
             outPacket.ObjectData[0].ClickAction = clickAction;
-            //outPacket.ObjectData[0].Flags = 0;
+            outPacket.ObjectData[0].Flags = 0;
 
             if (attachment)
             {
@@ -2248,8 +2251,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 outPacket.ObjectData[0].State = (byte)((AttachPoint % 16) * 16 + (AttachPoint / 16));
             }
 
-            // Sound Radius
-            outPacket.ObjectData[0].Radius = 20;
+            // Xantor 20080528: Send sound info as well
+            outPacket.ObjectData[0].Sound   = SoundId;
+            outPacket.ObjectData[0].OwnerID = ownerID;
+            outPacket.ObjectData[0].Gain    = (float) SoundGain;
+            outPacket.ObjectData[0].Radius  = (float) SoundRadius;
+            outPacket.ObjectData[0].Flags   = SoundFlags; 
+
 
             byte[] pb = pos.GetBytes();
             Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
diff --git a/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs b/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs
index bad089d..caa3b5c 100644
--- a/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/Environment/Modules/World/NPC/NPCAvatar.cs
@@ -515,7 +515,7 @@ namespace OpenSim.Region.Environment.Modules.World.NPC
                                                   LLUUID objectID, LLUUID ownerID, string text, byte[] color,
                                                   uint parentID,
                                                   byte[] particleSystem, byte clickAction, byte[] textureanimation,
-                                                  bool attachment, uint AttachmentPoint, LLUUID AssetId)
+                                                  bool attachment, uint AttachmentPoint, LLUUID AssetId, LLUUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius)
         {
         }
         public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID,
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index 4610c99..9afffbe 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -592,6 +592,20 @@ namespace OpenSim.Region.Environment.Scenes
             }
         }
 
+        //Xantor 20080528 Sound stuff:
+        //  Note: This isn't persisted in the database right now, as the fields for that aren't just there yet.
+        //        Not a big problem as long as the script that sets it remains in the prim on startup.
+        //        for SL compatibility it should be persisted though (set sound / displaytext / particlesystem, kill script)
+        [XmlIgnore]
+        public LLUUID Sound;
+        [XmlIgnore]
+        public byte SoundFlags;
+        [XmlIgnore]
+        public double SoundGain;
+        [XmlIgnore]
+        public double SoundRadius;
+
+
         private string m_sitName = String.Empty;
 
         public string SitName
@@ -2406,7 +2420,7 @@ namespace OpenSim.Region.Environment.Scenes
                                                m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape,
                                                lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid,
                                                OwnerID,
-                                               m_text, color, ParentID, m_particleSystem, m_clickAction, m_TextureAnimation, m_IsAttachment, m_attachmentPoint,fromAssetID);
+                                               m_text, color, ParentID, m_particleSystem, m_clickAction, m_TextureAnimation, m_IsAttachment, m_attachmentPoint,fromAssetID, Sound, SoundGain, SoundFlags, SoundRadius);
         }
 
         /// Terse updates
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index 4407462..6825fbc 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -430,7 +430,7 @@ namespace OpenSim.Region.Examples.SimpleModule
                                                   LLUUID objectID, LLUUID ownerID, string text, byte[] color,
                                                   uint parentID,
                                                   byte[] particleSystem, byte clickAction, byte[] textureanimation,
-                                                  bool attachment, uint AttachmentPoint, LLUUID AssetId)
+                                                  bool attachment, uint AttachmentPoint, LLUUID AssetId, LLUUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius)
         {
         }
         public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID,
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
index 61f92ef..e91e73c 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
@@ -1390,16 +1390,59 @@ namespace OpenSim.Region.ScriptEngine.Common
             Deprecated("llSound");
         }
 
+        // Xantor 20080528 PlaySound updated so it accepts an objectinventory name -or- a key to a sound
         public void llPlaySound(string sound, double volume)
         {
             m_host.AddScriptLPS(1);
+
+            LLUUID key = LLUUID.Zero;
+
+            // if we can parse the string as a key, use it.
+            if (LLUUID.TryParse(sound, out key))
+            {
+                 sound = key.ToString();
+            }
+            // else try to locate the name in inventory of object. found returns key,
+            // not found returns LLUUID.Zero
+            else
+            {
+                 sound = InventoryKey(sound).ToString();
+            }
+
+            // send the sound, once, to all clients in range
             m_host.SendSound(sound, volume, false, 0);
+
         }
 
+        // Xantor 20080528 we should do this differently.
+        // 1) apply the sound to the object
+        // 2) schedule full update
+        // just sending the sound out once doesn't work so well when other avatars come in view later on
+        // or when the prim gets moved, changed, sat on, whatever
+        // see large number of mantises (mantes?)
         public void llLoopSound(string sound, double volume)
         {
             m_host.AddScriptLPS(1);
-            m_host.SendSound(sound, volume, false, 1);
+//            m_host.SendSound(sound, volume, false, 1);
+            LLUUID key = LLUUID.Zero;
+
+            // if we can parse the string as a key, use it.
+            if (LLUUID.TryParse(sound, out key))
+            {
+                m_host.Sound = key;
+            }
+            // else try to locate the name in inventory of object. found returns key,
+            // not found returns LLUUID.Zero 
+            else
+            {
+                m_host.Sound = InventoryKey(sound.ToString());
+            }
+
+            m_host.SoundGain = volume;
+            m_host.SoundFlags = 1;      // looping
+            m_host.SoundRadius = 20;    // Magic number, 20 seems reasonable. Make configurable?
+
+            m_host.SendFullUpdateToAllClients();
         }
 
         public void llLoopSoundMaster(string sound, double volume)
@@ -1426,10 +1469,19 @@ namespace OpenSim.Region.ScriptEngine.Common
             m_host.SendSound(sound, volume, true, 0);
         }
 
+        // Xantor 20080528: Clear prim data of sound instead
         public void llStopSound()
         {
             m_host.AddScriptLPS(1);
-            m_host.SendSound(LLUUID.Zero.ToString(), 1.0, false, 2);
+
+            m_host.Sound = LLUUID.Zero;
+            m_host.SoundGain = 0;
+            m_host.SoundFlags = 0;
+            m_host.SoundRadius = 0; 
+
+            m_host.SendFullUpdateToAllClients();
+
+            // m_host.SendSound(LLUUID.Zero.ToString(), 1.0, false, 2);
         }
 
         public void llPreloadSound(string sound)
-- 
cgit v1.1