diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs index e9151b5183..b8a8f4215b 100644 --- a/OpenSim/Region/Application/OpenSimMain.cs +++ b/OpenSim/Region/Application/OpenSimMain.cs @@ -370,8 +370,9 @@ namespace OpenSim protected override Scene CreateScene(RegionInfo regionInfo, StorageManager storageManager, AgentCircuitManager circuitManager) { + SceneCommunicationService sceneGridService = new SceneCommunicationService(m_commsManager); return - new Scene(regionInfo, circuitManager, m_commsManager, m_assetCache, storageManager, m_httpServer, + new Scene(regionInfo, circuitManager, m_commsManager, sceneGridService, m_assetCache, storageManager, m_httpServer, m_moduleLoader, m_dumpAssetsToFile); } diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs new file mode 100644 index 0000000000..325153f252 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -0,0 +1,657 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; +using libsecondlife.Packets; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Region.Environment.Types; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Environment.Scenes +{ + public class InnerScene + { + public Dictionary ScenePresences; + public Dictionary SceneObjects; + public Dictionary Entities; + + public BasicQuadTreeNode QuadTree; + + protected RegionInfo m_regInfo; + + protected Scene m_parentScene; + public PhysicsScene PhyScene; + + private PermissionManager PermissionsMngr; + + public InnerScene(Scene parent, RegionInfo regInfo, PermissionManager permissionsMngr) + { + m_parentScene = parent; + m_regInfo = regInfo; + PermissionsMngr = permissionsMngr; + QuadTree = new BasicQuadTreeNode(null, "/0/", 0, 0, 256, 256); + QuadTree.Subdivide(); + QuadTree.Subdivide(); + } + + public void Close() + { + ScenePresences.Clear(); + SceneObjects.Clear(); + Entities.Clear(); + } + + public void AddEntityFromStorage(SceneObjectGroup sceneObject) + { + sceneObject.RegionHandle = m_regInfo.RegionHandle; + sceneObject.SetScene(m_parentScene); + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + part.LocalID = m_parentScene.PrimIDAllocate(); + } + sceneObject.UpdateParentIDs(); + AddEntity(sceneObject); + } + + public void AddEntity(SceneObjectGroup sceneObject) + { + if (!Entities.ContainsKey(sceneObject.UUID)) + { + // QuadTree.AddObject(sceneObject); + Entities.Add(sceneObject.UUID, sceneObject); + } + } + + public void RemovePrim(uint localID, LLUUID avatar_deleter) + { + foreach (EntityBase obj in Entities.Values) + { + if (obj is SceneObjectGroup) + { + if (((SceneObjectGroup)obj).LocalId == localID) + { + m_parentScene.RemoveEntity((SceneObjectGroup)obj); + return; + } + } + } + } + + public ScenePresence CreateAndAddScenePresence(IClientAPI client, bool child, AvatarWearable[] wearables, byte[] visualParams) + { + ScenePresence newAvatar = null; + + newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, visualParams, wearables); + newAvatar.IsChildAgent = child; + + if (child) + { + MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new child agent."); + } + else + { + //newAvatar.OnSignificantClientMovement += m_LandManager.handleSignificantClientMovement; + + MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new root agent."); + MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Adding Physical agent."); + + newAvatar.AddToPhysicalScene(); + } + + lock (Entities) + { + if (!Entities.ContainsKey(client.AgentId)) + { + Entities.Add(client.AgentId, newAvatar); + } + else + { + Entities[client.AgentId] = newAvatar; + } + } + lock (ScenePresences) + { + if (ScenePresences.ContainsKey(client.AgentId)) + { + ScenePresences[client.AgentId] = newAvatar; + } + else + { + ScenePresences.Add(client.AgentId, newAvatar); + } + } + + return newAvatar; + } + + /// + /// Request a List of all m_scenePresences in this World + /// + /// + public List GetScenePresences() + { + List result = new List(ScenePresences.Values); + + return result; + } + + public List GetAvatars() + { + List result = + GetScenePresences(delegate(ScenePresence scenePresence) { return !scenePresence.IsChildAgent; }); + + return result; + } + + /// + /// Request a filtered list of m_scenePresences in this World + /// + /// + public List GetScenePresences(FilterAvatarList filter) + { + List result = new List(); + + foreach (ScenePresence avatar in ScenePresences.Values) + { + if (filter(avatar)) + { + result.Add(avatar); + } + } + + return result; + } + + /// + /// Request a Avatar by UUID + /// + /// + /// + public ScenePresence GetScenePresence(LLUUID avatarID) + { + if (ScenePresences.ContainsKey(avatarID)) + { + return ScenePresences[avatarID]; + } + return null; + } + + + public LLUUID ConvertLocalIDToFullID(uint localID) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + return ((SceneObjectGroup)ent).GetPartsFullID(localID); + } + } + } + return LLUUID.Zero; + } + + public void SendAllSceneObjectsToClient(ScenePresence presence) + { + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + ((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence); + } + } + } + + public SceneObjectPart GetSceneObjectPart(uint localID) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + return ((SceneObjectGroup)ent).GetChildPart(localID); + } + } + } + return null; + } + + public SceneObjectPart GetSceneObjectPart(LLUUID fullID) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(fullID); + if (hasPrim != false) + { + return ((SceneObjectGroup)ent).GetChildPart(fullID); + } + } + } + return null; + } + + internal bool TryGetAvatar(LLUUID avatarId, out ScenePresence avatar) + { + ScenePresence presence; + if (ScenePresences.TryGetValue(avatarId, out presence)) + { + if (!presence.IsChildAgent) + { + avatar = presence; + return true; + } + } + + avatar = null; + return false; + } + + internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) + { + foreach (ScenePresence presence in ScenePresences.Values) + { + if (!presence.IsChildAgent) + { + string name = presence.ControllingClient.FirstName + " " + presence.ControllingClient.LastName; + + if (String.Compare(avatarName, name, true) == 0) + { + avatar = presence; + return true; + } + } + } + + avatar = null; + return false; + } + + + internal void ForEachClient(Action action) + { + foreach (ScenePresence presence in ScenePresences.Values) + { + action(presence.ControllingClient); + } + } + + #region Client Event handlers + /// + /// + /// + /// + /// + /// + public void UpdatePrimScale(uint localID, LLVector3 scale, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).Resize(scale, localID); + break; + } + } + } + } + + + /// + /// + /// + /// + /// + /// + public void UpdatePrimSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateSingleRotation(rot, localID); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateGroupRotation(rot); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + /// + public void UpdatePrimRotation(uint localID, LLVector3 pos, LLQuaternion rot, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateGroupRotation(pos, rot); + break; + } + } + } + } + + public void UpdatePrimSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateSinglePosition(pos, localID); + break; + } + } + } + } + + + /// + /// + /// + /// + /// + /// + public void UpdatePrimPosition(uint localID, LLVector3 pos, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateGroupPosition(pos); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateTextureEntry(localID, texture); + break; + } + } + } + } + + /// + /// + /// + /// + /// + /// + public void UpdatePrimFlags(uint localID, Packet packet, IClientAPI remoteClient) + { + bool hasprim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasprim = ((SceneObjectGroup)ent).HasChildPrim(localID); + if (hasprim != false) + { + ((SceneObjectGroup)ent).UpdatePrimFlags(localID, (ushort)packet.Type, true, packet.ToBytes()); + } + } + } + + //System.Console.WriteLine("Got primupdate packet: " + packet.UsePhysics.ToString()); + } + + public void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 pos, IClientAPI remoteClient) + { + if (PermissionsMngr.CanEditObject(remoteClient.AgentId, objectID)) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(objectID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).GrabMovement(offset, pos, remoteClient); + break; + } + } + } + } + } + + /// + /// + /// + /// + /// + public void PrimName(uint primLocalID, string name) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).SetPartName(name, primLocalID); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void PrimDescription(uint primLocalID, string description) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).SetPartDescription(description, primLocalID); + break; + } + } + } + } + + public void UpdateExtraParam(uint primLocalID, ushort type, bool inUse, byte[] data) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateExtraParam(primLocalID, type, inUse, data); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void UpdatePrimShape(uint primLocalID, ObjectShapePacket.ObjectDataBlock shapeBlock) + { + bool hasPrim = false; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + hasPrim = ((SceneObjectGroup)ent).HasChildPrim(primLocalID); + if (hasPrim != false) + { + ((SceneObjectGroup)ent).UpdateShape(shapeBlock, primLocalID); + break; + } + } + } + } + + /// + /// + /// + /// + /// + public void LinkObjects(uint parentPrim, List childPrims) + { + SceneObjectGroup parenPrim = null; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + if (((SceneObjectGroup)ent).LocalId == parentPrim) + { + parenPrim = (SceneObjectGroup)ent; + break; + } + } + } + + List children = new List(); + if (parenPrim != null) + { + for (int i = 0; i < childPrims.Count; i++) + { + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + if (((SceneObjectGroup)ent).LocalId == childPrims[i]) + { + children.Add((SceneObjectGroup)ent); + } + } + } + } + } + + foreach (SceneObjectGroup sceneObj in children) + { + parenPrim.LinkToGroup(sceneObj); + } + } + + /// + /// + /// + /// + /// + /// + public void DuplicateObject(uint originalPrim, LLVector3 offset, uint flags) + { + SceneObjectGroup originPrim = null; + foreach (EntityBase ent in Entities.Values) + { + if (ent is SceneObjectGroup) + { + if (((SceneObjectGroup)ent).LocalId == originalPrim) + { + originPrim = (SceneObjectGroup)ent; + break; + } + } + } + + if (originPrim != null) + { + SceneObjectGroup copy = originPrim.Copy(); + copy.AbsolutePosition = copy.AbsolutePosition + offset; + Entities.Add(copy.UUID, copy); + + copy.ScheduleGroupForFullUpdate(); + + } + else + { + MainLog.Instance.Warn("client", "Attempted to duplicate nonexistant prim"); + } + } + + + #endregion + } +} diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs index 73d317a6b6..a9f6991ac8 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs @@ -89,129 +89,6 @@ namespace OpenSim.Region.Environment.Scenes } } - /// - /// - /// - /// - /// - /// - public void DuplicateObject(uint originalPrim, LLVector3 offset, uint flags) - { - SceneObjectGroup originPrim = null; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - if (((SceneObjectGroup) ent).LocalId == originalPrim) - { - originPrim = (SceneObjectGroup) ent; - break; - } - } - } - - if (originPrim != null) - { - SceneObjectGroup copy = originPrim.Copy(); - copy.AbsolutePosition = copy.AbsolutePosition + offset; - Entities.Add(copy.UUID, copy); - - copy.ScheduleGroupForFullUpdate(); - /* List avatars = this.GetScenePresences(); - for (int i = 0; i < avatars.Count; i++) - { - // copy.SendAllChildPrimsToClient(avatars[i].ControllingClient); - }*/ - } - else - { - MainLog.Instance.Warn("client", "Attempted to duplicate nonexistant prim"); - } - } - - /// - /// - /// - /// - /// - public void LinkObjects(uint parentPrim, List childPrims) - { - SceneObjectGroup parenPrim = null; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - if (((SceneObjectGroup) ent).LocalId == parentPrim) - { - parenPrim = (SceneObjectGroup) ent; - break; - } - } - } - - List children = new List(); - if (parenPrim != null) - { - for (int i = 0; i < childPrims.Count; i++) - { - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - if (((SceneObjectGroup) ent).LocalId == childPrims[i]) - { - children.Add((SceneObjectGroup) ent); - } - } - } - } - } - - foreach (SceneObjectGroup sceneObj in children) - { - parenPrim.LinkToGroup(sceneObj); - } - } - - /// - /// - /// - /// - /// - public void UpdatePrimShape(uint primLocalID, ObjectShapePacket.ObjectDataBlock shapeBlock) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(primLocalID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).UpdateShape(shapeBlock, primLocalID); - break; - } - } - } - } - - public void UpdateExtraParam(uint primLocalID, ushort type, bool inUse, byte[] data) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(primLocalID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).UpdateExtraParam(primLocalID, type, inUse, data); - break; - } - } - } - } - /// /// /// @@ -255,250 +132,6 @@ namespace OpenSim.Region.Environment.Scenes } } - /// - /// - /// - /// - /// - public void PrimDescription(uint primLocalID, string description) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(primLocalID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).SetPartDescription(description, primLocalID); - break; - } - } - } - } - - /// - /// - /// - /// - /// - public void PrimName(uint primLocalID, string name) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(primLocalID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).SetPartName(name, primLocalID); - break; - } - } - } - } - - public void MoveObject(LLUUID objectID, LLVector3 offset, LLVector3 pos, IClientAPI remoteClient) - { - if (PermissionsMngr.CanEditObject(remoteClient.AgentId, objectID)) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(objectID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).GrabMovement(offset, pos, remoteClient); - break; - } - } - } - } - } - - /// - /// - /// - /// - /// - /// - public void UpdatePrimFlags(uint localID, Packet packet, IClientAPI remoteClient) - { - bool hasprim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasprim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasprim != false) - { - ((SceneObjectGroup) ent).UpdatePrimFlags(localID, (ushort) packet.Type, true, packet.ToBytes()); - } - } - } - - //System.Console.WriteLine("Got primupdate packet: " + packet.UsePhysics.ToString()); - } - - /// - /// - /// - /// - /// - /// - public void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).UpdateTextureEntry(localID, texture); - break; - } - } - } - } - - /// - /// - /// - /// - /// - /// - public void UpdatePrimPosition(uint localID, LLVector3 pos, IClientAPI remoteClient) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).UpdateGroupPosition(pos); - break; - } - } - } - } - - public void UpdatePrimSinglePosition(uint localID, LLVector3 pos, IClientAPI remoteClient) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).UpdateSinglePosition(pos, localID); - break; - } - } - } - } - - /// - /// - /// - /// - /// - /// - /// - public void UpdatePrimRotation(uint localID, LLVector3 pos, LLQuaternion rot, IClientAPI remoteClient) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).UpdateGroupRotation(pos, rot); - break; - } - } - } - } - - /// - /// - /// - /// - /// - /// - public void UpdatePrimRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).UpdateGroupRotation(rot); - break; - } - } - } - } - - /// - /// - /// - /// - /// - /// - public void UpdatePrimSingleRotation(uint localID, LLQuaternion rot, IClientAPI remoteClient) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).UpdateSingleRotation(rot, localID); - break; - } - } - } - } - - /// - /// - /// - /// - /// - /// - public void UpdatePrimScale(uint localID, LLVector3 scale, IClientAPI remoteClient) - { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - ((SceneObjectGroup) ent).Resize(scale, localID); - break; - } - } - } - } - public void StartAnimation(LLUUID animID, int seq, LLUUID agentId) { Broadcast(delegate(IClientAPI client) { client.SendAnimation(animID, seq, agentId); }); diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 9eb3a712a8..a956eb2cdb 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -51,13 +51,14 @@ using Timer=System.Timers.Timer; namespace OpenSim.Region.Environment.Scenes { + public delegate bool FilterAvatarList(ScenePresence avatar); + public partial class Scene : SceneBase { - public delegate bool FilterAvatarList(ScenePresence avatar); - + #region Fields protected Timer m_heartbeatTimer = new Timer(); - protected Dictionary m_scenePresences; - protected Dictionary m_sceneObjects; + + public InnerScene m_innerScene; private Random Rand = new Random(); private uint _primCount = 702000; @@ -66,16 +67,14 @@ namespace OpenSim.Region.Environment.Scenes private int m_timePhase = 24; private int m_timeUpdateCount; - public BasicQuadTreeNode QuadTree; - private readonly Mutex updateLock; protected ModuleLoader m_moduleLoader; protected StorageManager storageManager; protected AgentCircuitManager authenticateHandler; - protected RegionCommsListener regionCommsHost; public CommunicationsManager commsManager; // protected XferManager xferManager; + protected SceneCommunicationService m_sceneGridService; protected Dictionary capsHandlers = new Dictionary(); protected BaseHttpServer httpListener; @@ -111,6 +110,7 @@ namespace OpenSim.Region.Environment.Scenes private int m_update_terrain = 50; private int m_update_land = 1; private int m_update_avatars = 1; + #endregion #region Properties @@ -128,12 +128,16 @@ namespace OpenSim.Region.Environment.Scenes private readonly EstateManager m_estateManager; - private PhysicsScene phyScene; + private PhysicsScene phyScene + { + set { m_innerScene.PhyScene = value; } + get { return (m_innerScene.PhyScene); } + } public PhysicsScene PhysScene { - set { phyScene = value; } - get { return (phyScene); } + set { m_innerScene.PhyScene = value; } + get { return (m_innerScene.PhyScene); } } public EstateManager EstateManager @@ -148,29 +152,48 @@ namespace OpenSim.Region.Environment.Scenes get { return m_permissionManager; } } - public Dictionary Objects - { - get { return m_sceneObjects; } - } - public int TimePhase { get { return m_timePhase; } } + public Dictionary Objects + { + get { return m_innerScene.SceneObjects; } + } + + protected Dictionary m_scenePresences + { + get { return m_innerScene.ScenePresences; } + set { m_innerScene.ScenePresences = value; } + } + + protected Dictionary m_sceneObjects + { + get { return m_innerScene.SceneObjects; } + set { m_innerScene.SceneObjects = value; } + } + + public Dictionary Entities + { + get { return m_innerScene.Entities; } + set { m_innerScene.Entities = value; } + } + #endregion #region Constructors - public Scene(RegionInfo regInfo, AgentCircuitManager authen, CommunicationsManager commsMan, + public Scene(RegionInfo regInfo, AgentCircuitManager authen, CommunicationsManager commsMan, SceneCommunicationService sceneGridService, AssetCache assetCach, StorageManager storeManager, BaseHttpServer httpServer, ModuleLoader moduleLoader, bool dumpAssetsToFile) { updateLock = new Mutex(false); - + m_moduleLoader = moduleLoader; authenticateHandler = authen; commsManager = commsMan; + m_sceneGridService = sceneGridService; storageManager = storeManager; assetCache = assetCach; m_regInfo = regInfo; @@ -184,15 +207,13 @@ namespace OpenSim.Region.Environment.Scenes m_eventManager = new EventManager(); m_permissionManager = new PermissionManager(this); + m_innerScene = new InnerScene(this, regInfo, m_permissionManager); + m_eventManager.OnParcelPrimCountAdd += m_LandManager.addPrimToLandPrimCounts; m_eventManager.OnPermissionError += SendPermissionAlert; - QuadTree = new BasicQuadTreeNode(null, "/0/", 0, 0, 256, 256); - QuadTree.Subdivide(); - QuadTree.Subdivide(); - MainLog.Instance.Verbose("Creating new entitities instance"); Entities = new Dictionary(); m_scenePresences = new Dictionary(); @@ -209,6 +230,26 @@ namespace OpenSim.Region.Environment.Scenes #endregion + #region Startup / Close Methods + public override void Close() + { + m_heartbeatTimer.Close(); + m_innerScene.Close(); + m_sceneGridService.Close(); + + base.Close(); + } + + /// + /// + /// + public void StartTimer() + { + m_heartbeatTimer.Enabled = true; + m_heartbeatTimer.Interval = (int)(m_timespan * 1000); + m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); + } + public void SetModuleInterfaces() { m_simChatModule = RequestModuleInterface(); @@ -218,25 +259,8 @@ namespace OpenSim.Region.Environment.Scenes XferManager = RequestModuleInterface(); } - #region Script Handling Methods - - public void SendCommandToPlugins(string[] args) - { - m_eventManager.TriggerOnPluginConsole(args); - } - #endregion - /// - /// - /// - public void StartTimer() - { - m_heartbeatTimer.Enabled = true; - m_heartbeatTimer.Interval = (int) (m_timespan*1000); - m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); - } - #region Update Methods /// @@ -597,38 +621,17 @@ namespace OpenSim.Region.Environment.Scenes public void RemovePrim(uint localID, LLUUID avatar_deleter) { - foreach (EntityBase obj in Entities.Values) - { - if (obj is SceneObjectGroup) - { - if (((SceneObjectGroup) obj).LocalId == localID) - { - RemoveEntity((SceneObjectGroup) obj); - return; - } - } - } + m_innerScene.RemovePrim(localID, avatar_deleter); } public void AddEntityFromStorage(SceneObjectGroup sceneObject) { - sceneObject.RegionHandle = m_regionHandle; - sceneObject.SetScene(this); - foreach (SceneObjectPart part in sceneObject.Children.Values) - { - part.LocalID = PrimIDAllocate(); - } - sceneObject.UpdateParentIDs(); - AddEntity(sceneObject); + m_innerScene.AddEntityFromStorage(sceneObject); } public void AddEntity(SceneObjectGroup sceneObject) { - if (!Entities.ContainsKey(sceneObject.UUID)) - { - // QuadTree.AddObject(sceneObject); - Entities.Add(sceneObject.UUID, sceneObject); - } + m_innerScene.AddEntity(sceneObject); } public void RemoveEntity(SceneObjectGroup sceneObject) @@ -797,31 +800,30 @@ namespace OpenSim.Region.Environment.Scenes client.OnRegionHandShakeReply += SendLayerData; //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims); client.OnModifyTerrain += ModifyTerrain; - //client.OnChatFromViewer += SimChat; - client.OnRequestWearables += InformClientOfNeighbours; + // client.OnRequestWearables += InformClientOfNeighbours; client.OnAddPrim += AddNewPrim; - client.OnUpdatePrimGroupPosition += UpdatePrimPosition; - client.OnUpdatePrimSinglePosition += UpdatePrimSinglePosition; - client.OnUpdatePrimGroupRotation += UpdatePrimRotation; - client.OnUpdatePrimGroupMouseRotation += UpdatePrimRotation; - client.OnUpdatePrimSingleRotation += UpdatePrimSingleRotation; - client.OnUpdatePrimScale += UpdatePrimScale; - client.OnUpdateExtraParams += UpdateExtraParam; - client.OnUpdatePrimShape += UpdatePrimShape; + client.OnUpdatePrimGroupPosition += m_innerScene.UpdatePrimPosition; + client.OnUpdatePrimSinglePosition += m_innerScene.UpdatePrimSinglePosition; + client.OnUpdatePrimGroupRotation += m_innerScene.UpdatePrimRotation; + client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation; + client.OnUpdatePrimSingleRotation += m_innerScene.UpdatePrimSingleRotation; + client.OnUpdatePrimScale += m_innerScene.UpdatePrimScale; + client.OnUpdateExtraParams += m_innerScene.UpdateExtraParam; + client.OnUpdatePrimShape += m_innerScene.UpdatePrimShape; client.OnRequestMapBlocks += RequestMapBlocks; - client.OnUpdatePrimTexture += UpdatePrimTexture; + client.OnUpdatePrimTexture += m_innerScene.UpdatePrimTexture; client.OnTeleportLocationRequest += RequestTeleportLocation; client.OnObjectSelect += SelectPrim; client.OnObjectDeselect += DeselectPrim; - client.OnGrabUpdate += MoveObject; + client.OnGrabUpdate += m_innerScene.MoveObject; client.OnDeRezObject += DeRezObject; client.OnRezObject += RezObject; client.OnNameFromUUIDRequest += commsManager.HandleUUIDNameRequest; - client.OnObjectDescription += PrimDescription; - client.OnObjectName += PrimName; - client.OnLinkObjects += LinkObjects; - client.OnObjectDuplicate += DuplicateObject; - client.OnUpdatePrimFlags += UpdatePrimFlags; + client.OnObjectDescription += m_innerScene.PrimDescription; + client.OnObjectName += m_innerScene.PrimName; + client.OnLinkObjects += m_innerScene.LinkObjects; + client.OnObjectDuplicate += m_innerScene.DuplicateObject; + client.OnUpdatePrimFlags += m_innerScene.UpdatePrimFlags; client.OnParcelPropertiesRequest += new ParcelPropertiesRequest(m_LandManager.handleParcelPropertiesRequest); client.OnParcelDivideRequest += new ParcelDivideRequest(m_LandManager.handleParcelDivideRequest); @@ -845,8 +847,6 @@ namespace OpenSim.Region.Environment.Scenes client.OnRezScript += RezScript; client.OnRemoveTaskItem += RemoveTaskInventory; - // client.OnRequestAvatarProperties += RequestAvatarProperty; - client.OnGrabObject += ProcessObjectGrab; EventManager.TriggerOnNewClient(client); @@ -865,44 +865,11 @@ namespace OpenSim.Region.Environment.Scenes AvatarFactoryModule.GetDefaultAvatarAppearance(out wearables, out visualParams); } - newAvatar = new ScenePresence(client, this, m_regInfo, visualParams, wearables); - newAvatar.IsChildAgent = child; + newAvatar = m_innerScene.CreateAndAddScenePresence(client, child, wearables, visualParams); - if (child) - { - MainLog.Instance.Verbose("SCENE", RegionInfo.RegionName + ": Creating new child agent."); - } - else + if (!newAvatar.IsChildAgent) { newAvatar.OnSignificantClientMovement += m_LandManager.handleSignificantClientMovement; - - MainLog.Instance.Verbose("SCENE", RegionInfo.RegionName + ": Creating new root agent."); - MainLog.Instance.Verbose("SCENE", RegionInfo.RegionName + ": Adding Physical agent."); - - newAvatar.AddToPhysicalScene(); - } - - lock (Entities) - { - if (!Entities.ContainsKey(client.AgentId)) - { - Entities.Add(client.AgentId, newAvatar); - } - else - { - Entities[client.AgentId] = newAvatar; - } - } - lock (m_scenePresences) - { - if (m_scenePresences.ContainsKey(client.AgentId)) - { - m_scenePresences[client.AgentId] = newAvatar; - } - else - { - m_scenePresences.Add(client.AgentId, newAvatar); - } } return newAvatar; @@ -942,87 +909,13 @@ namespace OpenSim.Region.Environment.Scenes return; } + public void NotifyMyCoarseLocationChange() + { + ForEachScenePresence(delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); + } #endregion - #region Request m_scenePresences List Methods - - //The idea is to have a group of method that return a list of avatars meeting some requirement - // ie it could be all m_scenePresences within a certain range of the calling prim/avatar. - - /// - /// Request a List of all m_scenePresences in this World - /// - /// - public List GetScenePresences() - { - List result = new List(m_scenePresences.Values); - - return result; - } - - public List GetAvatars() - { - List result = - GetScenePresences(delegate(ScenePresence scenePresence) { return !scenePresence.IsChildAgent; }); - - return result; - } - - /// - /// Request a filtered list of m_scenePresences in this World - /// - /// - public List GetScenePresences(FilterAvatarList filter) - { - List result = new List(); - - foreach (ScenePresence avatar in m_scenePresences.Values) - { - if (filter(avatar)) - { - result.Add(avatar); - } - } - - return result; - } - - /// - /// Request a Avatar by UUID - /// - /// - /// - public ScenePresence GetScenePresence(LLUUID avatarID) - { - if (m_scenePresences.ContainsKey(avatarID)) - { - return m_scenePresences[avatarID]; - } - return null; - } - - /// - /// - /// - /// - public void ForEachScenePresence(Action action) - { - foreach (ScenePresence presence in m_scenePresences.Values) - { - action(presence); - } - } - - public void ForEachObject(Action action) - { - foreach (SceneObjectGroup presence in m_sceneObjects.Values) - { - action(presence); - } - } - - #endregion - + #region Entities /// /// /// @@ -1044,36 +937,18 @@ namespace OpenSim.Region.Environment.Scenes Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); } - public void NotifyMyCoarseLocationChange() - { - ForEachScenePresence(delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); - } + #endregion - public void SendAllSceneObjectsToClient(ScenePresence presence) - { - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - // ((SceneObjectGroup)ent).SendFullUpdateToClient(client); - ((SceneObjectGroup) ent).ScheduleFullUpdateToAvatar(presence); - } - } - } - - #region RegionCommsHost + #region RegionComms /// /// /// public void RegisterRegionWithComms() { - regionCommsHost = commsManager.GridService.RegisterRegion(m_regInfo); - if (regionCommsHost != null) - { - regionCommsHost.OnExpectUser += NewUserConnection; - regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing; - } + m_sceneGridService.RegisterRegion(m_regInfo); + m_sceneGridService.OnExpectUser += NewUserConnection; + m_sceneGridService.OnAvatarCrossingIntoRegion += AgentCrossing; } /// @@ -1083,27 +958,23 @@ namespace OpenSim.Region.Environment.Scenes /// public void NewUserConnection(ulong regionHandle, AgentCircuitData agent) { - // Console.WriteLine("Scene.cs - add new user connection"); - //should just check that its meant for this region if (regionHandle == m_regInfo.RegionHandle) { if (agent.CapsPath != "") { - //Console.WriteLine("new user, so creating caps handler for it"); Caps cap = new Caps(commsManager.AssetCache, httpListener, m_regInfo.ExternalHostName, httpListener.Port, agent.CapsPath, agent.AgentID, m_dumpAssetsToFile); - Util.SetCapsURL(agent.AgentID, - "http://" + m_regInfo.ExternalHostName + ":" + httpListener.Port.ToString() + + Util.SetCapsURL(agent.AgentID, "http://" + m_regInfo.ExternalHostName + ":" + httpListener.Port.ToString() + "/CAPS/" + agent.CapsPath + "0000/"); cap.RegisterHandlers(); cap.AddNewInventoryItem = AddInventoryItem; cap.ItemUpdatedCall = CapsUpdateInventoryItemAsset; if (capsHandlers.ContainsKey(agent.AgentID)) { - MainLog.Instance.Warn("client", "Adding duplicate CAPS entry for user " + - agent.AgentID.ToStringHyphenated()); + //MainLog.Instance.Warn("client", "Adding duplicate CAPS entry for user " + + // agent.AgentID.ToStringHyphenated()); capsHandlers[agent.AgentID] = cap; } else @@ -1126,61 +997,13 @@ namespace OpenSim.Region.Environment.Scenes } } - private delegate void InformClientOfNeighbourDelegate( - IClientAPI remoteClient, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint); - - private void InformClientOfNeighbourCompleted(IAsyncResult iar) - { - InformClientOfNeighbourDelegate icon = (InformClientOfNeighbourDelegate) iar.AsyncState; - - - icon.EndInvoke(iar); - } - - /// - /// Async compnent for informing client of which neighbours exists - /// - /// - /// This needs to run asynchronesously, as a network timeout may block the thread for a long while - /// - /// - /// - /// - /// - private void InformClientOfNeighbourAsync(IClientAPI remoteClient, AgentCircuitData a, ulong regionHandle, - IPEndPoint endPoint) - { - MainLog.Instance.Notice("INTERGRID", "Starting to inform client about neighbours"); - bool regionAccepted = commsManager.InterRegion.InformRegionOfChildAgent(regionHandle, a); - - if (regionAccepted) - remoteClient.InformClientOfNeighbour(regionHandle, endPoint); - MainLog.Instance.Notice("INTERGRID", "Completed inform client about neighbours"); - } - + /// /// /// - public void InformClientOfNeighbours(IClientAPI remoteClient) + public void InformClientOfNeighbours(ScenePresence presence) { - List neighbours = - commsManager.GridService.RequestNeighbours(m_regInfo.RegionLocX, m_regInfo.RegionLocY); - if (neighbours != null) - { - for (int i = 0; i < neighbours.Count; i++) - { - AgentCircuitData agent = remoteClient.RequestClientInfo(); - agent.BaseFolder = LLUUID.Zero; - agent.InventoryFolder = LLUUID.Zero; - agent.startpos = new LLVector3(128, 128, 70); - agent.child = true; - - InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; - d.BeginInvoke(remoteClient, agent, neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint, - InformClientOfNeighbourCompleted, - d); - } - } + m_sceneGridService.InformClientOfNeighbours(presence); } /// @@ -1190,7 +1013,7 @@ namespace OpenSim.Region.Environment.Scenes /// public RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle) { - return commsManager.GridService.RequestNeighbourInfo(regionHandle); + return m_sceneGridService.RequestNeighbouringRegionInfo(regionHandle); } /// @@ -1202,9 +1025,7 @@ namespace OpenSim.Region.Environment.Scenes /// public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY) { - List mapBlocks; - mapBlocks = commsManager.GridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); - remoteClient.SendMapBlock(mapBlocks); + m_sceneGridService.RequestMapBlocks(remoteClient, minX, minY, maxX, maxX); } /// @@ -1218,34 +1039,9 @@ namespace OpenSim.Region.Environment.Scenes public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, LLVector3 lookAt, uint flags) { - if (regionHandle == m_regionHandle) + if (m_scenePresences.ContainsKey(remoteClient.AgentId)) { - if (m_scenePresences.ContainsKey(remoteClient.AgentId)) - { - remoteClient.SendTeleportLocationStart(); - remoteClient.SendLocalTeleport(position, lookAt, flags); - m_scenePresences[remoteClient.AgentId].Teleport(position); - } - } - else - { - RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); - if (reg != null) - { - remoteClient.SendTeleportLocationStart(); - AgentCircuitData agent = remoteClient.RequestClientInfo(); - agent.BaseFolder = LLUUID.Zero; - agent.InventoryFolder = LLUUID.Zero; - // agent.startpos = new LLVector3(128, 128, 70); - agent.startpos = position; - agent.child = true; - m_scenePresences[remoteClient.AgentId].Close(); - commsManager.InterRegion.InformRegionOfChildAgent(regionHandle, agent); - commsManager.InterRegion.ExpectAvatarCrossing(regionHandle, remoteClient.AgentId, position, false); - AgentCircuitData circuitdata = remoteClient.RequestClientInfo(); - string capsPath = Util.GetCapsURL(remoteClient.AgentId); - remoteClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath); - } + m_sceneGridService.RequestTeleportLocation(m_scenePresences[remoteClient.AgentId], regionHandle, position, lookAt, flags); } } @@ -1257,19 +1053,12 @@ namespace OpenSim.Region.Environment.Scenes /// public bool InformNeighbourOfCrossing(ulong regionhandle, LLUUID agentID, LLVector3 position, bool isFlying) { - return commsManager.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position, isFlying); - } - - public void performParcelPrimCountUpdate() - { - m_LandManager.resetAllLandPrimCounts(); - m_eventManager.TriggerParcelPrimCountUpdate(); - m_LandManager.finalizeLandPrimCountUpdate(); - m_LandManager.landPrimCountTainted = false; + return m_sceneGridService.InformNeighbourOfCrossing(regionhandle, agentID, position, isFlying); } #endregion + #region Module Methods public void AddModule(string name, IRegionModule module) { if (!Modules.ContainsKey(name)) @@ -1297,7 +1086,9 @@ namespace OpenSim.Region.Environment.Scenes return default(T); } } + #endregion + #region Other Methods public void SetTimePhase(int phase) { m_timePhase = phase; @@ -1313,6 +1104,26 @@ namespace OpenSim.Region.Environment.Scenes } } + public LLUUID MakeHttpRequest(string url, string type, string body) + { + if (m_httpRequestModule != null) + { + return m_httpRequestModule.MakeHttpRequest(url, type, body); + } + return LLUUID.Zero; + } + + public void performParcelPrimCountUpdate() + { + m_LandManager.resetAllLandPrimCounts(); + m_eventManager.TriggerParcelPrimCountUpdate(); + m_LandManager.finalizeLandPrimCountUpdate(); + m_LandManager.landPrimCountTainted = false; + } + + #endregion + + #region Console Commands #region Alert Methods private void SendPermissionAlert(LLUUID user, string reason) @@ -1444,15 +1255,17 @@ namespace OpenSim.Region.Environment.Scenes } } - public LLUUID MakeHttpRequest(string url, string type, string body) + #endregion + + #region Script Handling Methods + + public void SendCommandToPlugins(string[] args) { - if (m_httpRequestModule != null) - { - return m_httpRequestModule.MakeHttpRequest(url, type, body); - } - return LLUUID.Zero; + m_eventManager.TriggerOnPluginConsole(args); } + #endregion + #region Script Engine private List ScriptEngines = new List(); @@ -1467,106 +1280,100 @@ namespace OpenSim.Region.Environment.Scenes #endregion + #region InnerScene wrapper methods + public LLUUID ConvertLocalIDToFullID(uint localID) { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) + return m_innerScene.ConvertLocalIDToFullID(localID); + } + + public void SendAllSceneObjectsToClient(ScenePresence presence) + { + m_innerScene.SendAllSceneObjectsToClient(presence); + } + + //The idea is to have a group of method that return a list of avatars meeting some requirement + // ie it could be all m_scenePresences within a certain range of the calling prim/avatar. + + public List GetAvatars() + { + return m_innerScene.GetAvatars(); + } + + /// + /// Request a List of all m_scenePresences in this World + /// + /// + public List GetScenePresences() + { + return m_innerScene.GetScenePresences(); + } + + /// + /// Request a filtered list of m_scenePresences in this World + /// + /// + public List GetScenePresences(FilterAvatarList filter) + { + return m_innerScene.GetScenePresences(filter); + } + + /// + /// Request a Avatar by UUID + /// + /// + /// + public ScenePresence GetScenePresence(LLUUID avatarID) + { + return m_innerScene.GetScenePresence(avatarID); + } + + /// + /// + /// + /// + public void ForEachScenePresence(Action action) + { + foreach (ScenePresence presence in m_scenePresences.Values) { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - return ((SceneObjectGroup) ent).GetPartsFullID(localID); - } - } + action(presence); + } + } + + public void ForEachObject(Action action) + { + foreach (SceneObjectGroup presence in m_sceneObjects.Values) + { + action(presence); } - return LLUUID.Zero; } public SceneObjectPart GetSceneObjectPart(uint localID) { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(localID); - if (hasPrim != false) - { - return ((SceneObjectGroup) ent).GetChildPart(localID); - } - } - } - return null; + return m_innerScene.GetSceneObjectPart(localID); } public SceneObjectPart GetSceneObjectPart(LLUUID fullID) { - bool hasPrim = false; - foreach (EntityBase ent in Entities.Values) - { - if (ent is SceneObjectGroup) - { - hasPrim = ((SceneObjectGroup) ent).HasChildPrim(fullID); - if (hasPrim != false) - { - return ((SceneObjectGroup) ent).GetChildPart(fullID); - } - } - } - return null; + return m_innerScene.GetSceneObjectPart(fullID); } internal bool TryGetAvatar(LLUUID avatarId, out ScenePresence avatar) { - ScenePresence presence; - if (m_scenePresences.TryGetValue(avatarId, out presence)) - { - if (!presence.IsChildAgent) - { - avatar = presence; - return true; - } - } - - avatar = null; - return false; + return m_innerScene.TryGetAvatar(avatarId, out avatar); } - public override void Close() - { - m_heartbeatTimer.Close(); - - base.Close(); - } internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) { - foreach (ScenePresence presence in m_scenePresences.Values) - { - if (!presence.IsChildAgent) - { - string name = presence.ControllingClient.FirstName + " " + presence.ControllingClient.LastName; - - if (String.Compare(avatarName, name, true) == 0) - { - avatar = presence; - return true; - } - } - } - - avatar = null; - return false; + return m_innerScene.TryGetAvatarByName(avatarName, out avatar); } internal void ForEachClient(Action action) { - foreach (ScenePresence presence in m_scenePresences.Values) - { - action(presence.ControllingClient); - } + m_innerScene.ForEachClient(action); } + + #endregion } } \ No newline at end of file diff --git a/OpenSim/Region/Environment/Scenes/SceneBase.cs b/OpenSim/Region/Environment/Scenes/SceneBase.cs index ba4c40eb8b..149443789b 100644 --- a/OpenSim/Region/Environment/Scenes/SceneBase.cs +++ b/OpenSim/Region/Environment/Scenes/SceneBase.cs @@ -37,6 +37,7 @@ namespace OpenSim.Region.Environment.Scenes { public abstract class SceneBase : IScene { + #region Fields private readonly ClientManager m_clientManager = new ClientManager(); public ClientManager ClientManager @@ -44,7 +45,7 @@ namespace OpenSim.Region.Environment.Scenes get { return m_clientManager; } } - public Dictionary Entities; + // public Dictionary Entities; protected ulong m_regionHandle; protected string m_regionName; protected RegionInfo m_regInfo; @@ -69,6 +70,8 @@ namespace OpenSim.Region.Environment.Scenes private uint m_nextLocalId = 8880000; protected AssetCache assetCache; + #endregion + #region Update Methods /// diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs new file mode 100644 index 0000000000..2ade989ba2 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs @@ -0,0 +1,212 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Text; +using libsecondlife; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Communications; + + +namespace OpenSim.Region.Environment.Scenes +{ + public class SceneCommunicationService //one instance per region + { + protected CommunicationsManager m_commsProvider; + protected RegionInfo m_regionInfo; + + protected RegionCommsListener regionCommsHost; + + public event AgentCrossing OnAvatarCrossingIntoRegion; + public event ExpectUserDelegate OnExpectUser; + + + public SceneCommunicationService(CommunicationsManager commsMan) + { + m_commsProvider = commsMan; + } + + public void RegisterRegion(RegionInfo regionInfos) + { + m_regionInfo = regionInfos; + regionCommsHost = m_commsProvider.GridService.RegisterRegion(m_regionInfo); + if (regionCommsHost != null) + { + regionCommsHost.OnExpectUser += NewUserConnection; + regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing; + } + } + + public void Close() + { + regionCommsHost.OnExpectUser -= NewUserConnection; + regionCommsHost.OnAvatarCrossingIntoRegion -= AgentCrossing; + //regionCommsHost.RemoveRegion(m_regionInfo); //TODO add to method to commsManager + regionCommsHost = null; + } + + #region CommsManager Event handlers + /// + /// + /// + /// + /// + public void NewUserConnection(ulong regionHandle, AgentCircuitData agent) + { + if (OnExpectUser != null) + { + OnExpectUser(regionHandle, agent); + } + } + + public void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + if (OnAvatarCrossingIntoRegion != null) + { + OnAvatarCrossingIntoRegion(regionHandle, agentID, position, isFlying); + } + } + #endregion + + #region Inform Client of Neighbours + private delegate void InformClientOfNeighbourDelegate( + ScenePresence avatar, AgentCircuitData a, ulong regionHandle, IPEndPoint endPoint); + + private void InformClientOfNeighbourCompleted(IAsyncResult iar) + { + InformClientOfNeighbourDelegate icon = (InformClientOfNeighbourDelegate)iar.AsyncState; + icon.EndInvoke(iar); + } + + /// + /// Async compnent for informing client of which neighbours exists + /// + /// + /// This needs to run asynchronesously, as a network timeout may block the thread for a long while + /// + /// + /// + /// + /// + private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, ulong regionHandle, + IPEndPoint endPoint) + { + MainLog.Instance.Notice("INTERGRID", "Starting to inform client about neighbours"); + bool regionAccepted = m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, a); + + if (regionAccepted) + { + avatar.ControllingClient.InformClientOfNeighbour(regionHandle, endPoint); + avatar.AddNeighbourRegion(regionHandle); + MainLog.Instance.Notice("INTERGRID", "Completed inform client about neighbours"); + } + } + + /// + /// + /// + public void InformClientOfNeighbours(ScenePresence avatar) + { + List neighbours = + m_commsProvider.GridService.RequestNeighbours(m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); + if (neighbours != null) + { + for (int i = 0; i < neighbours.Count; i++) + { + AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); + agent.BaseFolder = LLUUID.Zero; + agent.InventoryFolder = LLUUID.Zero; + agent.startpos = new LLVector3(128, 128, 70); + agent.child = true; + + InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; + d.BeginInvoke(avatar, agent, neighbours[i].RegionHandle, neighbours[i].ExternalEndPoint, + InformClientOfNeighbourCompleted, + d); + } + } + } + #endregion + + /// + /// + /// + /// + /// + public virtual RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle) + { + return m_commsProvider.GridService.RequestNeighbourInfo(regionHandle); + } + + /// + /// + /// + /// + /// + /// + /// + public virtual void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY) + { + List mapBlocks; + mapBlocks = m_commsProvider.GridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY); + remoteClient.SendMapBlock(mapBlocks); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public virtual void RequestTeleportLocation(ScenePresence avatar, ulong regionHandle, LLVector3 position, + LLVector3 lookAt, uint flags) + { + if (regionHandle == m_regionInfo.RegionHandle) + { + + avatar.ControllingClient.SendTeleportLocationStart(); + avatar.ControllingClient.SendLocalTeleport(position, lookAt, flags); + avatar.Teleport(position); + + } + else + { + RegionInfo reg = RequestNeighbouringRegionInfo(regionHandle); + if (reg != null) + { + avatar.ControllingClient.SendTeleportLocationStart(); + AgentCircuitData agent = avatar.ControllingClient.RequestClientInfo(); + agent.BaseFolder = LLUUID.Zero; + agent.InventoryFolder = LLUUID.Zero; + agent.startpos = position; + agent.child = true; + avatar.Close(); + m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, agent); + m_commsProvider.InterRegion.ExpectAvatarCrossing(regionHandle, avatar.ControllingClient.AgentId, position, false); + AgentCircuitData circuitdata = avatar.ControllingClient.RequestClientInfo(); + string capsPath = Util.GetCapsURL(avatar.ControllingClient.AgentId); + avatar.ControllingClient.SendRegionTeleport(regionHandle, 13, reg.ExternalEndPoint, 4, (1 << 4), capsPath); + avatar.MakeChildAgent(); + } + } + } + + /// + /// + /// + /// + /// + /// + public bool InformNeighbourOfCrossing(ulong regionhandle, LLUUID agentID, LLVector3 position, bool isFlying) + { + return m_commsProvider.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position, isFlying); + } + + public void CloseAgentConnection(ScenePresence presence) + { + throw new Exception("The method or operation is not implemented."); + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index d0edff3878..637e090d09 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -260,6 +260,7 @@ namespace OpenSim.Region.Environment.Scenes public SceneObjectGroup ParentGroup { get { return m_parentGroup; } + } #region Constructors diff --git a/OpenSim/Region/Examples/SimpleApp/MyWorld.cs b/OpenSim/Region/Examples/SimpleApp/MyWorld.cs index c616f6af95..e65868843c 100644 --- a/OpenSim/Region/Examples/SimpleApp/MyWorld.cs +++ b/OpenSim/Region/Examples/SimpleApp/MyWorld.cs @@ -42,10 +42,10 @@ namespace SimpleApp { private List m_avatars; - public MyWorld(RegionInfo regionInfo, AgentCircuitManager authen, CommunicationsManager commsMan, + public MyWorld(RegionInfo regionInfo, AgentCircuitManager authen, CommunicationsManager commsMan, SceneCommunicationService sceneGridService, AssetCache assetCach, StorageManager storeMan, BaseHttpServer httpServer, ModuleLoader moduleLoader) - : base(regionInfo, authen, commsMan, assetCach, storeMan, httpServer, moduleLoader, false) + : base(regionInfo, authen, commsMan, sceneGridService, assetCach, storeMan, httpServer, moduleLoader, false) { m_avatars = new List(); } diff --git a/OpenSim/Region/Examples/SimpleApp/Program.cs b/OpenSim/Region/Examples/SimpleApp/Program.cs index b37c2ee93c..6c54d525c2 100644 --- a/OpenSim/Region/Examples/SimpleApp/Program.cs +++ b/OpenSim/Region/Examples/SimpleApp/Program.cs @@ -169,8 +169,9 @@ namespace SimpleApp protected override Scene CreateScene(RegionInfo regionInfo, StorageManager storageManager, AgentCircuitManager circuitManager) { + SceneCommunicationService sceneGridService = new SceneCommunicationService(m_commsManager); return - new MyWorld(regionInfo, circuitManager, m_commsManager, m_assetCache, storageManager, m_httpServer, + new MyWorld(regionInfo, circuitManager, m_commsManager, sceneGridService, m_assetCache, storageManager, m_httpServer, new ModuleLoader(m_log, m_config)); }