public void Remove(ISceneEntity sceneEntity) { if (!_items.Contains(sceneEntity)) throw new ItemDoesNotExistException(Resources.Message_Scene_entity_does_not_exists_in_the_stage); _items.Remove(sceneEntity); OnSceneEntityRemoved(sceneEntity); }
private double GetPriorityByDistance(IClientAPI client, ISceneEntity entity) { ScenePresence presence = m_scene.GetScenePresence(client.AgentId); if (presence != null) { // If this is an update for our own avatar give it the highest priority if (presence == entity) return 0.0; // Use the camera position for local agents and avatar position for remote agents Vector3 presencePos = (presence.IsChildAgent) ? presence.AbsolutePosition : presence.CameraPosition; // Use group position for child prims Vector3 entityPos; if (entity is SceneObjectPart) entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; else entityPos = entity.AbsolutePosition; return Vector3.DistanceSquared(presencePos, entityPos); } return double.NaN; }
public void Add(ISceneEntity sceneEntity) { if (_items.Contains(sceneEntity)) throw new ItemAlreadyExistsException(Resources.Message_Scene_entity_already_exists_in_the_stage); _items.Add(sceneEntity); OnSceneEntityAdded(sceneEntity); }
/// <summary> /// /// </summary> /// <param name="entity"></param> /// <returns>True if the entity was added to the scene graph, false if /// it was updated</returns> public bool AddOrUpdate(ISceneEntity entity) { bool added; m_syncRoot.EnterWriteLock(); try { if (!m_entityLocalIDs.ContainsKey(entity.LocalID)) { // Sanity check if (m_entityUUIDs.ContainsKey(entity.ID)) throw new ArgumentException("Cannot add entity with LocalID " + entity.LocalID + ", ID " + entity.ID + " already exists in the scene"); // Insert this entity into the scene graph, uint map, and UUID map m_entityLocalIDs.Add(entity.LocalID, entity); m_entityUUIDs.Add(entity.ID, entity); added = true; } else { added = false; } // If this is a scene presence, add/update it in the presence collection if (entity is IScenePresence) m_presences.Add(entity.ID, (IScenePresence)entity); } finally { m_syncRoot.ExitWriteLock(); } return added; }
public void PreloadSound(ISceneEntity source, UUID soundID, float radius) { m_scene.CreateInterestListEvent(new InterestListEvent( UUID.Combine(soundID, PRELOAD_EVENT_ID), PRELOAD_SOUND, source.ScenePosition, new Vector3(radius), new object[] { source, soundID }) ); }
/// <summary> /// Gets the color representation of the given entity. /// </summary> /// <returns>The color.</returns> /// <param name="entity">Entity.</param> public static Color GetColor(ISceneEntity entity) { // Build Color if (entity.InBuild) { if (entity.IsEnabled) return SceneOpenButton_InBuild_Enabled; else return SceneOpenButton_InBuild_Disabled; } return SceneOpenButton_Regular; }
public double GetUpdatePriority(IClientAPI client, ISceneEntity entity) { double priority = 0; if (entity == null) return 100000; switch (m_scene.UpdatePrioritizationScheme) { case UpdatePrioritizationSchemes.Time: priority = GetPriorityByTime(); break; case UpdatePrioritizationSchemes.Distance: priority = GetPriorityByDistance(client, entity); break; case UpdatePrioritizationSchemes.SimpleAngularDistance: priority = GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance break; case UpdatePrioritizationSchemes.FrontBack: priority = GetPriorityByFrontBack(client, entity); break; case UpdatePrioritizationSchemes.BestAvatarResponsiveness: priority = GetPriorityByBestAvatarResponsiveness(client, entity); break; default: throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); } // Adjust priority so that root prims are sent to the viewer first. This is especially important for // attachments acting as huds, since current viewers fail to display hud child prims if their updates // arrive before the root one. if (entity is SceneObjectPart) { SceneObjectPart sop = ((SceneObjectPart)entity); if (sop.IsRoot) { if (priority >= double.MinValue + m_childPrimAdjustmentFactor) priority -= m_childPrimAdjustmentFactor; } else { if (priority <= double.MaxValue - m_childPrimAdjustmentFactor) priority += m_childPrimAdjustmentFactor; } } return priority; }
public double GetUpdatePriority(IClientAPI client, ISceneEntity entity) { switch (m_scene.UpdatePrioritizationScheme) { case UpdatePrioritizationSchemes.Time: return GetPriorityByTime(); case UpdatePrioritizationSchemes.Distance: return GetPriorityByDistance(client, entity); case UpdatePrioritizationSchemes.SimpleAngularDistance: return GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance case UpdatePrioritizationSchemes.FrontBack: return GetPriorityByFrontBack(client, entity); case UpdatePrioritizationSchemes.BestAvatarResponsiveness: return GetPriorityByBestAvatarResponsiveness(client, entity); default: throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); } }
/// <summary> /// Returns the priority queue into which the update should be placed. Updates within a /// queue will be processed in arrival order. There are currently 12 priority queues /// implemented in PriorityQueue class in LLClientView. Queue 0 is generally retained /// for avatar updates. The fair queuing discipline for processing the priority queues /// assumes that the number of entities in each priority queues increases exponentially. /// So for example... if queue 1 contains all updates within 10m of the avatar or camera /// then queue 2 at 20m is about 3X bigger in space & about 3X bigger in total number /// of updates. /// </summary> public uint GetUpdatePriority(IClientAPI client, ISceneEntity entity) { // If entity is null we have a serious problem if (entity == null) { m_log.WarnFormat("[PRIORITIZER] attempt to prioritize null entity"); throw new InvalidOperationException("Prioritization entity not defined"); } // If this is an update for our own avatar give it the highest priority if (client.AgentId == entity.UUID) return 0; uint priority; // HACK return GetPriorityByBestAvatarResponsiveness(client, entity); switch (m_scene.UpdatePrioritizationScheme) { case UpdatePrioritizationSchemes.Time: priority = GetPriorityByTime(client, entity); break; case UpdatePrioritizationSchemes.Distance: priority = GetPriorityByDistance(client, entity); break; case UpdatePrioritizationSchemes.SimpleAngularDistance: priority = GetPriorityByDistance(client, entity); // TODO: Reimplement SimpleAngularDistance break; case UpdatePrioritizationSchemes.FrontBack: priority = GetPriorityByFrontBack(client, entity); break; case UpdatePrioritizationSchemes.BestAvatarResponsiveness: priority = GetPriorityByBestAvatarResponsiveness(client, entity); break; default: throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); } return priority; }
public void AddDamageToPrim(ISceneEntity entity) { }
private void DetachSingleAttachmentGroupToInventoryInternal(UUID itemID, IClientAPI remoteClient, bool fireEvent, ISceneEntity group) { if (fireEvent) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); group.DetachToInventoryPrep(); } IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence != null) { AvatarAttachments attModule = presence.RequestModuleInterface <AvatarAttachments> (); if (attModule != null) { attModule.RemoveAttachment(group); } if (attModule != null) { presence.SetAttachments(attModule.Get()); } } MainConsole.Instance.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); //Update the saved attach points if (group.RootChild.AttachedPos != group.RootChild.SavedAttachedPos || group.RootChild.SavedAttachmentPoint != group.RootChild.AttachmentPoint) { group.RootChild.SavedAttachedPos = group.RootChild.AttachedPos; group.RootChild.SavedAttachmentPoint = group.RootChild.AttachmentPoint; //Make sure we get updated group.HasGroupChanged = true; } // If an item contains scripts, it's always changed. // This ensures script state is saved on detach foreach (ISceneChildEntity p in group.ChildrenEntities()) { if (p.Inventory.ContainsScripts()) { group.HasGroupChanged = true; break; } } if (group.HasGroupChanged) { UpdateKnownItem(remoteClient, group, group.RootChild.FromUserInventoryItemID, group.OwnerID); } }
// NOTE: Call under Taint Lock void RemoveObject(ISceneEntity obj) { ParcelCounts parcelCounts; if (obj.IsAttachment) { return; } var parcelManagment = m_Scene.RequestModuleInterface <IParcelManagementModule>(); Vector3 pos = obj.AbsolutePosition; ILandObject landObject = parcelManagment.GetLandObject(pos.X, pos.Y) ?? parcelManagment.GetNearestAllowedParcel(UUID.Zero, pos.X, pos.Y); if (landObject == null) { return; } LandData landData = landObject.LandData; if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { UUID landOwner = landData.OwnerID; // check for temporary objects first if (((obj.RootChild.Flags & PrimFlags.TemporaryOnRez) != 0) || ((obj.RootChild.Flags & PrimFlags.Temporary) != 0)) { parcelCounts.Temporary -= obj.PrimCount; // do not process temporary objects further return; } foreach (ISceneChildEntity child in obj.ChildrenEntities()) { bool foundit = false; if (!parcelCounts.Objects.ContainsKey(child.UUID)) { //was not found, lets look through all the parcels foreach (ILandObject parcel in parcelManagment.AllParcels()) { landData = parcel.LandData; if (!m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { continue; } landOwner = landData.OwnerID; if (!parcelCounts.Objects.ContainsKey(child.UUID)) { continue; } foundit = true; break; } } else { foundit = true; } if (!foundit) { continue; } parcelCounts.Objects.Remove(child.UUID); if (m_SimwideCounts.ContainsKey(landOwner)) { m_SimwideCounts[landOwner] -= 1; } if (parcelCounts.Users.ContainsKey(obj.OwnerID)) { parcelCounts.Users[obj.OwnerID] -= 1; } if (landData.IsGroupOwned) { if (obj.OwnerID == landData.GroupID) { parcelCounts.Owner -= 1; } else if (obj.GroupID == landData.GroupID) { parcelCounts.Group -= 1; } else { parcelCounts.Others -= 1; } } else { if (obj.OwnerID == landData.OwnerID) { parcelCounts.Owner -= 1; } else if (obj.GroupID == landData.GroupID) { parcelCounts.Group -= 1; } else { parcelCounts.Others -= 1; } } } } }
public void LoadModuleFromArchive(byte [] data, string filePath, TarArchiveReader.TarEntryType type, IScene scene) { if (filePath.StartsWith("parcels/", StringComparison.Ordinal)) { if (!m_merge) { //Only use if we are not merging LandData parcel = new LandData(); OSD parcelData = OSDParser.DeserializeLLSDBinary(data); parcel.FromOSD((OSDMap)parcelData); m_parcels.Add(parcel); } } #region New Style Terrain Loading else if (filePath.StartsWith("newstyleterrain/", StringComparison.Ordinal)) { ITerrainModule terrainModule = scene.RequestModuleInterface <ITerrainModule> (); terrainModule.TerrainMap = ReadTerrain(data, scene); } else if (filePath.StartsWith("newstylerevertterrain/", StringComparison.Ordinal)) { ITerrainModule terrainModule = scene.RequestModuleInterface <ITerrainModule> (); terrainModule.TerrainRevertMap = ReadTerrain(data, scene); } else if (filePath.StartsWith("newstylewater/", StringComparison.Ordinal)) { ITerrainModule terrainModule = scene.RequestModuleInterface <ITerrainModule> (); terrainModule.TerrainWaterMap = ReadTerrain(data, scene); } else if (filePath.StartsWith("newstylerevertwater/", StringComparison.Ordinal)) { ITerrainModule terrainModule = scene.RequestModuleInterface <ITerrainModule> (); terrainModule.TerrainWaterRevertMap = ReadTerrain(data, scene); } #endregion #region Old Style Terrain Loading else if (filePath.StartsWith("terrain/", StringComparison.Ordinal)) { ITerrainModule terrainModule = scene.RequestModuleInterface <ITerrainModule> (); MemoryStream ms = new MemoryStream(data); terrainModule.LoadFromStream(filePath, ms, 0, 0); ms.Close(); } else if (filePath.StartsWith("revertterrain/", StringComparison.Ordinal)) { ITerrainModule terrainModule = scene.RequestModuleInterface <ITerrainModule> (); MemoryStream ms = new MemoryStream(data); terrainModule.LoadRevertMapFromStream(filePath, ms, 0, 0); ms.Close(); } else if (filePath.StartsWith("water/", StringComparison.Ordinal)) { ITerrainModule terrainModule = scene.RequestModuleInterface <ITerrainModule> (); MemoryStream ms = new MemoryStream(data); terrainModule.LoadWaterFromStream(filePath, ms, 0, 0); ms.Close(); } else if (filePath.StartsWith("revertwater/", StringComparison.Ordinal)) { ITerrainModule terrainModule = scene.RequestModuleInterface <ITerrainModule> (); MemoryStream ms = new MemoryStream(data); terrainModule.LoadWaterRevertMapFromStream(filePath, ms, 0, 0); ms.Close(); } #endregion else if (filePath.StartsWith("entities/", StringComparison.Ordinal)) { MemoryStream ms = new MemoryStream(data); ISceneEntity sceneObject = SceneEntitySerializer.SceneObjectSerializer.FromXml2Format(ref ms, scene); ms.Close(); m_groups.Add(sceneObject); } else if (filePath.StartsWith("assets/", StringComparison.Ordinal)) { if (m_loadAssets) { AssetBase asset = new AssetBase(); asset.Unpack(OSDParser.DeserializeJson(Encoding.UTF8.GetString(data))); scene.AssetService.Store(asset); } } }
/// <summary> /// Get a child prim of this group by UUID /// </summary> /// <param name="UUID"></param> /// <param name="entity"></param> /// <returns></returns> public override bool GetChildPrim(UUID UUID, out ISceneEntity entity) { entity = GetChildPart(UUID); return entity != null; }
/// <summary> /// Called when objects or attachments cross the border, or teleport, between regions. /// </summary> /// <param name="regionID"></param> /// <param name="sog"></param> /// <returns></returns> public virtual bool IncomingCreateObject(UUID regionID, ISceneEntity sog) { return(AddSceneObject(m_scene, sog)); }
/// <summary> /// Add a backup taint to the prim /// </summary> /// <param name="sceneObjectGroup"></param> public void AddPrimBackupTaint (ISceneEntity sceneObjectGroup) { lock (m_backupTaintedPrims) { if (sceneObjectGroup is SceneObjectGroup) { if (!m_backupTaintedPrims.ContainsKey(sceneObjectGroup.UUID)) m_backupTaintedPrims.Add(sceneObjectGroup.UUID, (SceneObjectGroup)sceneObjectGroup); } } }
/// <summary> /// Return the given objects to the agent given /// </summary> /// <param name="returnobjects">The objects to return</param> /// <param name="AgentId">The agent UUID that will get the inventory items for these objects</param> /// <returns></returns> public bool ReturnObjects(ISceneEntity[] returnobjects, UUID AgentId) { if (returnobjects.Length == 0) return true; //AddReturns(returnobjects[0].OwnerID, returnobjects[0].Name, returnobjects.Length, returnobjects[0].AbsolutePosition, "parcel owner return"); #if (!ISWIN) List<uint> IDs = new List<uint>(); foreach (ISceneEntity grp in returnobjects) IDs.Add(grp.LocalId); #else List<uint> IDs = returnobjects.Select(grp => grp.LocalId).ToList(); #endif IClientAPI client; m_scene.ClientManager.TryGetValue(AgentId, out client); //Its ok if the client is null, its taken care of DeRezObjects(client, IDs, returnobjects[0].RootChild.GroupID, DeRezAction.Return, UUID.Zero); return true; }
/// <summary> /// Move this group from inside of another group into the Scene as a full member /// This does not reset IDs so that it is updated correctly in the client /// </summary> /// <param name="entity"></param> public void DelinkPartToScene(ISceneEntity entity) { //Force the prim to backup now that it has been added entity.ForcePersistence(); //Tell the entity that they are being added to a scene entity.RebuildPhysicalRepresentation(true, null); //Now save the entity that we have AddEntity(entity, false); }
/// <summary> /// THIS IS TO ONLY BE CALLED WHEN AN OBJECT UUID IS UPDATED!!! /// This method is HIGHLY unsafe and destroys the integrity of the checks above! /// This is NOT to be used lightly! Do NOT use this unless you have to! /// </summary> /// <param name="entity"></param> /// <param name="newID">new UUID to set the root part to</param> public void UpdateEntity(ISceneEntity entity, UUID newID) { RemoveEntity(entity); //Set it to the root so that we don't create an infinite loop as the ONLY place this should be being called is from the setter in SceneObjectGroup.UUID entity.RootChild.UUID = newID; AddEntity(entity, false); }
public void SendEntityFullUpdateImmediate(ISceneEntity avatar) { }
/// <summary> /// Add the Entity to the Scene and back it up /// </summary> /// <param name="entity"></param> /// <returns></returns> public bool AddPrimToScene(ISceneEntity entity) { //Reset the entity IDs ResetEntityIDs(entity); //Force the prim to backup now that it has been added entity.ForcePersistence(); //Tell the entity that they are being added to a scene entity.AttachToScene(m_parentScene); //Now save the entity that we have return AddEntity(entity, false); }
private uint ComputeDistancePriority(IClientAPI client, ISceneEntity entity, bool useFrontBack) { // Get this agent's position ScenePresence presence = m_scene.GetScenePresence(client.AgentId); if (presence == null) { // this shouldn't happen, it basically means that we are prioritizing // updates to send to a client that doesn't have a presence in the scene // seems like there's race condition here... // m_log.WarnFormat("[PRIORITIZER] attempt to use agent {0} not in the scene",client.AgentId); // throw new InvalidOperationException("Prioritization agent not defined"); return(PriorityQueue.NumberOfQueues - 1); } // Use group position for child prims, since we are putting child prims in // the same queue with the root of the group, the root prim (which goes into // the queue first) should always be sent first, no need to adjust child prim // priorities Vector3 entityPos = entity.AbsolutePosition; if (entity is SceneObjectPart) { SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup; if (group != null) { entityPos = group.AbsolutePosition; } } // Use the camera position for local agents and avatar position for remote agents Vector3 presencePos = (presence.IsChildAgent) ? presence.AbsolutePosition : presence.CameraPosition; // Compute the distance... double distance = Vector3.Distance(presencePos, entityPos); // And convert the distance to a priority queue, this computation gives queues // at 10, 20, 40, 80, 160, 320, 640, and 1280m uint pqueue = PriorityQueue.NumberOfImmediateQueues; uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues; for (int i = 0; i < queues - 1; i++) { if (distance < 10 * Math.Pow(2.0, i)) { break; } pqueue++; } // If this is a root agent, then determine front & back // Bump up the priority queue (drop the priority) for any objects behind the avatar if (useFrontBack && !presence.IsChildAgent) { // Root agent, decrease priority for objects behind us Vector3 camPosition = presence.CameraPosition; Vector3 camAtAxis = presence.CameraAtAxis; // Plane equation float d = -Vector3.Dot(camPosition, camAtAxis); float p = Vector3.Dot(camAtAxis, entityPos) + d; if (p < 0.0f) { pqueue++; } } return(pqueue); }
/// <summary> /// Check all the localIDs in this group to make sure that they have not been used previously /// </summary> /// <param name="group"></param> public void CheckAllocationOfLocalIds(ISceneEntity group) { foreach (ISceneChildEntity part in group.ChildrenEntities()) { if (part.LocalId != 0) CheckAllocationOfLocalId(part.LocalId); } }
/// <summary> /// Create the path used to store an object in an OpenSim Archive. /// </summary> /// <param name="sog"></param> /// <returns></returns> public static string CreateObjectPath(ISceneEntity sog) { return(ArchiveConstants.CreateOarObjectPath(sog.Name, sog.UUID, sog.AbsolutePosition)); }
public void TriggerSignificantObjectMovement (ISceneEntity group) { SignificantObjectMovement handlerSignificantObjectMovement = OnSignificantObjectMovement; if (handlerSignificantObjectMovement != null) { foreach (SignificantObjectMovement d in handlerSignificantObjectMovement.GetInvocationList ()) { try { d (group); } catch (Exception e) { m_log.ErrorFormat ( "[EVENT MANAGER]: Delegate for TriggerSignificantObjectMovement failed - continuing. {0} {1}", e.ToString (), e.StackTrace); } } } }
public void StopFlying(ISceneEntity presence) { }
// this is diferente from SendTerseUpdateToClient // this sends bypassing entities updates public void SendAgentTerseUpdate(ISceneEntity p) { ControllingClient.SendAgentTerseUpdate(p); }
public string SerializeGroupToXml2(ISceneEntity grp) { return(SceneEntitySerializer.SceneObjectSerializer.ToXml2Format(grp)); }
/// <summary> /// Add this child to the group and set the parent ID's, /// but do NOT set the link number, /// the caller wants to deal with it if they call this /// </summary> /// <param name="child"></param> /// <returns></returns> public override bool LinkChild(ISceneEntity child) { lock (m_partsLock) { if (child is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart)child; //Root part is first if (m_partsList.Count == 0) { m_rootPart = part; } //Set the parent prim part.SetParent(this); part.SetParentLocalId(m_rootPart.LocalId); if (!m_parts.ContainsKey(child.UUID)) { m_parts.Add(child.UUID, part); m_partsList.Add(part); } m_partsList.Sort(m_scene.SceneGraph.linkSetSorter); return true; } } return false; }
public bool DistanceCulling(IScenePresence client, IEntity entity, IScene scene) { float DD = client.DrawDistance; if (DD < 32) //Limit to a small distance { DD = 32; } if (DD > scene.RegionInfo.RegionSizeX && DD > scene.RegionInfo.RegionSizeY) { return(true); //Its larger than the region, no culling check even necessary } Vector3 posToCheckFrom = client.GetAbsolutePosition(); if (client.IsChildAgent) { /*if (m_cachedXOffset == 0 && m_cachedYOffset == 0) //Not found yet * { * int RegionLocX, RegionLocY; * Util.UlongToInts(client.RootAgentHandle, out RegionLocX, out RegionLocY); * m_cachedXOffset = scene.RegionInfo.RegionLocX - RegionLocX; * m_cachedYOffset = scene.RegionInfo.RegionLocY - RegionLocY; * } * //We need to add the offset so that we can check from the right place in child regions * if (m_cachedXOffset < 0) * posToCheckFrom.X = scene.RegionInfo.RegionSizeX - * (scene.RegionInfo.RegionSizeX + client.AbsolutePosition.X + m_cachedXOffset); * if (m_cachedYOffset < 0) * posToCheckFrom.Y = scene.RegionInfo.RegionSizeY - * (scene.RegionInfo.RegionSizeY + client.AbsolutePosition.Y + m_cachedYOffset); * if (m_cachedXOffset > scene.RegionInfo.RegionSizeX) * posToCheckFrom.X = scene.RegionInfo.RegionSizeX - * (scene.RegionInfo.RegionSizeX - (client.AbsolutePosition.X + m_cachedXOffset)); * if (m_cachedYOffset > scene.RegionInfo.RegionSizeY) * posToCheckFrom.Y = scene.RegionInfo.RegionSizeY - * (scene.RegionInfo.RegionSizeY - (client.AbsolutePosition.Y + m_cachedYOffset));*/ } Vector3 entityPosToCheckFrom = Vector3.Zero; bool doHeavyCulling = false; if (entity is ISceneEntity) { doHeavyCulling = true; //We need to check whether this object is an attachment, and if so, set it so that we check from the avatar's // position, rather than from the offset of the attachment ISceneEntity sEntity = (ISceneEntity)entity; if (sEntity.RootChild.IsAttachment) { IScenePresence attachedAvatar = scene.GetScenePresence(sEntity.RootChild.AttachedAvatar); if (attachedAvatar != null) { entityPosToCheckFrom = attachedAvatar.AbsolutePosition; } } else { entityPosToCheckFrom = sEntity.RootChild.GetGroupPosition(); } } else if (entity is IScenePresence) { //We need to check whether this presence is sitting on anything, so that we can check from the object's // position, rather than the offset position of the object that the avatar is sitting on IScenePresence pEntity = (IScenePresence)entity; if (pEntity.Sitting) { ISceneChildEntity sittingEntity = scene.GetSceneObjectPart(pEntity.SittingOnUUID); if (sittingEntity != null) { entityPosToCheckFrom = sittingEntity.GetGroupPosition(); } } else { entityPosToCheckFrom = pEntity.GetAbsolutePosition(); } } //If the distance is greater than the clients draw distance, its out of range if (Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom) > DD * DD) //Use squares to make it faster than having to do the sqrt { if (!doHeavyCulling) { return(false); //Don't do the hardcore checks } ISceneEntity childEntity = (entity as ISceneEntity); if (childEntity != null && HardCullingCheck(childEntity)) { #region Side culling check (X, Y, Z) plane checks if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(childEntity.OOBsize.X, 0, 0)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(childEntity.OOBsize.X, 0, 0)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(0, childEntity.OOBsize.Y, 0)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(0, childEntity.OOBsize.Y, 0)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(0, 0, childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(0, 0, childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } #endregion #region Corner checks ((x,y),(-x,-y),(x,-y),(-x,y), (y,z),(-y,-z),(y,-z),(-y,z), (x,z),(-x,-z),(x,-z),(-x,z)) if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(childEntity.OOBsize.X, childEntity.OOBsize.Y, 0)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(childEntity.OOBsize.X, childEntity.OOBsize.Y, 0)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(childEntity.OOBsize.X, -childEntity.OOBsize.Y, 0)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(childEntity.OOBsize.X, -childEntity.OOBsize.Y, 0)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(0, childEntity.OOBsize.Y, childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(0, childEntity.OOBsize.Y, childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(0, childEntity.OOBsize.Y, -childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(0, childEntity.OOBsize.Y, -childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom + new Vector3(-childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } if ( Vector3.DistanceSquared(posToCheckFrom, entityPosToCheckFrom - new Vector3(-childEntity.OOBsize.X, 0, childEntity.OOBsize.Z)) < DD * DD) //Use squares to make it faster than having to do the sqrt { return(true); } #endregion } return(false); } return(true); }
// NOTE: Call under Taint Lock void AddObject(ISceneEntity obj) { ParcelCounts parcelCounts; if (obj.IsAttachment) { return; } Vector3 pos = obj.AbsolutePosition; var landObject = m_Scene.RequestModuleInterface <IParcelManagementModule>().GetLandObject(pos.X, pos.Y); if (landObject == null) { return; } LandData landData = landObject.LandData; if (m_ParcelCounts.TryGetValue(landData.GlobalID, out parcelCounts)) { UUID landOwner = landData.OwnerID; parcelCounts.Objects[obj.UUID] = obj; // check for temporary objects first if (((obj.RootChild.Flags & PrimFlags.TemporaryOnRez) != 0) || ((obj.RootChild.Flags & PrimFlags.Temporary) != 0)) { parcelCounts.Temporary += obj.PrimCount; // do not add temporary counts further return; } if (!m_SimwideCounts.ContainsKey(landOwner)) { m_SimwideCounts.Add(landOwner, 0); } m_SimwideCounts[landOwner] += obj.PrimCount; if (parcelCounts.Users.ContainsKey(obj.OwnerID)) { parcelCounts.Users[obj.OwnerID] += obj.PrimCount; } else { parcelCounts.Users[obj.OwnerID] = obj.PrimCount; } if (landData.IsGroupOwned) { if (obj.OwnerID == landData.GroupID) { parcelCounts.Owner += obj.PrimCount; } else if (obj.GroupID == landData.GroupID) { parcelCounts.Group += obj.PrimCount; } else { parcelCounts.Others += obj.PrimCount; } } else { if (obj.OwnerID == landData.OwnerID) { parcelCounts.Owner += obj.PrimCount; } else if (obj.GroupID == landData.GroupID) { parcelCounts.Group += obj.PrimCount; } else { parcelCounts.Others += obj.PrimCount; } } } }
public ISceneEntity RezSingleAttachmentFromInventory( IClientAPI remoteClient, UUID itemID, UUID assetID, int AttachmentPt, bool updateUUIDs) { MainConsole.Instance.DebugFormat( "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); IInventoryAccessModule invAccess = m_scene.RequestModuleInterface <IInventoryAccessModule>(); if (invAccess != null) { InventoryItemBase item = null; ISceneEntity objatt = assetID == UUID.Zero ? invAccess.CreateObjectFromInventory(remoteClient, itemID, out item) : invAccess.CreateObjectFromInventory(remoteClient, itemID, assetID, null); if (objatt != null) { #region Set up object for attachment status if (item != null) { assetID = item.AssetID; // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. objatt.RootChild.Name = item.Name; objatt.RootChild.Description = item.Description; } objatt.RootChild.Flags |= PrimFlags.Phantom; objatt.RootChild.IsAttachment = true; objatt.SetFromItemID(itemID, assetID); List <ISceneChildEntity> partList = new List <ISceneChildEntity>(objatt.ChildrenEntities()); foreach (ISceneChildEntity part in partList) { part.AttachedAvatar = remoteClient.AgentId; } objatt.SetGroup(remoteClient.ActiveGroupId, remoteClient.AgentId, false); if (objatt.RootChild.OwnerID != remoteClient.AgentId) { //Need to kill the for sale here objatt.RootChild.ObjectSaleType = 0; objatt.RootChild.SalePrice = 10; if (m_scene.Permissions.PropagatePermissions()) { if (item == null) { item = m_scene.InventoryService.GetItem(remoteClient.AgentId, itemID); } if (item == null) { return(null); } if ((item.CurrentPermissions & 8) != 0) { foreach (ISceneChildEntity part in partList) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } objatt.ApplyNextOwnerPermissions(); } } foreach (ISceneChildEntity part in partList) { if (part.OwnerID != remoteClient.AgentId) { part.LastOwnerID = part.OwnerID; part.OwnerID = remoteClient.AgentId; part.Inventory.ChangeInventoryOwner(remoteClient.AgentId); } } objatt.RootChild.TrimPermissions(); objatt.RootChild.IsAttachment = true; objatt.IsDeleted = false; //Update the ItemID with the new item objatt.SetFromItemID(itemID, assetID); //We also have to reset the IDs so that it doesn't have the same IDs as one inworld (possibly)! ISceneEntity[] atts = GetAttachmentsForAvatar(remoteClient.AgentId); foreach (var obj in atts) { if (obj.UUID == objatt.UUID) { updateUUIDs = false; //If the user is already wearing it, don't readd } } bool forceUpdateOnNextDeattach = false; try { bool foundDuplicate = false; foreach (var obj in atts) { if (obj.RootChild.FromUserInventoryItemID == objatt.RootChild.FromUserInventoryItemID) { foundDuplicate = true; } } IEntity e; if (!m_scene.SceneGraph.TryGetEntity(objatt.UUID, out e)) //if (updateUUIDs) { foreach (var prim in objatt.ChildrenEntities()) { prim.LocalId = 0; } bool success = m_scene.SceneGraph.RestorePrimToScene(objatt, false); if (!success) { MainConsole.Instance.Error("[AttachmentModule]: Failed to add attachment " + objatt.Name + " for user " + remoteClient.Name + "!"); return(null); } } else { if (!foundDuplicate) { //If the user has information stored about this object, we need to force updating next time if (m_scene.SceneGraph.AddPrimToScene(objatt)) { forceUpdateOnNextDeattach = true; } } else { if (e as ISceneEntity != null) { (e as ISceneEntity).ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); } return(e as ISceneEntity); //It was already added } } } catch { } //If we updated the attachment, we need to save the change IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence != null) { FindAttachmentPoint(remoteClient, objatt.LocalId, objatt, AttachmentPt, assetID, forceUpdateOnNextDeattach, false); } else { objatt = null; //Presence left, kill the attachment } #endregion } else { MainConsole.Instance.WarnFormat( "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", itemID, remoteClient.Name, AttachmentPt); } return(objatt); } return(null); }
/// <summary> /// Add a backup taint to the prim /// </summary> /// <param name="sceneObjectGroup"></param> public void AddPrimBackupTaint(ISceneEntity sceneObjectGroup) { //Tell the database that something has changed m_scene.SimulationDataService.Tainted(); }
/// <summary> /// Attach the object to the avatar /// </summary> /// <param name="remoteClient">The client that is having the attachment done</param> /// <param name="localID">The localID (SceneObjectPart) that is being attached (for the attach script event)</param> /// <param name="group">The group (SceneObjectGroup) that is being attached</param> /// <param name="AttachmentPt">The point to where the attachment will go</param> /// <param name="assetID" /> /// <param name="forceUpdatePrim">Force updating of the prim the next time the user attempts to deattach it</param> /// <param name="isTempAttach">Is a temporary attachment</param> protected void FindAttachmentPoint(IClientAPI remoteClient, uint localID, ISceneEntity group, int AttachmentPt, UUID assetID, bool forceUpdatePrim, bool isTempAttach) { //Make sure that we arn't over the limit of attachments ISceneEntity[] attachments = GetAttachmentsForAvatar(remoteClient.AgentId); if (attachments.Length + 1 > m_maxNumberOfAttachments) { //Too many remoteClient.SendAgentAlertMessage( "You are wearing too many attachments. Take one off to attach this object", false); return; } Vector3 attachPos = group.GetAttachmentPos(); bool hasMultipleAttachmentsSet = (AttachmentPt & 0x7f) != 0 || AttachmentPt == 0; if (!m_allowMultipleAttachments) { hasMultipleAttachmentsSet = false; } AttachmentPt &= 0x7f; //Disable it! Its evil! //Did the attachment change position or attachment point? bool changedPositionPoint = false; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. //Simplier terms: the attachment point changed, set it to the default 0,0,0 location if (AttachmentPt != 0 && AttachmentPt != (group.GetAttachmentPoint() & 0x7f)) { attachPos = Vector3.Zero; changedPositionPoint = true; } else { // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = group.GetSavedAttachmentPoint() & 0x7f; attachPos = group.GetAttachmentPos(); } //Check state afterwards... use the newer GetSavedAttachmentPoint and Pos above first if (AttachmentPt == 0) { // Check object for older stored attachment point AttachmentPt = group.RootChild.Shape.State & 0x7f; } // if we still didn't find a suitable attachment point, force it to the default //This happens on the first time an avatar 'wears' an object if (AttachmentPt == 0) { // Stick it on right hand with Zero Offset from the attachment point. AttachmentPt = (int)AttachmentPoint.RightHand; //Default location attachPos = Vector3.Zero; changedPositionPoint = true; } } MainConsole.Instance.DebugFormat( "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2} localID {3}", group.Name, remoteClient.Name, AttachmentPt, group.LocalId); //Update where we are put group.SetAttachmentPoint((byte)AttachmentPt); //Fix the position with the one we found group.AbsolutePosition = attachPos; // Remove any previous attachments IScenePresence presence = m_scene.GetScenePresence(remoteClient.AgentId); if (presence == null) { return; } UUID itemID = UUID.Zero; //Check for multiple attachment bits and whether we should remove the old if (!hasMultipleAttachmentsSet) { foreach (ISceneEntity grp in attachments) { if (grp.GetAttachmentPoint() == (byte)AttachmentPt) { itemID = grp.RootChild.FromUserInventoryItemID; break; } } if (itemID != UUID.Zero) { DetachSingleAttachmentToInventory(itemID, remoteClient); } } itemID = group.RootChild.FromUserInventoryItemID; group.RootChild.AttachedAvatar = presence.UUID; List <ISceneChildEntity> parts = group.ChildrenEntities(); foreach (ISceneChildEntity t in parts) { t.AttachedAvatar = presence.UUID; } if (group.RootChild.PhysActor != null) { m_scene.PhysicsScene.DeletePrim(group.RootChild.PhysActor); group.RootChild.PhysActor = null; } group.RootChild.AttachedPos = attachPos; group.RootChild.IsAttachment = true; group.AbsolutePosition = attachPos; group.RootChild.SetParentLocalId(presence.LocalId); group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); // Killing it here will cause the client to deselect it // It then reappears on the avatar, deselected // through the full update below if (group.IsSelected) { foreach (ISceneChildEntity part in group.ChildrenEntities()) { part.CreateSelected = true; } } //NOTE: This MUST be here, otherwise we limit full updates during attachments when they are selected and it will block the first update. // So until that is changed, this MUST stay. The client will instantly reselect it, so this value doesn't stay borked for long. group.IsSelected = false; if (!isTempAttach) { if (itemID == UUID.Zero) { //Delete the object inworld to inventory List <ISceneEntity> groups = new List <ISceneEntity>(1) { group }; IInventoryAccessModule inventoryAccess = m_scene.RequestModuleInterface <IInventoryAccessModule>(); if (inventoryAccess != null) { inventoryAccess.DeleteToInventory(DeRezAction.AcquireToUserInventory, UUID.Zero, groups, remoteClient.AgentId, out itemID); } } else { //it came from an item, we need to start the scripts // Fire after attach, so we don't get messy perms dialogs. group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero, false); } if (UUID.Zero == itemID) { MainConsole.Instance.Error( "[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID."); remoteClient.SendAgentAlertMessage( "Unable to save attachment. Error inventory item ID.", false); return; } // XXYY!! if (assetID == UUID.Zero) { assetID = m_scene.InventoryService.GetItemAssetID(remoteClient.AgentId, itemID); //Update the ItemID with the new item group.SetFromItemID(itemID, assetID); } } else { // Fire after attach, so we don't get messy perms dialogs. group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero, false); group.RootChild.FromUserInventoryItemID = UUID.Zero; } AvatarAttachments attPlugin = presence.RequestModuleInterface <AvatarAttachments>(); if (attPlugin != null) { attPlugin.AddAttachment(group); presence.SetAttachments(attPlugin.Get()); if (!isTempAttach) { IAvatarAppearanceModule appearance = presence.RequestModuleInterface <IAvatarAppearanceModule>(); appearance.Appearance.SetAttachments(attPlugin.Get()); AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); } } // In case it is later dropped again, don't let // it get cleaned up group.RootChild.RemFlag(PrimFlags.TemporaryOnRez); group.HasGroupChanged = changedPositionPoint || forceUpdatePrim; //Now recreate it so that it is selected group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); m_scene.EventManager.TriggerOnAttach(localID, group.RootChild.FromUserInventoryItemID, remoteClient.AgentId); }
private void AddEntityToParcel(ISceneEntity entity) { // Ignore avatars if (entity is IScenePresence) { return; } // Only track root entities if (entity is ILinkable && ((ILinkable)entity).Parent != null) { return; } // NOTE: We can safely use RelativePosition instead of ScenePosition here since we only // deal with root entities SceneParcel parcel; if (TryGetParcel(entity.RelativePosition, out parcel)) { bool removeOld = false; lock (parcel.ParcelEntities) { if (!parcel.ParcelEntities.ContainsKey(entity.ID)) { // Add this entity to the new parcel parcel.ParcelEntities.Add(entity.ID, entity); // Remove this entity from the previous parcel if a last significant // position is set removeOld = (entity.LastSignificantPosition != Vector3.Zero); } } if (removeOld) { bool removed = false; SceneParcel oldParcel; if (TryGetParcel(entity.LastSignificantPosition, out oldParcel)) { lock (oldParcel.ParcelEntities) removed = oldParcel.ParcelEntities.Remove(entity.ID); } #region Plan B if (!removed) { m_log.Debug("Doing a deep search for the previous parcel of entity " + entity.ID); m_parcels.ForEach( delegate(SceneParcel p) { lock (p.ParcelEntities) { if (p.ParcelEntities.Remove(entity.ID)) { removed = true; } } } ); if (!removed) { m_log.Warn("Deep search for previous parcel of entity " + entity.ID + " failed"); } } #endregion Plan B } } }
public void SendEntityFullUpdateImmediate(ISceneEntity ent) { }
public virtual void TriggerSound( UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) { bool LocalOnly = false; ILandObject ILO = null; IParcelManagementModule parcelManagement = m_scene.RequestModuleInterface <IParcelManagementModule>(); if (parcelManagement != null) { ILO = parcelManagement.GetLandObject(position.X, position.Y); if (ILO != null) //Check only if null, otherwise this breaks mega-regions { LocalOnly = (ILO.LandData.Flags & (uint)ParcelFlags.SoundLocal) == (uint)ParcelFlags.SoundLocal; } } ISceneChildEntity part = m_scene.GetSceneObjectPart(objectID); if (part == null) { IScenePresence sp; if (!m_scene.TryGetScenePresence(objectID, out sp)) { return; } } else { ISceneEntity grp = part.ParentEntity; if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) { objectID = ownerID; parentID = ownerID; } } m_scene.ForEachScenePresence(delegate(IScenePresence sp) { if (Cones.Count != 0) { foreach (ConeOfSilence CS in Cones.Values) { if (Util.GetDistanceTo(sp.AbsolutePosition, CS.Position) > CS.Radius) { // Presence is outside of the Cone of silence if (Util.GetDistanceTo(CS.Position, position) < CS.Radius) { //Sound was triggered inside the cone, but avatar is outside continue; } } else { // Avatar is inside the cone of silence if (Util.GetDistanceTo(CS.Position, position) > CS.Radius) { //Sound was triggered outside of the cone, but avatar is inside of the cone. continue; } } } } if (sp.IsChildAgent) { return; } float dis = (float)Util.GetDistanceTo(sp.AbsolutePosition, position); if (dis > 100.0f) // Max audio distance { return; } //Check to see if the person is local and the av is in the same parcel if (LocalOnly && sp.CurrentParcelUUID != ILO.LandData.GlobalID) { return; } // Scale by distance float thisSPGain; if (radius == 0) { thisSPGain = (float)(gain * ((100.0f - dis) / 100.0f)); } else { thisSPGain = (float)(gain * ((radius - dis) / radius)); } sp.ControllingClient.SendTriggeredSound( soundId, ownerID, objectID, parentID, handle, position, thisSPGain); }); }
public void SendEntityTerseUpdateImmediate(ISceneEntity ent) { }
/// <summary> /// Delinks the object from the group in the EntityManager /// </summary> /// <param name="entity"></param> /// <param name="part"></param> /// <returns></returns> public bool DeLinkPartFromEntity(ISceneEntity entity, ISceneChildEntity part) { //Remove the entity so that we can rebuild RemoveEntity(entity); bool RetVal = entity.RemoveChild(part); AddEntity(entity, false); //Now that everything is linked, destroy the undo states because it will fry the object otherwise entity.ClearUndoState(); return RetVal; }
public RegionData LoadBackup(string file) { if (!File.Exists(file)) { return(null); } var stream = ArchiveHelpers.GetStream(file); if (stream == null) { return(null); } GZipStream m_loadStream = new GZipStream(stream, CompressionMode.Decompress); TarArchiveReader reader = new TarArchiveReader(m_loadStream); List <uint> foundLocalIDs = new List <uint>(); RegionData regiondata = new RegionData(); regiondata.Init(); byte[] data; string filePath; TarArchiveReader.TarEntryType entryType; System.Collections.Concurrent.ConcurrentQueue <byte[]> groups = new System.Collections.Concurrent.ConcurrentQueue <byte[]>(); //Load the archive data that we need while ((data = reader.ReadEntry(out filePath, out entryType)) != null) { if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) { continue; } if (filePath.StartsWith("parcels/")) { //Only use if we are not merging LandData parcel = new LandData(); OSD parcelData = OSDParser.DeserializeLLSDBinary(data); parcel.FromOSD((OSDMap)parcelData); if (parcel.OwnerID != UUID.Parse("05948863-b678-433e-87a4-e44d17678d1d")) { //The default owner of the 'default' region regiondata.Parcels.Add(parcel); } } else if (filePath.StartsWith("newstyleterrain/")) { regiondata.Terrain = data; } else if (filePath.StartsWith("newstylerevertterrain/")) { regiondata.RevertTerrain = data; } else if (filePath.StartsWith("newstylewater/")) { regiondata.Water = data; } else if (filePath.StartsWith("newstylerevertwater/")) { regiondata.RevertWater = data; } else if (filePath.StartsWith("entities/")) { groups.Enqueue(data); } else if (filePath.StartsWith("regioninfo/")) { RegionInfo info = new RegionInfo(); info.FromOSD((OSDMap)OSDParser.DeserializeLLSDBinary(data)); regiondata.RegionInfo = info; } data = null; } m_loadStream.Close(); m_loadStream = null; int threadCount = groups.Count > 16 ? 16 : groups.Count; System.Threading.Thread[] threads = new System.Threading.Thread[threadCount]; for (int i = 0; i < threadCount; i++) { threads[i] = new System.Threading.Thread(() => { byte[] groupData; while (groups.TryDequeue(out groupData)) { MemoryStream ms = new MemoryStream(groupData); ISceneEntity sceneObject = SceneEntitySerializer.SceneObjectSerializer .FromXml2Format(ref ms, null); ms.Close(); ms = null; data = null; if (sceneObject != null) { foreach ( ISceneChildEntity part in sceneObject.ChildrenEntities()) { lock (foundLocalIDs) { if ( !foundLocalIDs.Contains( part.LocalId)) { foundLocalIDs.Add(part.LocalId); } else { part.LocalId = 0; } //Reset it! Only use it once! } } regiondata.Groups.Add( sceneObject as SceneObjectGroup); } } }); threads[i].Start(); } for (int i = 0; i < threadCount; i++) { threads[i].Join(); } foundLocalIDs.Clear(); return(regiondata); }
/// <summary> /// Get this prim ready to add to the scene /// </summary> /// <param name="entity"></param> public void PrepPrimForAdditionToScene(ISceneEntity entity) { ResetEntityIDs(entity); }
public void SendObjectPropertiesFamilyData(ISceneEntity Entity, uint RequestFlags) { }
/// <summary> /// Add the Entity to the Scene and back it up, but do NOT reset its ID's /// </summary> /// <param name="entity"></param> /// <param name="force"></param> /// <returns></returns> public bool RestorePrimToScene(ISceneEntity entity, bool force) { List<ISceneChildEntity> children = entity.ChildrenEntities(); //Sort so that we rebuild in the same order and the root being first children.Sort(LinkSetSorter); entity.ClearChildren(); foreach (ISceneChildEntity child in children) { if (child.LocalId == 0) child.LocalId = AllocateLocalId(); if (((SceneObjectPart) child).PhysActor != null) { ((SceneObjectPart) child).PhysActor.LocalID = child.LocalId; ((SceneObjectPart) child).PhysActor.UUID = child.UUID; } child.Flags &= ~PrimFlags.Scripted; child.TrimPermissions(); entity.AddChild(child, child.LinkNum); } //Tell the entity that they are being added to a scene entity.AttachToScene(m_parentScene); //Now save the entity that we have bool success = AddEntity(entity, false); if (force && !success) { IBackupModule backup = m_parentScene.RequestModuleInterface<IBackupModule>(); backup.DeleteSceneObjects(new ISceneEntity[1] {entity}, false, true); return RestorePrimToScene(entity, false); } return success; }
public void SendObjectPropertiesReply(ISceneEntity entity) { }
/// <summary> /// Reset all of the UUID's, localID's, etc in this group (includes children) /// </summary> /// <param name="entity"></param> private void ResetEntityIDs(ISceneEntity entity) { List<ISceneChildEntity> children = entity.ChildrenEntities(); //Sort so that we rebuild in the same order and the root being first children.Sort(LinkSetSorter); entity.ClearChildren(); foreach (ISceneChildEntity child in children) { UUID oldID = child.UUID; child.ResetEntityIDs(); entity.AddChild(child, child.LinkNum); } //This clears the xml file, which will need rebuilt now that we have changed the UUIDs entity.HasGroupChanged = true; foreach (ISceneChildEntity child in children) { if (!child.IsRoot) { child.SetParentLocalId(entity.RootChild.LocalId); } } }
public void SendAgentTerseUpdate(ISceneEntity presence) { }
public ISceneEntity CreateEntity( ISceneEntity baseEntity, UUID ownerID, UUID groupID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) { if (Array.IndexOf(creationCapabilities, (PCode) shape.PCode) < 0) { MainConsole.Instance.DebugFormat("[VEGETATION]: PCode {0} not handled by {1}", shape.PCode, Name); return null; } ISceneChildEntity rootPart = baseEntity.GetChildPart(baseEntity.UUID); // if grass or tree, make phantom //rootPart.TrimPermissions(); rootPart.AddFlag(PrimFlags.Phantom); if (rootPart.Shape.PCode != (byte) PCode.Grass) AdaptTree(ref shape); m_scene.SceneGraph.AddPrimToScene(baseEntity); baseEntity.SetGroup(groupID, ownerID, true); baseEntity.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); return baseEntity; }
public void SendPartPhysicsProprieties(ISceneEntity entity) { }
public void TriggerObjectBeingRemovedFromScene (ISceneEntity obj) { ObjectBeingRemovedFromScene handlerObjectBeingRemovedFromScene = OnObjectBeingRemovedFromScene; if (handlerObjectBeingRemovedFromScene != null) { foreach (ObjectBeingRemovedFromScene d in handlerObjectBeingRemovedFromScene.GetInvocationList ()) { try { d (obj); } catch (Exception e) { m_log.ErrorFormat ( "[EVENT MANAGER]: Delegate for TriggerObjectBeingRemovedFromScene failed - continuing. {0} {1}", e.ToString (), e.StackTrace); } } } }
public void SendPartFullUpdate(ISceneEntity ent, uint?parentID) { }
/// <summary> /// Synchronously delete the objects from the scene. /// This does send kill object updates and resets the parcel prim counts. /// </summary> /// <param name="groups"></param> /// <param name="DeleteScripts"></param> /// <returns></returns> public bool DeleteSceneObjects (ISceneEntity[] groups, bool DeleteScripts) { List<SceneObjectPart> parts = new List<SceneObjectPart>(); foreach (ISceneEntity grp in groups) { SceneObjectGroup group = grp as SceneObjectGroup; if (grp == null) continue; //if (group.IsAttachment) // continue; parts.AddRange(group.ChildrenList); DeleteSceneObject(group, true, true); } m_scene.ForEachScenePresence(delegate(IScenePresence avatar) { avatar.ControllingClient.SendKillObject(m_scene.RegionInfo.RegionHandle, parts.ToArray()); }); return true; }
public void SendCachedTextureResponse(ISceneEntity avatar, int serial, List <CachedTextureResponseArg> cachedTextures) { }
//TODO - add more scene element tests private void TestLoadGeometry(ISceneEntity sceneEntity) { _stage.Add(sceneEntity); _dataAdapter.EntityFolderPath = _stageFolderPath; _dataAdapter.Save(_stage); var actionResult = _dataAdapter.Load(_stage.Name); Assert.IsTrue(actionResult.Success); var loadedStage = actionResult.Value; Assert.AreEqual(1, loadedStage.Items.Count); var loadedGeometry = loadedStage.Items[0].Geometry; Assert.IsNotNull(loadedGeometry); Assert.AreEqual(sceneEntity.Geometry.GetType(), loadedGeometry.GetType()); Assert.IsTrue(GeometryEqualityHelper.SceneElementEqual(sceneEntity.Geometry, loadedGeometry)); }
public void SendAvatarDataImmediate(ISceneEntity avatar) { }
/// <summary> /// Get a child prim of this group by LocalID /// </summary> /// <param name="LocalID"></param> /// <param name="entity"></param> /// <returns></returns> public override bool GetChildPrim(uint LocalID, out ISceneEntity entity) { entity = GetChildPart(LocalID); return entity != null; }
public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) { }
/// <summary> /// Add a child to the group, set the parent id's and then set the link number /// </summary> /// <param name="child"></param> /// <returns></returns> public override bool AddChild(ISceneEntity child, int linkNum) { lock (m_partsLock) { if (child is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart)child; //Root part is first if (m_partsList.Count == 0) { m_rootPart = part; } //Set the parent prim part.SetParent(this); if (m_rootPart.LocalId != 0 && !part.IsRoot) part.SetParentLocalId(m_rootPart.LocalId); else part.SetParentLocalId(0); //Fix the link num part.LinkNum = linkNum; if (!m_parts.ContainsKey(child.UUID)) { m_parts.Add(child.UUID, part); m_partsList.Add(part); } return true; } } return false; }
public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType) { ISceneChildEntity part = m_scene.GetSceneObjectPart(localID); if (part == null) { return(false); } if (part.ParentEntity == null) { return(false); } ISceneEntity group = part.ParentEntity; ILLClientInventory inventoryModule = m_scene.RequestModuleInterface <ILLClientInventory>(); switch (saleType) { case 1: // Sell as original (in-place sale) uint effectivePerms = group.GetEffectivePermissions(); if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } group.SetOwnerId(remoteClient.AgentId); group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId); if (m_scene.Permissions.PropagatePermissions()) { foreach (ISceneChildEntity child in group.ChildrenEntities()) { child.Inventory.ChangeInventoryOwner(remoteClient.AgentId); child.TriggerScriptChangedEvent(Changed.OWNER); child.ApplyNextOwnerPermissions(); } } part.ObjectSaleType = 0; part.SalePrice = 10; group.HasGroupChanged = true; part.GetProperties(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); part.ScheduleUpdate(PrimUpdateFlags.ForcedFullUpdate); break; case 2: // Sell a copy Vector3 inventoryStoredPosition = new Vector3 (((group.AbsolutePosition.X > m_scene.RegionInfo.RegionSizeX) ? m_scene.RegionInfo.RegionSizeX - 1 : group.AbsolutePosition.X) , (group.AbsolutePosition.X > m_scene.RegionInfo.RegionSizeY) ? m_scene.RegionInfo.RegionSizeY - 1 : group.AbsolutePosition.X, group.AbsolutePosition.Z); Vector3 originalPosition = group.AbsolutePosition; group.AbsolutePosition = inventoryStoredPosition; string sceneObjectXml = SceneEntitySerializer.SceneObjectSerializer.ToOriginalXmlFormat(group); group.AbsolutePosition = originalPosition; uint perms = group.GetEffectivePermissions(); if ((perms & (uint)PermissionMask.Transfer) == 0) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale"); } return(false); } AssetBase asset = new AssetBase(UUID.Random(), part.Name, AssetType.Object, group.OwnerID) { Description = part.Description, Data = Utils.StringToBytes(sceneObjectXml) }; asset.ID = m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase { CreatorId = part.CreatorID.ToString(), CreatorData = part.CreatorData, ID = UUID.Random(), Owner = remoteClient.AgentId, AssetID = asset.ID, Description = asset.Description, Name = asset.Name, AssetType = asset.Type, InvType = (int)InventoryType.Object, Folder = categoryID }; uint nextPerms = (perms & 7) << 13; if ((nextPerms & (uint)PermissionMask.Copy) == 0) { perms &= ~(uint)PermissionMask.Copy; } if ((nextPerms & (uint)PermissionMask.Transfer) == 0) { perms &= ~(uint)PermissionMask.Transfer; } if ((nextPerms & (uint)PermissionMask.Modify) == 0) { perms &= ~(uint)PermissionMask.Modify; } item.BasePermissions = perms & part.NextOwnerMask; item.CurrentPermissions = perms & part.NextOwnerMask; item.NextPermissions = part.NextOwnerMask; item.EveryOnePermissions = part.EveryoneMask & part.NextOwnerMask; item.GroupPermissions = part.GroupMask & part.NextOwnerMask; item.CurrentPermissions |= 16; // Slam! item.CreationDate = Util.UnixTimeSinceEpoch(); m_scene.InventoryService.AddItemAsync(item, (itm) => remoteClient.SendInventoryItemCreateUpdate(itm, 0)); break; case 3: // Sell contents List <UUID> invList = part.Inventory.GetInventoryList(); bool okToSell = invList.Select(invID => part.Inventory.GetInventoryItem(invID)) .All(item1 => (item1.CurrentPermissions & (uint)PermissionMask.Transfer) != 0); if (!okToSell) { if (m_dialogModule != null) { m_dialogModule.SendAlertToUser( remoteClient, "This item's inventory doesn't appear to be for sale"); } return(false); } if (invList.Count > 0) { if (inventoryModule != null) { inventoryModule.MoveTaskInventoryItemsToUserInventory(remoteClient.AgentId, part.Name, part, invList); } } break; } return(true); }
/// <summary> /// Remove this child from the group and then update the link numbers so that there is not a hole /// </summary> /// <param name="child"></param> /// <returns></returns> public override bool RemoveChild(ISceneEntity child) { lock (m_partsLock) { if (child is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart)child; m_parts.Remove(part.UUID); m_partsList.Remove(part); //Fix the link numbers now FixLinkNumbers(); return true; } } return false; }
bool DearchiveRegion0DotStar() { if (m_loadStream == null) { return(false); } int successfulAssetRestores = 0; int failedAssetRestores = 0; string filePath = "NONE"; DateTime start = DateTime.Now; TarArchiveReader archive = new TarArchiveReader(m_loadStream); if (!m_skipAssets) { m_threadpool = new WhiteCoreThreadPool(new WhiteCoreThreadPoolStartInfo() { Threads = 1, priority = System.Threading.ThreadPriority .BelowNormal }); } IBackupModule backup = m_scene.RequestModuleInterface <IBackupModule>(); if (!m_merge) { DateTime before = DateTime.Now; MainConsole.Instance.Info("[ARCHIVER]: Clearing all existing scene objects"); if (backup != null) { backup.DeleteAllSceneObjects(); } MainConsole.Instance.Info("[ARCHIVER]: Cleared all existing scene objects in " + (DateTime.Now - before).Minutes + ":" + (DateTime.Now - before).Seconds); } IScriptModule[] modules = m_scene.RequestModuleInterfaces <IScriptModule>(); //Disable the script engine so that it doesn't load in the background and kill OAR loading foreach (IScriptModule module in modules) { module.Disabled = true; } //Disable backup for now as well if (backup != null) { backup.LoadingPrims = true; } IRegionSerialiserModule serialiser = m_scene.RequestModuleInterface <IRegionSerialiserModule>(); int sceneObjectsLoadedCount = 0; //We save the groups so that we can back them up later List <ISceneEntity> groupsToBackup = new List <ISceneEntity>(); List <LandData> landData = new List <LandData>(); // must save off some stuff until after assets have been saved and recieved new uuids // keeping these collection local because I am sure they will get large and garbage collection is better that way List <byte[]> seneObjectGroups = new List <byte[]>(); Dictionary <UUID, UUID> assetBinaryChangeRecord = new Dictionary <UUID, UUID>(); Queue <UUID> assets2Save = new Queue <UUID>(); MainConsole.Instance.Info("[ARCHIVER]: Commencing load from archive"); int ticker = 0; try { byte[] data; TarArchiveReader.TarEntryType entryType; while ((data = archive.ReadEntry(out filePath, out entryType)) != null) { if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY == entryType) { continue; } if (TarArchiveReader.TarEntryType.TYPE_NORMAL_FILE == entryType) { var fName = Path.GetFileName(filePath); if (fName.StartsWith(".")) // ignore hidden files { continue; } } ticker++; if (ticker % 10 == 0) { MainConsole.Instance.Ticker(); } if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) { seneObjectGroups.Add(data); if (seneObjectGroups.Count % 100 == 0) { MainConsole.Instance.InfoFormat("[ARCHIVER]: Found {0} scene object groups...", seneObjectGroups.Count); } } else if (!m_skipAssets && filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) { AssetBase asset; if (LoadAsset(filePath, data, out asset)) { successfulAssetRestores++; if (m_useAsync) { lock (AssetsToAdd) AssetsToAdd.Add(asset); } else { if (asset.IsBinaryAsset) { UUID aid = asset.ID; asset.ID = m_scene.AssetService.Store(asset); if (asset.ID != aid && asset.ID != UUID.Zero) { assetBinaryChangeRecord.Add(aid, asset.ID); } } else { if (!assetNonBinaryCollection.ContainsKey(asset.ID)) { assetNonBinaryCollection.Add(asset.ID, asset); // I need something I can safely loop through assets2Save.Enqueue(asset.ID); } } } } else { failedAssetRestores++; } if ((successfulAssetRestores + failedAssetRestores) % 100 == 0) { MainConsole.Instance.Info("[ARCHIVER]: Loaded " + successfulAssetRestores + " assets and failed to load " + failedAssetRestores + " assets..."); } } else if (!m_skipTerrain && filePath.StartsWith(ArchiveConstants.TERRAINS_PATH)) { LoadTerrain(filePath, data); } else if (!m_merge && filePath.StartsWith(ArchiveConstants.SETTINGS_PATH)) { LoadRegionSettings(filePath, data); } else if (!m_skipTerrain && filePath.StartsWith(ArchiveConstants.LANDDATA_PATH)) { var parcel = LoadLandData(data); landData.Add(parcel); } else if (filePath == ArchiveConstants.CONTROL_FILE_PATH) { LoadControlFile(data); } } MainConsole.Instance.CleanInfo(""); MainConsole.Instance.Info("[ARCHIVER]: Saving loaded assets"); ticker = 0; // Save Assets int savingAssetsCount = 0; while (assets2Save.Count > 0) { ticker++; if (ticker % 10 == 0) { MainConsole.Instance.Ticker(); } try { UUID assetid = assets2Save.Dequeue(); SaveNonBinaryAssets(assetid, assetNonBinaryCollection[assetid], assetBinaryChangeRecord); savingAssetsCount++; if ((savingAssetsCount) % 100 == 0) { MainConsole.Instance.Info("[ARCHIVER]: Saving " + savingAssetsCount + " assets..."); } } catch (Exception ex) { MainConsole.Instance.Info("[ARCHIVER]: Exception in saving an asset: " + ex.ToString()); } } MainConsole.Instance.CleanInfo(""); MainConsole.Instance.Info("[ARCHIVER]: Saving loaded objects"); ticker = 0; foreach (byte[] data2 in seneObjectGroups) { ticker++; if (ticker % 10 == 0) { MainConsole.Instance.Ticker(); } byte[] data3 = data2; string stringData = Utils.BytesToString(data3); MatchCollection mc = Regex.Matches(stringData, sPattern); bool didChange = false; if (mc.Count >= 1) { foreach (Match match in mc) { UUID thematch = new UUID(match.Value); UUID newvalue = thematch; if (assetNonBinaryCollection.ContainsKey(thematch)) { newvalue = assetNonBinaryCollection[thematch].ID; } else if (assetBinaryChangeRecord.ContainsKey(thematch)) { newvalue = assetBinaryChangeRecord[thematch]; } if (thematch == newvalue) { continue; } stringData = stringData.Replace(thematch.ToString().Trim(), newvalue.ToString().Trim()); didChange = true; } } if (didChange) { data3 = Utils.StringToBytes(stringData); } ISceneEntity sceneObject = serialiser.DeserializeGroupFromXml2(data3, m_scene); if (sceneObject == null) { //! big error! MainConsole.Instance.Error("Error reading SOP XML (Please mantis this!): " + m_asciiEncoding.GetString(data3)); continue; } // check sceneObject ownership sceneObject.OwnerID = ResolveUserUuid(sceneObject.OwnerID, sceneObject.LastSignificantPosition, landData); //... and children foreach (ISceneChildEntity part in sceneObject.ChildrenEntities()) { // check user ID's part.CreatorID = ResolveUserUuid(part.CreatorID, part.AbsolutePosition, landData); part.OwnerID = ResolveUserUuid(part.OwnerID, part.AbsolutePosition, landData); part.LastOwnerID = ResolveUserUuid(part.LastOwnerID, part.AbsolutePosition, landData); //check group ID's part.GroupID = ResolveGroupUuid(part.GroupID); // And zap any troublesome sit target information part.SitTargetOrientation = new Quaternion(0, 0, 0, 1); part.SitTargetPosition = new Vector3(0, 0, 0); // Fix ownership/creator of inventory items // Not doing so results in inventory items // being no copy/no mod for everyone lock (part.TaskInventory) { TaskInventoryDictionary inv = part.TaskInventory; foreach (KeyValuePair <UUID, TaskInventoryItem> kvp in inv) { // check user ID's kvp.Value.OwnerID = ResolveUserUuid( kvp.Value.OwnerID, part.AbsolutePosition, landData ); kvp.Value.LastOwnerID = ResolveUserUuid( kvp.Value.LastOwnerID, part.AbsolutePosition, landData ); kvp.Value.CreatorID = ResolveUserUuid( kvp.Value.CreatorID, part.AbsolutePosition, landData ); // ..and possible group ID's kvp.Value.GroupID = ResolveGroupUuid(kvp.Value.GroupID); } } } //Add the offsets of the region Vector3 newPos = new Vector3(sceneObject.AbsolutePosition.X + m_offsetX, sceneObject.AbsolutePosition.Y + m_offsetY, sceneObject.AbsolutePosition.Z + m_offsetZ); if (m_flipX) { newPos.X = m_scene.RegionInfo.RegionSizeX - newPos.X; } if (m_flipY) { newPos.Y = m_scene.RegionInfo.RegionSizeY - newPos.Y; } sceneObject.SetAbsolutePosition(false, newPos); if (m_scene.SceneGraph.AddPrimToScene(sceneObject)) { groupsToBackup.Add(sceneObject); sceneObject.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); sceneObject.CreateScriptInstances(0, false, StateSource.RegionStart, UUID.Zero, true); } sceneObjectsLoadedCount++; if (sceneObjectsLoadedCount % 100 == 0) { MainConsole.Instance.Info("[ARCHIVER]: Loaded " + sceneObjectsLoadedCount + " objects..."); } } assetNonBinaryCollection.Clear(); assetBinaryChangeRecord.Clear(); seneObjectGroups.Clear(); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[ARCHIVER]: Aborting load with error in archive file {0}. {1}", filePath, e); m_errorMessage += e.ToString(); m_scene.EventManager.TriggerOarFileLoaded(UUID.Zero.Guid, m_errorMessage); return(false); } finally { archive.Close(); m_loadStream.Close(); m_loadStream.Dispose(); //Re-enable scripts now that we are done foreach (IScriptModule module in modules) { module.Disabled = false; } //Reset backup too if (backup != null) { backup.LoadingPrims = false; } } // finished with the ticker MainConsole.Instance.CleanInfo(""); //Now back up the prims foreach (ISceneEntity grp in groupsToBackup) { //Backup! grp.HasGroupChanged = true; } if (!m_skipAssets && m_useAsync && !AssetSaverIsRunning) { m_threadpool.QueueEvent(SaveAssets, 0); } if (!m_skipAssets) { MainConsole.Instance.InfoFormat("[ARCHIVER]: Restored {0} assets", successfulAssetRestores); if (failedAssetRestores > 0) { MainConsole.Instance.ErrorFormat("[ARCHIVER]: Failed to load {0} assets", failedAssetRestores); m_errorMessage += String.Format("Failed to load {0} assets", failedAssetRestores); } } // Reload serialized parcels if (!m_skipTerrain) { MainConsole.Instance.InfoFormat("[ARCHIVER]: Loading {0} parcels. Please wait.", landData.Count); IParcelManagementModule parcelManagementModule = m_scene.RequestModuleInterface <IParcelManagementModule> (); if (parcelManagementModule != null) { parcelManagementModule.IncomingLandDataFromOAR(landData, m_merge, new Vector2(m_offsetX, m_offsetY)); } MainConsole.Instance.InfoFormat("[ARCHIVER]: Restored {0} parcels.", landData.Count); } //Clean it out landData.Clear(); MainConsole.Instance.InfoFormat("[ARCHIVER]: Successfully loaded archive in " + (DateTime.Now - start).Minutes + ":" + (DateTime.Now - start).Seconds); m_validUserUuids.Clear(); m_validGroupUuids.Clear(); m_scene.EventManager.TriggerOarFileLoaded(UUID.Zero.Guid, m_errorMessage); return(true); // all good }