* Rex merge, Environment/Scene

afrisby-3
Adam Frisby 2008-02-23 04:02:11 +00:00
parent 69c92d53cb
commit dd96983915
19 changed files with 7642 additions and 6458 deletions

View File

@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using System;
using System.Collections.Generic;
using System.Xml;
@ -40,11 +41,6 @@ namespace OpenSim.Region.Environment.Scenes
public AvatarAnimations()
{
}
public void LoadAnims()
{
//MainLog.Instance.Verbose("CLIENT", "Loading avatar animations");
using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
{
XmlDocument doc = new XmlDocument();
@ -53,24 +49,13 @@ namespace OpenSim.Region.Environment.Scenes
{
if (nod.Attributes["name"] != null)
{
AnimsLLUUID.Add(nod.Attributes["name"].Value, nod.InnerText);
}
}
}
string name = (string)nod.Attributes["name"].Value;
LLUUID id = (LLUUID)nod.InnerText;
// MainLog.Instance.Verbose("CLIENT", "Loaded " + AnimsLLUUID.Count.ToString() + " animation(s)");
try
{
//Mantis: 0000224: 2755 - Enumeration Operation may not execute [immediate crash] (ODE/2750/WIN2003)
foreach (KeyValuePair<string, LLUUID> kp in ScenePresence.Animations.AnimsLLUUID)
{
AnimsNames.Add(kp.Value, kp.Key);
AnimsLLUUID.Add(name, id);
AnimsNames.Add(id, name);
}
}
catch (InvalidOperationException)
{
MainLog.Instance.Warn("AVATAR", "Unable to load animation names for an Avatar");
}
}
}

View File

@ -35,12 +35,24 @@ namespace OpenSim.Region.Environment.Scenes
public class AvatarAppearance
{
protected LLUUID m_scenePresenceID;
public LLUUID ScenePresenceID
{
get { return m_scenePresenceID; }
set { m_scenePresenceID = value; }
}
protected int m_wearablesSerial = 1;
protected bool m_rexmode; //rex
protected string m_avatarStorageAddr;
public int WearablesSerial
{
get { return m_wearablesSerial; }
set { m_wearablesSerial = value; }
}
protected byte[] m_visualParams;
public byte[] VisualParams

View File

@ -13,7 +13,7 @@
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
@ -34,8 +34,6 @@ namespace OpenSim.Region.Environment.Scenes
{
public abstract class EntityBase
{
protected List<EntityBase> m_children;
protected Scene m_scene;
public Scene Scene
@ -116,33 +114,17 @@ namespace OpenSim.Region.Environment.Scenes
Rotation = new Quaternion();
m_name = "(basic entity)";
m_rotationalvelocity = new LLVector3(0, 0, 0);
m_children = new List<EntityBase>();
}
/// <summary>
///
/// </summary>
public virtual void UpdateMovement()
{
foreach (EntityBase child in m_children)
{
child.UpdateMovement();
}
}
public abstract void UpdateMovement();
/// <summary>
/// Performs any updates that need to be done at each frame. This function is overridable from it's children.
/// Performs any updates that need to be done at each frame.
/// </summary>
public virtual void Update()
{
// Do any per-frame updates needed that are applicable to every type of entity
foreach (EntityBase child in m_children)
{
child.Update();
}
}
public abstract void Update();
/// <summary>
/// Copies the entity

View File

@ -13,7 +13,7 @@
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY

View File

@ -42,9 +42,12 @@ namespace OpenSim.Region.Environment.Scenes
public class InnerScene
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#region Events
public event PhysicsCrash UnRecoverableError;
private PhysicsCrash handler001 = null;
#endregion
@ -60,11 +63,15 @@ namespace OpenSim.Region.Environment.Scenes
protected RegionInfo m_regInfo;
protected Scene m_parentScene;
protected PermissionManager PermissionsMngr;
protected List<EntityBase> m_updateList = new List<EntityBase>();
protected int m_numRootAgents = 0;
protected int m_numPrim = 0;
protected int m_numChildAgents = 0;
protected int m_physicalPrim = 0;
protected int m_activeScripts = 0;
protected int m_scriptLPS = 0;
internal object m_syncRoot = new object();
public PhysicsScene _PhyScene;
@ -76,7 +83,7 @@ namespace OpenSim.Region.Environment.Scenes
m_parentScene = parent;
m_regInfo = regInfo;
PermissionsMngr = permissionsMngr;
QuadTree = new BasicQuadTreeNode(null, "/0/", 0, 0, 256, 256);
QuadTree = new BasicQuadTreeNode(null, "/0/", 0, 0, (short)Constants.RegionSize, (short)Constants.RegionSize);
QuadTree.Subdivide();
QuadTree.Subdivide();
}
@ -141,11 +148,20 @@ namespace OpenSim.Region.Environment.Scenes
}
}
internal void UpdatePresences()
{
List<ScenePresence> updateScenePresences = GetScenePresences();
foreach (ScenePresence pres in updateScenePresences)
{
pres.Update();
}
}
internal float UpdatePhysics(double elapsed)
{
lock (m_syncRoot)
{
return _PhyScene.Simulate((float) elapsed);
return _PhyScene.Simulate((float)elapsed);
}
}
@ -170,6 +186,7 @@ namespace OpenSim.Region.Environment.Scenes
foreach (SceneObjectPart part in sceneObject.Children.Values)
{
part.LocalID = m_parentScene.PrimIDAllocate();
}
sceneObject.UpdateParentIDs();
AddEntity(sceneObject);
@ -188,6 +205,29 @@ namespace OpenSim.Region.Environment.Scenes
}
}
internal void AddToUpdateList(EntityBase obj)
{
lock (m_updateList)
{
if (!m_updateList.Contains(obj))
{
m_updateList.Add(obj);
}
}
}
internal void ProcessUpdates()
{
lock (m_updateList)
{
for (int i = 0; i < m_updateList.Count; i++)
{
m_updateList[i].Update();
}
m_updateList.Clear();
}
}
public void AddPhysicalPrim(int number)
{
m_physicalPrim++;
@ -198,6 +238,16 @@ namespace OpenSim.Region.Environment.Scenes
m_physicalPrim--;
}
public void AddToScriptLPS(int number)
{
m_scriptLPS += number;
}
public void AddActiveScripts(int number)
{
m_activeScripts += number;
}
public void RemovePrim(uint localID, LLUUID avatar_deleter)
{
List<EntityBase> EntityList = GetEntities();
@ -206,9 +256,9 @@ namespace OpenSim.Region.Environment.Scenes
{
if (obj is SceneObjectGroup)
{
if (((SceneObjectGroup) obj).LocalId == localID)
if (((SceneObjectGroup)obj).LocalId == localID)
{
m_parentScene.RemoveEntity((SceneObjectGroup) obj);
m_parentScene.RemoveEntity((SceneObjectGroup)obj);
m_numPrim--;
return;
}
@ -216,6 +266,148 @@ namespace OpenSim.Region.Environment.Scenes
}
}
public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, LLQuaternion rot)
{
System.Console.WriteLine("Attaching object " + objectLocalID + " to " + AttachmentPt);
SceneObjectPart p = GetSceneObjectPart(objectLocalID);
ScenePresence av = null;
if (TryGetAvatar(remoteClient.AgentId, out av))
{
ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
objupdate.RegionData.RegionHandle = m_regInfo.RegionHandle;
objupdate.RegionData.TimeDilation = ushort.MaxValue;
objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[2];
// avatar stuff - horrible group copypaste
objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
objupdate.ObjectData[0].PSBlock = new byte[0];
objupdate.ObjectData[0].ExtraParams = new byte[1];
objupdate.ObjectData[0].MediaURL = new byte[0];
objupdate.ObjectData[0].NameValue = new byte[0];
objupdate.ObjectData[0].Text = new byte[0];
objupdate.ObjectData[0].TextColor = new byte[4];
objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0);
objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0);
objupdate.ObjectData[0].Material = 4;
objupdate.ObjectData[0].TextureAnim = new byte[0];
objupdate.ObjectData[0].Sound = LLUUID.Zero;
objupdate.ObjectData[0].State = 0;
objupdate.ObjectData[0].Data = new byte[0];
objupdate.ObjectData[0].ObjectData = new byte[76];
objupdate.ObjectData[0].ObjectData[15] = 128;
objupdate.ObjectData[0].ObjectData[16] = 63;
objupdate.ObjectData[0].ObjectData[56] = 128;
objupdate.ObjectData[0].ObjectData[61] = 102;
objupdate.ObjectData[0].ObjectData[62] = 40;
objupdate.ObjectData[0].ObjectData[63] = 61;
objupdate.ObjectData[0].ObjectData[64] = 189;
objupdate.ObjectData[0].UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
objupdate.ObjectData[0].PathCurve = 16;
objupdate.ObjectData[0].ProfileCurve = 1;
objupdate.ObjectData[0].PathScaleX = 100;
objupdate.ObjectData[0].PathScaleY = 100;
objupdate.ObjectData[0].ParentID = 0;
objupdate.ObjectData[0].OwnerID = LLUUID.Zero;
objupdate.ObjectData[0].Scale = new LLVector3(1, 1, 1);
objupdate.ObjectData[0].PCode = 47;
objupdate.ObjectData[0].TextureEntry = ScenePresence.DefaultTexture;
objupdate.ObjectData[0].ID = av.LocalId;
objupdate.ObjectData[0].FullID = remoteClient.AgentId;
objupdate.ObjectData[0].ParentID = 0;
objupdate.ObjectData[0].NameValue =
Helpers.StringToField("FirstName STRING RW SV " + av.Firstname + "\nLastName STRING RW SV " + av.Lastname);
LLVector3 pos2 = av.AbsolutePosition;
// new LLVector3((float) Pos.X, (float) Pos.Y, (float) Pos.Z);
byte[] pb = pos2.GetBytes();
Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
// primitive part
objupdate.ObjectData[1] = new ObjectUpdatePacket.ObjectDataBlock();
// SetDefaultPrimPacketValues
objupdate.ObjectData[1].PSBlock = new byte[0];
objupdate.ObjectData[1].ExtraParams = new byte[1];
objupdate.ObjectData[1].MediaURL = new byte[0];
objupdate.ObjectData[1].NameValue = new byte[0];
objupdate.ObjectData[1].Text = new byte[0];
objupdate.ObjectData[1].TextColor = new byte[4];
objupdate.ObjectData[1].JointAxisOrAnchor = new LLVector3(0, 0, 0);
objupdate.ObjectData[1].JointPivot = new LLVector3(0, 0, 0);
objupdate.ObjectData[1].Material = 3;
objupdate.ObjectData[1].TextureAnim = new byte[0];
objupdate.ObjectData[1].Sound = LLUUID.Zero;
objupdate.ObjectData[1].State = 0;
objupdate.ObjectData[1].Data = new byte[0];
objupdate.ObjectData[1].ObjectData = new byte[60];
objupdate.ObjectData[1].ObjectData[46] = 128;
objupdate.ObjectData[1].ObjectData[47] = 63;
// SetPrimPacketShapeData
PrimitiveBaseShape primData = p.Shape;
objupdate.ObjectData[1].TextureEntry = primData.TextureEntry;
objupdate.ObjectData[1].PCode = primData.PCode;
objupdate.ObjectData[1].State = (byte)(((byte)AttachmentPt) << 4);
objupdate.ObjectData[1].PathBegin = primData.PathBegin;
objupdate.ObjectData[1].PathEnd = primData.PathEnd;
objupdate.ObjectData[1].PathScaleX = primData.PathScaleX;
objupdate.ObjectData[1].PathScaleY = primData.PathScaleY;
objupdate.ObjectData[1].PathShearX = primData.PathShearX;
objupdate.ObjectData[1].PathShearY = primData.PathShearY;
objupdate.ObjectData[1].PathSkew = primData.PathSkew;
objupdate.ObjectData[1].ProfileBegin = primData.ProfileBegin;
objupdate.ObjectData[1].ProfileEnd = primData.ProfileEnd;
objupdate.ObjectData[1].Scale = primData.Scale;
objupdate.ObjectData[1].PathCurve = primData.PathCurve;
objupdate.ObjectData[1].ProfileCurve = primData.ProfileCurve;
objupdate.ObjectData[1].ProfileHollow = primData.ProfileHollow;
objupdate.ObjectData[1].PathRadiusOffset = primData.PathRadiusOffset;
objupdate.ObjectData[1].PathRevolutions = primData.PathRevolutions;
objupdate.ObjectData[1].PathTaperX = primData.PathTaperX;
objupdate.ObjectData[1].PathTaperY = primData.PathTaperY;
objupdate.ObjectData[1].PathTwist = primData.PathTwist;
objupdate.ObjectData[1].PathTwistBegin = primData.PathTwistBegin;
objupdate.ObjectData[1].ExtraParams = primData.ExtraParams;
objupdate.ObjectData[1].UpdateFlags = 276957500; // flags; // ??
objupdate.ObjectData[1].ID = p.LocalID;
objupdate.ObjectData[1].FullID = p.UUID;
objupdate.ObjectData[1].OwnerID = p.OwnerID;
objupdate.ObjectData[1].Text = Helpers.StringToField(p.Text);
objupdate.ObjectData[1].TextColor[0] = 255;
objupdate.ObjectData[1].TextColor[1] = 255;
objupdate.ObjectData[1].TextColor[2] = 255;
objupdate.ObjectData[1].TextColor[3] = 128;
objupdate.ObjectData[1].ParentID = objupdate.ObjectData[0].ID;
//objupdate.ObjectData[1].PSBlock = particleSystem;
//objupdate.ObjectData[1].ClickAction = clickAction;
objupdate.ObjectData[1].Radius = 20;
objupdate.ObjectData[1].NameValue =
Helpers.StringToField("AttachItemID STRING RW SV " + p.UUID);
LLVector3 pos = new LLVector3((float)0.0, (float)0.0, (float)0.0);
pb = pos.GetBytes();
Array.Copy(pb, 0, objupdate.ObjectData[1].ObjectData, 0, pb.Length);
byte[] brot = rot.GetBytes();
Array.Copy(brot, 0, objupdate.ObjectData[1].ObjectData, 36, brot.Length);
remoteClient.OutPacket(objupdate, ThrottleOutPacketType.Task);
}
else
{
m_log.Info("[SCENE]: Avatar " + remoteClient.AgentId + " not found");
}
}
public ScenePresence CreateAndAddScenePresence(IClientAPI client, bool child, AvatarAppearance appearance)
{
ScenePresence newAvatar = null;
@ -226,13 +418,13 @@ namespace OpenSim.Region.Environment.Scenes
if (child)
{
m_numChildAgents++;
MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new child agent.");
m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Creating new child agent.");
}
else
{
m_numRootAgents++;
MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Creating new root agent.");
MainLog.Instance.Verbose("SCENE", m_regInfo.RegionName + ": Adding Physical agent.");
m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Creating new root agent.");
m_log.Info("[SCENE]: " + m_regInfo.RegionName + ": Adding Physical agent.");
newAvatar.AddToPhysicalScene();
}
@ -301,6 +493,12 @@ namespace OpenSim.Region.Environment.Scenes
public int GetChildAgentCount()
{
// some network situations come in where child agents get closed twice.
if (m_numChildAgents < 0)
{
m_numChildAgents = 0;
}
return m_numChildAgents;
}
@ -319,6 +517,17 @@ namespace OpenSim.Region.Environment.Scenes
return m_physicalPrim;
}
public int GetActiveScripts()
{
return m_activeScripts;
}
public int GetScriptLPS()
{
int returnval = m_scriptLPS;
m_scriptLPS = 0;
return returnval;
}
#endregion
#region Get Methods
@ -389,8 +598,8 @@ namespace OpenSim.Region.Environment.Scenes
{
if (ent is SceneObjectGroup)
{
if (((SceneObjectGroup) ent).HasChildPrim(localID))
return (SceneObjectGroup) ent;
if (((SceneObjectGroup)ent).HasChildPrim(localID))
return (SceneObjectGroup)ent;
}
}
return null;
@ -404,8 +613,8 @@ namespace OpenSim.Region.Environment.Scenes
{
if (ent is SceneObjectGroup)
{
if (((SceneObjectGroup) ent).HasChildPrim(fullID))
return (SceneObjectGroup) ent;
if (((SceneObjectGroup)ent).HasChildPrim(fullID))
return (SceneObjectGroup)ent;
}
}
return null;
@ -420,7 +629,7 @@ namespace OpenSim.Region.Environment.Scenes
{
if (ent is SceneObjectGroup)
{
SceneObjectGroup reportingG = (SceneObjectGroup) ent;
SceneObjectGroup reportingG = (SceneObjectGroup)ent;
EntityIntersection result = reportingG.TestIntersection(hray);
if (result.HitTF)
{
@ -507,9 +716,10 @@ namespace OpenSim.Region.Environment.Scenes
public void physicsBasedCrash()
{
if (UnRecoverableError != null)
handler001 = UnRecoverableError;
if (handler001 != null)
{
UnRecoverableError();
handler001();
}
}
@ -536,24 +746,24 @@ namespace OpenSim.Region.Environment.Scenes
// the initial update for and what we'll use to limit the
// space we check for new objects on movement.
if (presence.IsChildAgent)
if (presence.IsChildAgent && m_parentScene.m_seeIntoRegionFromNeighbor)
{
//Vector3 avPosition = new Vector3(presence.AbsolutePosition.X,presence.AbsolutePosition.Y,presence.AbsolutePosition.Z);
//LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition;
//Vector3 objPosition = new Vector3(oLoc.X,oLoc.Y,oLoc.Z);
//float distResult = Vector3Distance(avPosition, objPosition);
//if (distResult > 512)
//{
//int x = 0;
//}
//if (distResult < presence.DrawDistance)
//{
((SceneObjectGroup) ent).ScheduleFullUpdateToAvatar(presence);
//}
LLVector3 oLoc = ((SceneObjectGroup)ent).AbsolutePosition;
float distResult = (float)Util.GetDistanceTo(presence.AbsolutePosition, oLoc);
//m_log.Info("[DISTANCE]: " + distResult.ToString());
if (distResult < presence.DrawDistance)
{
// Send Only if we don't already know about it.
// KnownPrim also makes the prim known when called.
if (!presence.KnownPrim(((SceneObjectGroup)ent).UUID))
((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence);
}
}
else
{
((SceneObjectGroup) ent).ScheduleFullUpdateToAvatar(presence);
((SceneObjectGroup)ent).ScheduleFullUpdateToAvatar(presence);
}
}
}
@ -602,8 +812,10 @@ namespace OpenSim.Region.Environment.Scenes
{
SceneObjectGroup group = GetGroupByPrim(ObjectID);
if (group != null)
{
group.ServiceObjectPropertiesFamilyRequest(remoteClient, AgentID, RequestFlags);
}
}
/// <summary>
///
@ -721,7 +933,7 @@ namespace OpenSim.Region.Environment.Scenes
{
if (PermissionsMngr.CanEditObject(remoteClient.AgentId, group.UUID))
{
group.UpdatePrimFlags(localID, (ushort) packet.Type, true, packet.ToBytes());
group.UpdatePrimFlags(localID, (ushort)packet.Type, true, packet.ToBytes());
}
}
}
@ -735,6 +947,11 @@ namespace OpenSim.Region.Environment.Scenes
{
group.GrabMovement(offset, pos, remoteClient);
}
// This is outside the above permissions condition
// so that if the object is locked the client moving the object
// get's it's position on the simulator even if it was the same as before
// This keeps the moving user's client in sync with the rest of the world.
group.SendGroupTerseUpdate();
}
}
@ -816,9 +1033,9 @@ namespace OpenSim.Region.Environment.Scenes
{
if (ent is SceneObjectGroup)
{
if (((SceneObjectGroup) ent).LocalId == parentPrim)
if (((SceneObjectGroup)ent).LocalId == parentPrim)
{
parenPrim = (SceneObjectGroup) ent;
parenPrim = (SceneObjectGroup)ent;
break;
}
}
@ -833,9 +1050,9 @@ namespace OpenSim.Region.Environment.Scenes
{
if (ent is SceneObjectGroup)
{
if (((SceneObjectGroup) ent).LocalId == childPrims[i])
if (((SceneObjectGroup)ent).LocalId == childPrims[i])
{
children.Add((SceneObjectGroup) ent);
children.Add((SceneObjectGroup)ent);
}
}
}
@ -862,21 +1079,25 @@ namespace OpenSim.Region.Environment.Scenes
// be more efficient yet to keep this dictionary permanently on hand.
Dictionary<uint, SceneObjectGroup> sceneObjects = new Dictionary<uint, SceneObjectGroup>();
List<EntityBase> EntitieList = GetEntities();
foreach (EntityBase ent in EntitieList)
{
if (ent is SceneObjectGroup)
{
SceneObjectGroup obj = (SceneObjectGroup) ent;
SceneObjectGroup obj = (SceneObjectGroup)ent;
sceneObjects.Add(obj.LocalId, obj);
}
}
// Find the root prim among the prim ids we've been given
for (int i = 0; i < primIds.Count; i++)
{
if (sceneObjects.ContainsKey(primIds[i]))
{
parenPrim = sceneObjects[primIds[i]];
primIds.RemoveAt(i);
break;
@ -892,11 +1113,31 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Verbose("SCENE",
// If the first scan failed, we need to do a /deep/ scan of the linkages. This is /really/ slow
// We know that this is not the root prim now essentially, so we don't have to worry about remapping
// which one is the root prim
bool delinkedSomething = false;
for (int i = 0; i < primIds.Count; i++)
{
foreach (SceneObjectGroup grp in sceneObjects.Values)
{
SceneObjectPart gPart = grp.GetChildPart(primIds[i]);
if (gPart != null)
{
grp.DelinkFromGroup(primIds[i]);
delinkedSomething = true;
}
}
}
if (!delinkedSomething)
{
m_log.InfoFormat("[SCENE]: " +
"DelinkObjects(): Could not find a root prim out of {0} as given to a delink request!",
primIds);
}
}
}
/// <summary>
///
@ -913,9 +1154,9 @@ namespace OpenSim.Region.Environment.Scenes
{
if (ent is SceneObjectGroup)
{
if (((SceneObjectGroup) ent).LocalId == originalPrim)
if (((SceneObjectGroup)ent).LocalId == originalPrim)
{
originPrim = (SceneObjectGroup) ent;
originPrim = (SceneObjectGroup)ent;
break;
}
}
@ -927,18 +1168,23 @@ namespace OpenSim.Region.Environment.Scenes
{
SceneObjectGroup copy = originPrim.Copy(AgentID, GroupID);
copy.AbsolutePosition = copy.AbsolutePosition + offset;
copy.ResetIDs();
lock (Entities)
{
Entities.Add(copy.UUID, copy);
}
m_numPrim++;
copy.StartScripts();
copy.ScheduleGroupForFullUpdate();
m_parentScene.EventManager.TriggerOnAddEntity(copy.RootPart.LocalID); // rex, added
}
}
else
{
MainLog.Instance.Warn("client", "Attempted to duplicate nonexistant prim");
m_log.WarnFormat("[SCENE]: Attempted to duplicate nonexistant prim id {0}", GroupID);
}
}
@ -955,7 +1201,7 @@ namespace OpenSim.Region.Environment.Scenes
return
(float)
Math.Sqrt((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y) + (v1.z - v2.z)*(v1.z - v2.z));
Math.Sqrt((v1.x - v2.x) * (v1.x - v2.x) + (v1.y - v2.y) * (v1.y - v2.y) + (v1.z - v2.z) * (v1.z - v2.z));
}
#endregion

View File

@ -13,7 +13,7 @@
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
@ -26,6 +26,7 @@
*
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
@ -34,17 +35,25 @@ using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Console;
using System;
using Axiom.Math;
using System.IO;
using System.Text;
using System.Xml;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Scenes
{
public partial class Scene
{
private static readonly log4net.ILog m_log
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Start all the scripts in the scene which should be started.
/// </summary>
public void StartScripts()
{
MainLog.Instance.Verbose("PRIMINVENTORY", "Starting scripts in scene");
m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
foreach (SceneObjectGroup group in Entities.Values)
{
@ -60,7 +69,9 @@ namespace OpenSim.Region.Environment.Scenes
/// in which the item is to be placed.</param>
public void AddInventoryItem(IClientAPI remoteClient, InventoryItemBase item)
{
CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
CachedUserInfo userInfo
= CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
if (userInfo != null)
{
userInfo.AddItem(remoteClient.AgentId, item);
@ -80,8 +91,8 @@ namespace OpenSim.Region.Environment.Scenes
if (!TryGetAvatar(avatarId, out avatar))
{
MainLog.Instance.Error(
"AGENTINVENTORY", "Could not find avatar {0} to add inventory item", avatarId);
m_log.ErrorFormat(
"[AGENT INVENTORY]: Could not find avatar {0} to add inventory item", avatarId);
return;
}
@ -167,8 +178,8 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Error(
"AGENTINVENTORY",
m_log.ErrorFormat(
"[AGENT INVENTORY]: " +
"Avatar {0} cannot be found to update its inventory item asset",
avatarId);
}
@ -184,27 +195,46 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="primID">The prim which contains the item to update</param>
/// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
/// <param name="data"></param>
/// <returns>Asset LLUID created</returns>
public void CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, LLUUID itemId,
LLUUID primId, bool isScriptRunning, byte[] data)
{
// TODO Not currently doing anything with the isScriptRunning bool
// Retrieve group
SceneObjectPart part = GetSceneObjectPart(primId);
SceneObjectGroup group = part.ParentGroup;
if (null == group)
{
m_log.ErrorFormat(
"[PRIM INVENTORY]: " +
"Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
itemId, primId);
MainLog.Instance.Verbose(
"PRIMINVENTORY",
"Prim inventory script save functionality not yet implemented."
+ " remoteClient: {0}, itemID: {1}, primID: {2}, isScriptRunning: {3}",
remoteClient, itemId, primId, isScriptRunning);
return;
}
// TODO
// Retrieve client LLUID
// Retrieve sog containing primID
// Retrieve item
// Create new asset and add to cache
TaskInventoryItem item = group.GetInventoryItem(part.LocalID, itemId);
if (null == item)
{
return;
}
// Create new asset
// XXX Hardcoding the numbers is a temporary measure - need an enumeration for this
// There may well be one in libsecondlife
AssetBase asset = CreateAsset(item.Name, item.Description, 10, 10, data);
AssetCache.AddAsset(asset);
// Update item with new asset
// Trigger SOG update (see RezScript)
item.AssetID = asset.FullID;
group.UpdateInventoryItem(item);
group.GetProperties(remoteClient);
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
// return new asset id
if (isScriptRunning)
{
group.StopScript(part.LocalID, item.ItemID);
group.StartScript(part.LocalID, item.ItemID);
}
}
/// <summary>
@ -222,8 +252,8 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY",
m_log.ErrorFormat(
"[PRIM INVENTORY]: " +
"Avatar {0} cannot be found to update its prim item asset",
avatarId);
}
@ -250,6 +280,7 @@ namespace OpenSim.Region.Environment.Scenes
if (userInfo != null && userInfo.RootFolder != null)
{
InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
if (item != null)
{
if (LLUUID.Zero == transactionID)
@ -262,48 +293,24 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
AgentAssetTransactions transactions
= CommsManager.TransactionsManager.GetUserTransActions(remoteClient.AgentId);
if (transactions != null)
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
if (agentTransactions != null)
{
LLUUID assetID = LLUUID.Combine(transactionID, remoteClient.SecureSessionId);
AssetBase asset
= AssetCache.GetAsset(
assetID, (item.assetType == (int) AssetType.Texture ? true : false));
if (asset == null)
{
asset = transactions.GetTransactionAsset(transactionID);
}
if (asset != null && asset.FullID == assetID)
{
asset.Name = item.inventoryName;
asset.Description = item.inventoryDescription;
asset.InvType = (sbyte) item.invType;
asset.Type = (sbyte) item.assetType;
item.assetID = asset.FullID;
AssetCache.AddAsset(asset);
}
userInfo.UpdateItem(remoteClient.AgentId, item);
agentTransactions.HandleItemUpdateFromTransaction(
remoteClient, transactionID, item);
}
}
}
else
{
MainLog.Instance.Warn(
"AGENTINVENTORY",
"Item ID " + itemID + " not found for an inventory item update.");
m_log.Error(
"[AGENTINVENTORY]: Item ID " + itemID + " not found for an inventory item update.");
}
}
else
{
MainLog.Instance.Warn(
"AGENTINVENTORY",
"Agent ID " + remoteClient.AgentId + " not found for an inventory item update.");
m_log.Error(
"[AGENT INVENTORY]: Agent ID " + remoteClient.AgentId + " not found for an inventory item update.");
}
}
@ -316,7 +323,7 @@ namespace OpenSim.Region.Environment.Scenes
CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(oldAgentID);
if (userInfo == null)
{
MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find user " + oldAgentID.ToString());
m_log.Error("[AGENT INVENTORY]: Failed to find user " + oldAgentID.ToString());
return;
}
@ -325,29 +332,33 @@ namespace OpenSim.Region.Environment.Scenes
item = userInfo.RootFolder.HasItem(oldItemID);
if (item == null)
{
MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find item " + oldItemID.ToString());
m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString());
return;
}
}
else
{
MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find item " + oldItemID.ToString());
m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString());
return;
}
}
AssetBase asset
= AssetCache.GetAsset(
item.assetID, (item.assetType == (int)AssetType.Texture ? true : false));
AssetBase asset = AssetCache.CopyAsset(item.assetID);
if (asset == null)
if (asset != null)
{
MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find asset " + item.assetID.ToString());
return;
}
asset.Name = (newName.Length == 0) ? item.inventoryName : newName;
// TODO: preserve current permissions?
CreateNewInventoryItem(remoteClient, newFolderID, callbackID, asset, item.inventoryNextPermissions);
CreateNewInventoryItem(
remoteClient, newFolderID, callbackID, asset, item.inventoryNextPermissions);
}
else
{
m_log.ErrorFormat(
"[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found",
item.inventoryName, item.assetID);
}
}
private AssetBase CreateAsset(string name, string description, sbyte invType, sbyte assetType, byte[] data)
@ -389,14 +400,14 @@ namespace OpenSim.Region.Environment.Scenes
public void MoveInventoryItem(IClientAPI remoteClient, LLUUID folderID, LLUUID itemID, int length,
string newName)
{
MainLog.Instance.Verbose(
"AGENTINVENTORY",
m_log.Info(
"[AGENT INVENTORY]: " +
"Moving item for " + remoteClient.AgentId.ToString());
CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
if (userInfo == null)
{
MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find user " + remoteClient.AgentId.ToString());
m_log.Error("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
return;
}
@ -405,7 +416,7 @@ namespace OpenSim.Region.Environment.Scenes
InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
if (item != null)
{
if (newName != "")
if (newName != System.String.Empty)
{
item.inventoryName = newName;
}
@ -417,21 +428,31 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find item " + itemID.ToString());
m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemID.ToString());
return;
}
}
else
{
MainLog.Instance.Warn("AGENTINVENTORY", "Failed to find item " + itemID.ToString() + ", no root folder");
m_log.Error("[AGENT INVENTORY]: Failed to find item " + itemID.ToString() + ", no root folder");
return;
}
}
/// <summary>
/// Create a new inventory item.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="folderID"></param>
/// <param name="callbackID"></param>
/// <param name="asset"></param>
/// <param name="nextOwnerMask"></param>
private void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID folderID, uint callbackID,
AssetBase asset, uint nextOwnerMask)
{
CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
CachedUserInfo userInfo
= CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
if (userInfo != null)
{
InventoryItemBase item = new InventoryItemBase();
@ -450,13 +471,19 @@ namespace OpenSim.Region.Environment.Scenes
userInfo.AddItem(remoteClient.AgentId, item);
remoteClient.SendInventoryItemCreateUpdate(item);
}
else
{
m_log.WarnFormat(
"No user details associated with client {0} uuid {1} in CreateNewInventoryItem!",
remoteClient.Name, remoteClient.AgentId);
}
}
/// <summary>
/// temporary method to test out creating new inventory items
/// Create a new inventory item.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="transActionID"></param>
/// <param name="transactionID"></param>
/// <param name="folderID"></param>
/// <param name="callbackID"></param>
/// <param name="description"></param>
@ -465,14 +492,16 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="type"></param>
/// <param name="wearableType"></param>
/// <param name="nextOwnerMask"></param>
public void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID transActionID, LLUUID folderID,
public void CreateNewInventoryItem(IClientAPI remoteClient, LLUUID transactionID, LLUUID folderID,
uint callbackID, string description, string name, sbyte invType,
sbyte assetType,
byte wearableType, uint nextOwnerMask)
{
if (transActionID == LLUUID.Zero)
if (transactionID == LLUUID.Zero)
{
CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
CachedUserInfo userInfo
= CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
if (userInfo != null)
{
AssetBase asset = CreateAsset(name, description, invType, assetType, null);
@ -480,13 +509,69 @@ namespace OpenSim.Region.Environment.Scenes
CreateNewInventoryItem(remoteClient, folderID, callbackID, asset, nextOwnerMask);
}
else
{
m_log.ErrorFormat(
"userInfo for agent uuid {0} unexpectedly null in CreateNewInventoryItem",
remoteClient.AgentId);
}
}
else
{
CommsManager.TransactionsManager.HandleInventoryFromTransaction(remoteClient, transActionID, folderID,
callbackID, description, name, invType,
assetType, wearableType, nextOwnerMask);
//System.Console.WriteLine("request to create inventory item from transaction " + transActionID);
IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>();
if (agentTransactions != null)
{
agentTransactions.HandleItemCreationFromTransaction(
remoteClient, transactionID, folderID, callbackID, description,
name, invType, assetType, wearableType, nextOwnerMask);
}
}
}
private void RemoveInventoryItem(IClientAPI remoteClient, LLUUID itemID)
{
CachedUserInfo userInfo
= CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
if (userInfo == null)
{
m_log.Error("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
return;
}
// is going through the root folder really the best way?
// this triggers a tree walk to find and remove the item. 8-(
// since this only happens in Trash (in theory) shouldn't we grab
// the trash folder directly instead of RootFolder?
if (userInfo.RootFolder != null)
{
InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
if (item != null)
{
userInfo.DeleteItem(remoteClient.AgentId, item);
}
}
}
private void RemoveInventoryFolder(IClientAPI remoteClient, LLUUID folderID)
{
CachedUserInfo userInfo
= CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
if (userInfo == null)
{
m_log.Error("[AGENT INVENTORY]: Failed to find user " + remoteClient.AgentId.ToString());
return;
}
if (userInfo.RootFolder != null)
{
InventoryItemBase folder = userInfo.RootFolder.HasItem(folderID);
if (folder != null)
{
// doesn't work just yet, commented out. will fix in next patch.
// userInfo.DeleteItem(remoteClient.AgentId, folder);
}
}
}
@ -526,15 +611,16 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Warn(
"PRIMINVENTORY", "Inventory requested of prim {0} which doesn't exist", primLocalID);
m_log.ErrorFormat(
"[PRIM INVENTORY]: Inventory requested of prim {0} which doesn't exist", primLocalID);
}
}
/// <summary>
/// Remove an item from a prim (task) inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="remoteClient">Unused at the moment but retained since the avatar ID might
/// be necessary for a permissions check at some stage.</param>
/// <param name="itemID"></param>
/// <param name="localID"></param>
public void RemoveTaskInventory(IClientAPI remoteClient, LLUUID itemID, uint localID)
@ -542,8 +628,8 @@ namespace OpenSim.Region.Environment.Scenes
SceneObjectGroup group = GetGroupByPrim(localID);
if (group != null)
{
int type = group.RemoveInventoryItem(remoteClient, localID, itemID);
group.GetProperites(remoteClient);
int type = group.RemoveInventoryItem(localID, itemID);
group.GetProperties(remoteClient);
if (type == 10)
{
EventManager.TriggerRemoveScript(localID, itemID);
@ -551,8 +637,8 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Warn(
"PRIMINVENTORY",
m_log.ErrorFormat(
"[PRIM INVENTORY]: " +
"Removal of item {0} requested of prim {1} but this prim does not exist",
itemID,
localID);
@ -575,16 +661,17 @@ namespace OpenSim.Region.Environment.Scenes
{
// TODO Retrieve itemID from client's inventory to pass on
//group.AddInventoryItem(remoteClient, primLocalID, null);
MainLog.Instance.Verbose(
"PRIMINVENTORY",
"UpdateTaskInventory called with script {0}, folder {1}, primLocalID {2}, user {3}",
m_log.InfoFormat(
"[PRIM INVENTORY]: " +
"Non script prim inventory not yet implemented!"
+ "\nUpdateTaskInventory called with item {0}, folder {1}, primLocalID {2}, user {3}",
itemID, folderID, primLocalID, remoteClient.Name);
}
else
{
MainLog.Instance.Warn(
"PRIMINVENTORY",
"Update with script {0} requested of prim {1} for {2} but this prim does not exist",
m_log.WarnFormat(
"[PRIM INVENTORY]: " +
"Update with item {0} requested of prim {1} for {2} but this prim does not exist",
itemID, primLocalID, remoteClient.Name);
}
}
@ -597,13 +684,23 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="localID"></param>
public void RezScript(IClientAPI remoteClient, LLUUID itemID, uint localID)
{
CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
LLUUID copyID = LLUUID.Random();
if (userInfo != null)
if (itemID != LLUUID.Zero)
{
if (userInfo.RootFolder != null)
CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
if (userInfo != null && userInfo.RootFolder != null)
{
InventoryItemBase item = userInfo.RootFolder.HasItem(itemID);
// Try library
// XXX clumsy, possibly should be one call
if (null == item)
{
item = CommsManager.UserProfileCacheService.libraryRoot.HasItem(itemID);
}
if (item != null)
{
SceneObjectGroup group = GetGroupByPrim(localID);
@ -611,17 +708,16 @@ namespace OpenSim.Region.Environment.Scenes
{
group.AddInventoryItem(remoteClient, localID, item, copyID);
group.StartScript(localID, copyID);
group.GetProperites(remoteClient);
group.GetProperties(remoteClient);
MainLog.Instance.Verbose(
"PRIMINVENTORY",
"Rezzed script {0} into prim local ID {1} for user {2}",
item.inventoryName, localID, remoteClient.Name);
// m_log.InfoFormat("[PRIMINVENTORY]: " +
// "Rezzed script {0} into prim local ID {1} for user {2}",
// item.inventoryName, localID, remoteClient.Name);
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY",
m_log.ErrorFormat(
"[PRIM INVENTORY]: " +
"Could not rez script {0} into prim local ID {1} for user {2}"
+ " because the prim could not be found in the region!",
item.inventoryName, localID, remoteClient.Name);
@ -629,12 +725,20 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY", "Could not find script inventory item {0} to rez for {1}!",
m_log.ErrorFormat(
"[PRIM INVENTORY]: Could not find script inventory item {0} to rez for {1}!",
itemID, remoteClient.Name);
}
}
}
else // If the itemID is zero then the script has been rezzed directly in an object's inventory
{
// not yet implemented
// TODO Need to get more details from original RezScript packet
// XXX jc tmp
// AssetBase asset = CreateAsset("chimney sweep", "sailor.lsl", 10, 10, null);
// AssetCache.AddAsset(asset);
}
}
/// <summary>
@ -655,7 +759,7 @@ namespace OpenSim.Region.Environment.Scenes
foreach (DeRezObjectPacket.ObjectDataBlock Data in DeRezPacket.ObjectData)
{
EntityBase selectedEnt = null;
//MainLog.Instance.Verbose("CLIENT", "LocalID:" + Data.ObjectLocalID.ToString());
//m_log.Info("[CLIENT]: LocalID:" + Data.ObjectLocalID.ToString());
List<EntityBase> EntitieList = GetEntities();
@ -776,6 +880,12 @@ namespace OpenSim.Region.Environment.Scenes
}
}
public void RezSingleAttachment(IClientAPI remoteClient, LLUUID itemID, uint AttachmentPt,
uint ItemFlags, uint NextOwnerMask)
{
System.Console.WriteLine("RezSingleAttachment: unimplemented yet");
}
protected void ObjectAttach(IClientAPI remoteClient, uint localID, LLQuaternion rotation, byte attachPoint)
{
System.Console.WriteLine("Attaching object " + localID + " to " + attachPoint);
@ -860,11 +970,14 @@ namespace OpenSim.Region.Environment.Scenes
private void AddRezObject(string xmlData, LLVector3 pos)
{
SceneObjectGroup group = new SceneObjectGroup(this, m_regionHandle, xmlData);
group.GenerateNewIDs();
group.ResetIDs();
AddEntity(group);
group.AbsolutePosition = pos;
SceneObjectPart rootPart = group.GetChildPart(group.UUID);
rootPart.ApplySanePermissions();
rootPart.TrimPermissions();
group.ApplyPhysics(m_physicalPrim);
group.StartScripts();
//bool UsePhysics = (((rootPart.ObjectFlags & (uint)LLObject.ObjectFlags.Physics) > 0)&& m_physicalPrim);
//if ((rootPart.ObjectFlags & (uint) LLObject.ObjectFlags.Phantom) == 0)
//{
@ -881,6 +994,7 @@ namespace OpenSim.Region.Environment.Scenes
// rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
// }
//
rootPart.ScheduleFullUpdate();
}
}

View File

@ -106,7 +106,7 @@ namespace OpenSim.Region.Environment.Scenes
{
if (((SceneObjectGroup) ent).LocalId == primLocalID)
{
((SceneObjectGroup) ent).GetProperites(remoteClient);
((SceneObjectGroup) ent).GetProperties(remoteClient);
((SceneObjectGroup) ent).IsSelected = true;
LandManager.setPrimsTainted();
break;
@ -138,9 +138,16 @@ namespace OpenSim.Region.Environment.Scenes
}
}
public virtual void ProcessMoneyTransferRequest(LLUUID source, LLUUID destination, int amount, int transactiontype, string description)
{
EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(
source, destination, amount, transactiontype, description);
EventManager.TriggerMoneyTransfer(this, args);
}
public virtual void ProcessObjectGrab(uint localID, LLVector3 offsetPos, IClientAPI remoteClient)
{
EventManager.TriggerObjectGrab(localID, offsetPos, remoteClient);
List<EntityBase> EntitieList = GetEntities();
@ -150,9 +157,21 @@ namespace OpenSim.Region.Environment.Scenes
{
SceneObjectGroup obj = ent as SceneObjectGroup;
// Is this prim part of the group
if (obj.HasChildPrim(localID))
{
// Currently only grab/touch for the single prim
// the client handles rez correctly
obj.ObjectGrabHandler(localID, offsetPos, remoteClient);
// trigger event, one for each prim part in the group
// so that a touch to a non-root prim in a group will still
// trigger a touch_start for a script in the root prim
foreach (SceneObjectPart part in obj.Children.Values)
{
EventManager.TriggerObjectGrab(part.LocalID, part.OffsetPosition, remoteClient);
}
return;
}
}
@ -164,7 +183,7 @@ namespace OpenSim.Region.Environment.Scenes
//EventManager.TriggerAvatarPickerRequest();
List<AvatarPickerAvatar> AvatarResponses = new List<AvatarPickerAvatar>();
AvatarResponses = CommsManager.GenerateAgentPickerRequestResponse(RequestID, query);
AvatarResponses = m_sceneGridService.GenerateAgentPickerRequestResponse(RequestID, query);
AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply);
// TODO: don't create new blocks if recycling an old packet
@ -176,7 +195,7 @@ namespace OpenSim.Region.Environment.Scenes
agentData.AgentID = avatarID;
agentData.QueryID = RequestID;
replyPacket.AgentData = agentData;
byte[] bytes = new byte[AvatarResponses.Count*32];
//byte[] bytes = new byte[AvatarResponses.Count*32];
int i = 0;
foreach (AvatarPickerAvatar item in AvatarResponses)

View File

@ -31,11 +31,14 @@ using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Console;
using OpenSim.Region.Terrain;
using OpenSim.Region.Environment.Interfaces;
namespace OpenSim.Region.Environment.Scenes
{
public abstract class SceneBase : IScene
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#region Events
public event restart OnRestart;
@ -56,6 +59,7 @@ namespace OpenSim.Region.Environment.Scenes
protected RegionInfo m_regInfo;
public TerrainEngine Terrain;
public ITerrainChannel Heightmap;
protected EventManager m_eventManager;
@ -164,8 +168,10 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="seconds"></param>
public virtual void Restart(int seconds)
{
MainLog.Instance.Error("REGION", "passing Restart Message up the namespace");
OnRestart(RegionInfo);
m_log.Error("[REGION]: passing Restart Message up the namespace");
restart handler001 = OnRestart;
if (handler001 != null)
handler001(RegionInfo);
}
public virtual bool PresenceChildStatus(LLUUID avatarID)
@ -174,6 +180,11 @@ namespace OpenSim.Region.Environment.Scenes
}
public abstract bool OtherRegionUp(RegionInfo thisRegion);
public virtual string GetSimulatorVersion()
{
return "OpenSimulator v0.5 SVN";
}
#endregion
#region Shutdown
@ -189,7 +200,7 @@ namespace OpenSim.Region.Environment.Scenes
}
catch (Exception e)
{
MainLog.Instance.Error("SCENE", "SceneBase.cs: Close() - Failed with exception " + e.ToString());
m_log.Error("[SCENE]: SceneBase.cs: Close() - Failed with exception " + e.ToString());
}
}

View File

@ -38,8 +38,12 @@ namespace OpenSim.Region.Environment.Scenes
{
public delegate void KillObjectDelegate(uint localID);
public delegate void RemoveKnownRegionsFromAvatarList(LLUUID avatarID, List<ulong> regionlst);
public class SceneCommunicationService //one instance per region
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
protected CommunicationsManager m_commsProvider;
protected RegionInfo m_regionInfo;
@ -47,14 +51,24 @@ namespace OpenSim.Region.Environment.Scenes
public event AgentCrossing OnAvatarCrossingIntoRegion;
public event ExpectUserDelegate OnExpectUser;
public event ExpectPrimDelegate OnExpectPrim;
public event CloseAgentConnection OnCloseAgentConnection;
public event PrimCrossing OnPrimCrossingIntoRegion;
public event RegionUp OnRegionUp;
public event ChildAgentUpdate OnChildAgentUpdate;
public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar;
private AgentCrossing handler001 = null; // OnAvatarCrossingIntoRegion;
private ExpectUserDelegate handler002 = null; // OnExpectUser;
private ExpectPrimDelegate handler003 = null; // OnExpectPrim;
private CloseAgentConnection handler004 = null; // OnCloseAgentConnection;
private PrimCrossing handler005 = null; // OnPrimCrossingIntoRegion;
private RegionUp handler006 = null; // OnRegionUp;
private ChildAgentUpdate handler007 = null; // OnChildAgentUpdate;
private RemoveKnownRegionsFromAvatarList handler008 = null; // OnRemoveKnownRegionFromAvatar;
public KillObjectDelegate KillObject;
public string _debugRegionName = "";
public string _debugRegionName = String.Empty;
public string debugRegionName
{
@ -76,20 +90,20 @@ namespace OpenSim.Region.Environment.Scenes
if (regionCommsHost != null)
{
//MainLog.Instance.Verbose("INTER", debugRegionName + ": SceneCommunicationService: registered with gridservice and got" + regionCommsHost.ToString());
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: registered with gridservice and got" + regionCommsHost.ToString());
regionCommsHost.debugRegionName = _debugRegionName;
regionCommsHost.OnExpectPrim += IncomingPrimCrossing;
regionCommsHost.OnExpectUser += NewUserConnection;
regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing;
regionCommsHost.OnPrimCrossingIntoRegion += PrimCrossing;
regionCommsHost.OnCloseAgentConnection += CloseConnection;
regionCommsHost.OnRegionUp += newRegionUp;
regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate;
}
else
{
//MainLog.Instance.Verbose("INTER", debugRegionName + ": SceneCommunicationService: registered with gridservice and got null");
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: registered with gridservice and got null");
}
}
@ -100,8 +114,8 @@ namespace OpenSim.Region.Environment.Scenes
regionCommsHost.OnChildAgentUpdate -= ChildAgentUpdate;
regionCommsHost.OnRegionUp -= newRegionUp;
regionCommsHost.OnExpectUser -= NewUserConnection;
regionCommsHost.OnExpectPrim -= IncomingPrimCrossing;
regionCommsHost.OnAvatarCrossingIntoRegion -= AgentCrossing;
regionCommsHost.OnPrimCrossingIntoRegion -= PrimCrossing;
regionCommsHost.OnCloseAgentConnection -= CloseConnection;
m_commsProvider.GridService.DeregisterRegion(m_regionInfo);
regionCommsHost = null;
@ -118,27 +132,30 @@ namespace OpenSim.Region.Environment.Scenes
///
protected void NewUserConnection(ulong regionHandle, AgentCircuitData agent)
{
if (OnExpectUser != null)
handler002 = OnExpectUser;
if (handler002 != null)
{
//MainLog.Instance.Verbose("INTER", debugRegionName + ": SceneCommunicationService: OnExpectUser Fired for User:" + agent.firstname + " " + agent.lastname);
OnExpectUser(regionHandle, agent);
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: OnExpectUser Fired for User:" + agent.firstname + " " + agent.lastname);
handler002(regionHandle, agent);
}
}
protected bool newRegionUp(RegionInfo region)
{
if (OnRegionUp != null)
handler006 = OnRegionUp;
if (handler006 != null)
{
//MainLog.Instance.Verbose("INTER", debugRegionName + ": SceneCommunicationService: newRegionUp Fired for User:" + region.RegionName);
OnRegionUp(region);
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: newRegionUp Fired for User:" + region.RegionName);
handler006(region);
}
return true;
}
protected bool ChildAgentUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
{
if (OnChildAgentUpdate != null)
OnChildAgentUpdate(regionHandle, cAgentData);
handler007 = OnChildAgentUpdate;
if (handler007 != null)
handler007(regionHandle, cAgentData);
return true;
@ -146,26 +163,41 @@ namespace OpenSim.Region.Environment.Scenes
protected void AgentCrossing(ulong regionHandle, LLUUID agentID, LLVector3 position, bool isFlying)
{
if (OnAvatarCrossingIntoRegion != null)
handler001 = OnAvatarCrossingIntoRegion;
if (handler001 != null)
{
OnAvatarCrossingIntoRegion(regionHandle, agentID, position, isFlying);
handler001(regionHandle, agentID, position, isFlying);
}
}
protected void IncomingPrimCrossing(ulong regionHandle, LLUUID primID, String objXMLData)
{
handler003 = OnExpectPrim;
if (handler003 != null)
{
handler003(regionHandle, primID, objXMLData);
}
}
protected void PrimCrossing(ulong regionHandle, LLUUID primID, LLVector3 position, bool isPhysical)
{
if (OnPrimCrossingIntoRegion != null)
handler005 = OnPrimCrossingIntoRegion;
if (handler005 != null)
{
OnPrimCrossingIntoRegion(regionHandle, primID, position, isPhysical);
handler005(regionHandle, primID, position, isPhysical);
}
}
protected void CloseConnection(ulong regionHandle, LLUUID agentID)
protected bool CloseConnection(ulong regionHandle, LLUUID agentID)
{
if (OnCloseAgentConnection != null)
m_log.Info("[INTERREGION]: Incoming Agent Close Request for agent: " + agentID.ToString());
handler004 = OnCloseAgentConnection;
if (handler004 != null)
{
OnCloseAgentConnection(regionHandle, agentID);
return handler004(regionHandle, agentID);
}
return false;
}
#endregion
@ -194,14 +226,14 @@ namespace OpenSim.Region.Environment.Scenes
private void InformClientOfNeighbourAsync(ScenePresence avatar, AgentCircuitData a, ulong regionHandle,
IPEndPoint endPoint)
{
MainLog.Instance.Notice("INTERGRID", "Starting to inform client about neighbours");
m_log.Info("[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");
m_log.Info("[INTERGRID]: Completed inform client about neighbours");
}
}
@ -286,17 +318,17 @@ namespace OpenSim.Region.Environment.Scenes
private void InformNeighboursThatRegionIsUpAsync(RegionInfo region, ulong regionhandle)
{
MainLog.Instance.Notice("INTERGRID", "Starting to inform neighbors that I'm here");
m_log.Info("[INTERGRID]: Starting to inform neighbors that I'm here");
bool regionAccepted =
m_commsProvider.InterRegion.RegionUp((new SearializableRegionInfo(region)), regionhandle);
if (regionAccepted)
{
MainLog.Instance.Notice("INTERGRID", "Completed informing neighbors that I'm here");
m_log.Info("[INTERGRID]: Completed informing neighbors that I'm here");
}
else
{
MainLog.Instance.Notice("INTERGRID", "Failed to inform neighbors that I'm here");
m_log.Info("[INTERGRID]: Failed to inform neighbors that I'm here");
}
}
@ -306,7 +338,7 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary>
public void InformNeighborsThatRegionisUp(RegionInfo region)
{
//MainLog.Instance.Verbose("INTER", debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName);
List<SimpleRegionInfo> neighbours = new List<SimpleRegionInfo>();
@ -327,7 +359,7 @@ namespace OpenSim.Region.Environment.Scenes
//bool val = m_commsProvider.InterRegion.RegionUp(new SearializableRegionInfo(region));
}
public delegate void SendChildAgentDataUpdateDelegate(ulong regionHandle, ChildAgentDataUpdate cAgentData);
public delegate void SendChildAgentDataUpdateDelegate(ChildAgentDataUpdate cAgentData, ScenePresence presence);
/// <summary>
/// This informs all neighboring regions about the settings of it's child agent.
@ -336,20 +368,31 @@ namespace OpenSim.Region.Environment.Scenes
/// This contains information, such as, Draw Distance, Camera location, Current Position, Current throttle settings, etc.
///
/// </summary>
private void SendChildAgentDataUpdateAsync(ulong regionHandle, ChildAgentDataUpdate cAgentData)
private void SendChildAgentDataUpdateAsync(ChildAgentDataUpdate cAgentData, ScenePresence presence)
{
//m_log.Info("[INTERGRID]: Informing neighbors about my agent.");
try
{
foreach (ulong regionHandle in presence.KnownChildRegions)
{
MainLog.Instance.Notice("INTERGRID", "Informing a neighbor about my agent.");
bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData);
if (regionAccepted)
{
MainLog.Instance.Notice("INTERGRID", "Completed sending a neighbor an update about my agent");
//m_log.Info("[INTERGRID]: Completed sending a neighbor an update about my agent");
}
else
{
MainLog.Instance.Notice("INTERGRID", "Failed sending a neighbor an update about my agent");
//m_log.Info("[INTERGRID]: Failed sending a neighbor an update about my agent");
}
}
}
catch (System.InvalidOperationException)
{
// We're ignoring a collection was modified error because this data gets old and outdated fast.
}
}
private void SendChildAgentDataUpdateCompleted(IAsyncResult iar)
{
@ -357,15 +400,64 @@ namespace OpenSim.Region.Environment.Scenes
icon.EndInvoke(iar);
}
public void SendChildAgentDataUpdate(ulong regionHandle, ChildAgentDataUpdate cAgentData)
public void SendChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, ScenePresence presence)
{
// This assumes that we know what our neighbors are.
SendChildAgentDataUpdateDelegate d = SendChildAgentDataUpdateAsync;
d.BeginInvoke(regionHandle, cAgentData,
d.BeginInvoke(cAgentData,presence,
SendChildAgentDataUpdateCompleted,
d);
}
public delegate void SendCloseChildAgentDelegate( LLUUID agentID, List<ulong> regionlst);
/// <summary>
/// This Closes child agents on neighboring regions
/// Calls an asynchronous method to do so.. so it doesn't lag the sim.
/// </summary>
private void SendCloseChildAgentAsync(LLUUID agentID, List<ulong> regionlst)
{
foreach (ulong regionHandle in regionlst)
{
bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID);
if (regionAccepted)
{
m_log.Info("[INTERGRID]: Completed sending agent Close agent Request to neighbor");
}
else
{
m_log.Info("[INTERGRID]: Failed sending agent Close agent Request to neighbor");
}
}
// We remove the list of known regions from the agent's known region list through an event
// to scene, because, if an agent logged of, it's likely that there will be no scene presence
// by the time we get to this part of the method.
handler008 = OnRemoveKnownRegionFromAvatar;
if (handler008 != null)
{
handler008(agentID, regionlst);
}
}
private void SendCloseChildAgentCompleted(IAsyncResult iar)
{
SendCloseChildAgentDelegate icon = (SendCloseChildAgentDelegate)iar.AsyncState;
icon.EndInvoke(iar);
}
public void SendCloseChildAgentConnections(LLUUID agentID, List<ulong> regionslst)
{
// This assumes that we know what our neighbors are.
SendCloseChildAgentDelegate d = SendCloseChildAgentAsync;
d.BeginInvoke(agentID, regionslst,
SendCloseChildAgentCompleted,
d);
}
/// <summary>
/// Helper function to request neighbors from grid-comms
@ -374,7 +466,7 @@ namespace OpenSim.Region.Environment.Scenes
/// <returns></returns>
public virtual RegionInfo RequestNeighbouringRegionInfo(ulong regionHandle)
{
//MainLog.Instance.Verbose("INTER", debugRegionName + ": SceneCommunicationService: Sending Grid Services Request about neighbor " + regionHandle.ToString());
//m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending Grid Services Request about neighbor " + regionHandle.ToString());
return m_commsProvider.GridService.RequestNeighbourInfo(regionHandle);
}
@ -403,6 +495,7 @@ namespace OpenSim.Region.Environment.Scenes
public virtual void RequestTeleportToLocation(ScenePresence avatar, ulong regionHandle, LLVector3 position,
LLVector3 lookAt, uint flags)
{
bool destRegionUp = false;
if (regionHandle == m_regionInfo.RegionHandle)
{
avatar.ControllingClient.SendTeleportLocationStart();
@ -420,6 +513,20 @@ namespace OpenSim.Region.Environment.Scenes
agent.InventoryFolder = LLUUID.Zero;
agent.startpos = position;
agent.child = true;
if (reg.RemotingAddress != "" && reg.RemotingPort != 0)
{
// region is remote. see if it is up
m_commsProvider.InterRegion.CheckRegion(reg.RemotingAddress, reg.RemotingPort);
destRegionUp = m_commsProvider.InterRegion.Available;
}
else
{
// assume local regions are always up
destRegionUp = true;
}
if(destRegionUp)
{
avatar.Close();
m_commsProvider.InterRegion.InformRegionOfChildAgent(regionHandle, agent);
m_commsProvider.InterRegion.ExpectAvatarCrossing(regionHandle, avatar.ControllingClient.AgentId,
@ -433,13 +540,18 @@ namespace OpenSim.Region.Environment.Scenes
{
KillObject(avatar.LocalId);
}
uint newRegionX = (uint) (regionHandle >> 40);
uint newRegionY = (((uint) (regionHandle)) >> 8);
uint oldRegionX = (uint) (m_regionInfo.RegionHandle >> 40);
uint oldRegionY = (((uint) (m_regionInfo.RegionHandle)) >> 8);
if (Util.fast_distance2d((int) (newRegionX - oldRegionX), (int) (newRegionY - oldRegionY)) > 3)
uint newRegionX = (uint)(regionHandle >> 40);
uint newRegionY = (((uint)(regionHandle)) >> 8);
uint oldRegionX = (uint)(m_regionInfo.RegionHandle >> 40);
uint oldRegionY = (((uint)(m_regionInfo.RegionHandle)) >> 8);
if (Util.fast_distance2d((int)(newRegionX - oldRegionX), (int)(newRegionY - oldRegionY)) > 3)
{
CloseChildAgentConnections(avatar);
SendCloseChildAgentConnections(avatar.UUID,avatar.GetKnownRegionList());
}
}
else
{
avatar.ControllingClient.SendTeleportFailed("Remote Region appears to be down");
}
}
}
@ -456,24 +568,55 @@ namespace OpenSim.Region.Environment.Scenes
return m_commsProvider.InterRegion.ExpectAvatarCrossing(regionhandle, agentID, position, isFlying);
}
public bool PrimCrossToNeighboringRegion(ulong regionhandle, LLUUID primID, LLVector3 position, bool isPhysical)
public bool PrimCrossToNeighboringRegion(ulong regionhandle, LLUUID primID, string objData)
{
return m_commsProvider.InterRegion.ExpectPrimCrossing(regionhandle, primID, position, isPhysical);
return m_commsProvider.InterRegion.InformRegionOfPrimCrossing(regionhandle, primID, objData);
}
public void CloseChildAgentConnections(ScenePresence presence)
{
foreach (ulong regionHandle in presence.KnownChildRegions)
{
m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle,
presence.ControllingClient.AgentId);
presence.RemoveNeighbourRegion(regionHandle);
}
}
public Dictionary<string, string> GetGridSettings()
{
return m_commsProvider.GridService.GetGridSettings();
}
public void LogOffUser(LLUUID userid, LLUUID regionid, ulong regionhandle, float posx, float posy, float posz)
{
m_commsProvider.LogOffUser(userid, regionid, regionhandle, posx, posy, posz);
}
public void ClearUserAgent(LLUUID avatarID)
{
m_commsProvider.UserService.clearUserAgent(avatarID);
}
public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
m_commsProvider.AddNewUserFriend(friendlistowner, friend, perms);
}
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
m_commsProvider.UpdateUserFriendPerms(friendlistowner, friend, perms);
}
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
m_commsProvider.RemoveUserFriend(friendlistowner, friend);
}
public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
{
return m_commsProvider.GetUserFriendList(friendlistowner);
}
public List<MapBlockData> RequestNeighbourMapBlocks(int minX, int minY, int maxX, int maxY)
{
return m_commsProvider.GridService.RequestNeighbourMapBlocks(minX, minY, maxX, maxY);
}
public List<AvatarPickerAvatar> GenerateAgentPickerRequestResponse(LLUUID queryID, string query)
{
return m_commsProvider.GenerateAgentPickerRequestResponse(queryID, query);
}
}
}

View File

@ -13,7 +13,7 @@
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
@ -38,11 +38,18 @@ namespace OpenSim.Region.Environment.Scenes
public class SceneManager
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public event RestartSim OnRestartSim;
private readonly List<Scene> m_localScenes;
private Scene m_currentScene = null;
public List<Scene> Scenes
{
get { return m_localScenes; }
}
public Scene CurrentScene
{
get { return m_currentScene; }
@ -98,8 +105,7 @@ namespace OpenSim.Region.Environment.Scenes
public void HandleRestart(RegionInfo rdata)
{
MainLog.Instance.Error("SCENEMANAGER",
"Got Restart message for region:" + rdata.RegionName + " Sending up to main");
m_log.Error("[SCENEMANAGER]: Got Restart message for region:" + rdata.RegionName + " Sending up to main");
int RegionSceneElement = -1;
for (int i = 0; i < m_localScenes.Count; i++)
{
@ -146,7 +152,7 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Error("REGION", "Unable to notify Other regions of this Region coming up");
m_log.Error("[REGION]: Unable to notify Other regions of this Region coming up");
}
}
@ -181,6 +187,12 @@ namespace OpenSim.Region.Environment.Scenes
{
success = false;
}
// Messy way of preventing us printing out the same help text for each scene
if (cmdparams.Length <= 0 || cmdparams[0] == "help")
{
break;
}
}
return success;
@ -297,26 +309,22 @@ namespace OpenSim.Region.Environment.Scenes
return false;
}
public void SetDebugPacketOnCurrentScene(LogBase log, int newDebug)
public void SetDebugPacketOnCurrentScene(int newDebug)
{
ForEachCurrentScene(delegate(Scene scene)
{
List<EntityBase> EntitieList = scene.GetEntities();
List<ScenePresence> scenePresences = scene.GetScenePresences();
foreach (EntityBase entity in EntitieList)
foreach (ScenePresence scenePresence in scenePresences)
{
if (entity is ScenePresence)
if (!scenePresence.IsChildAgent)
{
ScenePresence scenePrescence = entity as ScenePresence;
if (!scenePrescence.IsChildAgent)
{
log.Error(String.Format("Packet debug for {0} {1} set to {2}",
scenePrescence.Firstname,
scenePrescence.Lastname,
newDebug));
m_log.ErrorFormat("Packet debug for {0} {1} set to {2}",
scenePresence.Firstname,
scenePresence.Lastname,
newDebug);
scenePrescence.ControllingClient.SetDebug(newDebug);
}
scenePresence.ControllingClient.SetDebug(newDebug);
}
}
});
@ -328,19 +336,15 @@ namespace OpenSim.Region.Environment.Scenes
ForEachCurrentScene(delegate(Scene scene)
{
List<EntityBase> EntitieList = scene.GetEntities();
List<ScenePresence> scenePrescences = scene.GetScenePresences();
foreach (EntityBase entity in EntitieList)
foreach (ScenePresence scenePrescence in scenePrescences)
{
if (entity is ScenePresence)
{
ScenePresence scenePrescence = entity as ScenePresence;
if (!scenePrescence.IsChildAgent)
{
avatars.Add(scenePrescence);
}
}
}
});
return avatars;

View File

@ -13,7 +13,7 @@
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
@ -38,6 +38,8 @@ namespace OpenSim.Region.Environment.Scenes
{
public partial class SceneObjectGroup : EntityBase
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
/// <summary>
/// Start a given script.
/// </summary>
@ -53,23 +55,80 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY",
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't find part {0} in object group {1}, {2} to start script with ID {3}",
localID, Name, UUID, itemID);
}
}
// /// Start a given script.
// /// </summary>
// /// <param name="localID">
// /// A <see cref="System.UInt32"/>
// /// </param>
// public void StartScript(LLUUID partID, LLUUID itemID)
// {
// SceneObjectPart part = GetChildPart(partID);
// if (part != null)
// {
// part.StartScript(itemID);
// }
// else
// {
// m_log.ErrorFormat(
// "[PRIMINVENTORY]: " +
// "Couldn't find part {0} in object group {1}, {2} to start script with ID {3}",
// localID, Name, UUID, itemID);
// }
// }
/// <summary>
/// Start the scripts contained in all the prims in this group.
/// </summary>
public void StartScripts()
{
// Don't start scripts if they're turned off in the region!
if (!((m_scene.RegionInfo.EstateSettings.regionFlags & Simulator.RegionFlags.SkipScripts) == Simulator.RegionFlags.SkipScripts))
{
foreach (SceneObjectPart part in m_parts.Values)
{
part.StartScripts();
}
}
}
public void StopScripts()
{
lock (m_parts)
{
foreach (SceneObjectPart part in m_parts.Values)
{
part.StopScripts();
}
}
}
/// Start a given script.
/// </summary>
/// <param name="localID">
/// A <see cref="System.UInt32"/>
/// </param>
public void StopScript(uint partID, LLUUID itemID)
{
SceneObjectPart part = GetChildPart(partID);
if (part != null)
{
part.StopScript(itemID);
}
else
{
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't find part {0} in object group {1}, {2} to stop script with ID {3}",
partID, Name, UUID, itemID);
}
}
/// <summary>
///
@ -85,8 +144,8 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY",
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't find part {0} in object group {1}, {2} to retreive prim inventory",
localID, Name, UUID);
}
@ -102,8 +161,8 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY",
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't find part {0} in object group {1}, {2} to request inventory data",
localID, Name, UUID);
}
@ -120,36 +179,29 @@ namespace OpenSim.Region.Environment.Scenes
public bool AddInventoryItem(IClientAPI remoteClient, uint localID,
InventoryItemBase item, LLUUID copyItemID)
{
LLUUID newItemId = ((copyItemID != null) ? copyItemID : item.inventoryID);
LLUUID newItemId = (!copyItemID.Equals(null)) ? copyItemID : item.inventoryID;
SceneObjectPart part = GetChildPart(localID);
if (part != null)
{
TaskInventoryItem taskItem = new TaskInventoryItem();
taskItem.item_id = newItemId;
taskItem.asset_id = item.assetID;
taskItem.name = item.inventoryName;
taskItem.desc = item.inventoryDescription;
taskItem.owner_id = item.avatarID;
taskItem.creator_id = item.creatorsID;
taskItem.type = TaskInventoryItem.Types[item.assetType];
taskItem.inv_type = TaskInventoryItem.InvTypes[item.invType];
taskItem.ItemID = newItemId;
taskItem.AssetID = item.assetID;
taskItem.Name = item.inventoryName;
taskItem.Description = item.inventoryDescription;
taskItem.OwnerID = item.avatarID;
taskItem.CreatorID = item.creatorsID;
taskItem.Type = item.assetType;
taskItem.InvType = item.invType;
part.AddInventoryItem(taskItem);
// It might seem somewhat crude to update the whole group for a single prim inventory change,
// but it's possible that other prim inventory changes will take place before the region
// persistence thread visits this object. In the future, changes can be signalled at a more
// granular level, or we could let the datastore worry about whether prims have really
// changed since they were last persisted.
HasChanged = true;
return true;
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY",
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't find prim local ID {0} in group {1}, {2} to add inventory item ID {3}",
localID, Name, UUID, newItemId);
}
@ -157,19 +209,62 @@ namespace OpenSim.Region.Environment.Scenes
return false;
}
public int RemoveInventoryItem(IClientAPI remoteClient, uint localID, LLUUID itemID)
/// <summary>
/// Returns an existing inventory item. Returns the original, so any changes will be live.
/// </summary>
/// <param name="primID"></param>
/// <param name="itemID"></param>
/// <returns>null if the item does not exist</returns>
public TaskInventoryItem GetInventoryItem(uint primID, LLUUID itemID)
{
SceneObjectPart part = GetChildPart(primID);
if (part != null)
{
return part.GetInventoryItem(itemID);
}
else
{
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't find prim local ID {0} in prim {1}, {2} to get inventory item ID {3}",
primID, part.Name, part.UUID, itemID);
}
return null;
}
/// <summary>
/// Update an existing inventory item.
/// </summary>
/// <param name="item">The updated item. An item with the same id must already exist
/// in this prim's inventory</param>
/// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
public bool UpdateInventoryItem(TaskInventoryItem item)
{
SceneObjectPart part = GetChildPart(item.ParentPartID);
if (part != null)
{
part.UpdateInventoryItem(item);
return true;
}
else
{
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't find prim ID {0} to update item {1}, {2}",
item.ParentPartID, item.Name, item.ItemID);
}
return false;
}
public int RemoveInventoryItem(uint localID, LLUUID itemID)
{
SceneObjectPart part = GetChildPart(localID);
if (part != null)
{
int type = part.RemoveInventoryItem(remoteClient, localID, itemID);
// It might seem somewhat crude to update the whole group for a single prim inventory change,
// but it's possible that other prim inventory changes will take place before the region
// persistence thread visits this object. In the future, changes can be signalled at a more
// granular level, or we could let the datastore worry about whether prims have really
// changed since they were last persisted.
HasChanged = true;
int type = part.RemoveInventoryItem(itemID);
return type;
}

View File

@ -13,7 +13,7 @@
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
@ -33,6 +33,7 @@ using System.Xml.Serialization;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Framework.Communications.Cache;
using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes.Scripting;
@ -41,7 +42,9 @@ namespace OpenSim.Region.Environment.Scenes
{
public partial class SceneObjectPart : IScriptHost
{
private string m_inventoryFileName = "";
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private string m_inventoryFileName = String.Empty;
/// <summary>
/// The inventory folder for this prim
@ -58,18 +61,6 @@ namespace OpenSim.Region.Environment.Scenes
set { m_folderID = value; }
}
/// <summary>
/// Holds in memory prim inventory
/// </summary>
protected IDictionary<LLUUID, TaskInventoryItem> m_taskInventory
= new Dictionary<LLUUID, TaskInventoryItem>();
[XmlIgnore]
public IDictionary<LLUUID, TaskInventoryItem> TaskInventory
{
get { return m_taskInventory; }
}
/// <summary>
/// Serial count for inventory file , used to tell if inventory has changed
/// no need for this to be part of Database backup
@ -79,22 +70,76 @@ namespace OpenSim.Region.Environment.Scenes
public uint InventorySerial
{
get { return m_inventorySerial; }
set { m_inventorySerial = value; }
}
/// <summary>
/// Holds in memory prim inventory
/// </summary>
protected TaskInventoryDictionary m_taskInventory = new TaskInventoryDictionary();
public TaskInventoryDictionary TaskInventory
{
get { return m_taskInventory; }
set { m_taskInventory = value; }
}
/// <summary>
/// Tracks whether inventory has changed since the last persistent backup
/// </summary>
private bool HasInventoryChanged;
/// <summary>
/// Reset LLUUIDs for all the items in the prim's inventory. This involves either generating
/// new ones or setting existing UUIDs to the correct parent UUIDs
/// </summary>
/// <param name="linkNum'>Link number for the part</param>
public void ResetInventoryIDs()
{
lock (TaskInventory)
{
IList<TaskInventoryItem> items = new List<TaskInventoryItem>(TaskInventory.Values);
TaskInventory.Clear();
foreach (TaskInventoryItem item in items)
{
item.ResetIDs(UUID);
TaskInventory.Add(item.ItemID, item);
}
}
}
/// <summary>
/// Start all the scripts contained in this prim's inventory
/// </summary>
public void StartScripts()
{
lock (m_taskInventory)
{
foreach (TaskInventoryItem item in m_taskInventory.Values)
{
if ("lsltext" == item.type)
// XXX more hardcoding badness. Should be an enum in TaskInventoryItem
if (10 == item.Type)
{
StartScript(item);
}
}
}
}
public void StopScripts()
{
lock (m_taskInventory)
{
foreach (TaskInventoryItem item in m_taskInventory.Values)
{
if (10 == item.Type)
{
StopScript(item.ItemID);
}
}
}
}
/// <summary>
/// Start a script which is in this prim's inventory.
@ -103,24 +148,33 @@ namespace OpenSim.Region.Environment.Scenes
/// <returns></returns>
public void StartScript(TaskInventoryItem item)
{
// MainLog.Instance.Verbose(
// "PRIMINVENTORY",
// "Starting script {0}, {1} in prim {2}, {3}",
// item.name, item.item_id, Name, UUID);
// m_log.InfoFormat(
// "[PRIMINVENTORY]: " +
// "Starting script {0}, {1} in prim {2}, {3}",
// item.Name, item.ItemID, Name, UUID);
AddFlag(LLObject.ObjectFlags.Scripted);
AssetBase rezAsset = m_parentGroup.Scene.AssetCache.GetAsset(item.asset_id, false);
if (rezAsset != null)
if (!((m_parentGroup.Scene.RegionInfo.EstateSettings.regionFlags & Simulator.RegionFlags.SkipScripts) == Simulator.RegionFlags.SkipScripts))
{
string script = Helpers.FieldToUTF8String(rezAsset.Data);
m_parentGroup.Scene.EventManager.TriggerRezScript(LocalID, item.item_id, script);
AssetCache cache = m_parentGroup.Scene.AssetCache;
cache.GetAsset(item.AssetID, delegate(LLUUID assetID, AssetBase asset)
{
if (null == asset)
{
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't start script {0}, {1} since asset ID {2} could not be found",
item.Name, item.ItemID, item.AssetID);
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY",
"Couldn't start script {0}, {1} since asset ID {2} could not be found",
item.name, item.item_id, item.asset_id);
string script = Helpers.FieldToUTF8String(asset.Data);
m_parentGroup.Scene.EventManager.TriggerRezScript(LocalID,item.ItemID,script);
m_parentGroup.AddActiveScriptCount(1);
ScheduleFullUpdate();
}
}, false);
}
}
@ -131,19 +185,42 @@ namespace OpenSim.Region.Environment.Scenes
/// A <see cref="LLUUID"/>
/// </param>
public void StartScript(LLUUID itemId)
{
lock (m_taskInventory)
{
if (m_taskInventory.ContainsKey(itemId))
{
StartScript(m_taskInventory[itemId]);
}
else
{
MainLog.Instance.Error(
"PRIMINVENTORY",
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}",
itemId, Name, UUID);
}
}
}
/// <summary>
/// Stop a script which is in this prim's inventory.
/// </summary>
/// <param name="itemId"></param>
public void StopScript(LLUUID itemId)
{
if (m_taskInventory.ContainsKey(itemId))
{
m_parentGroup.Scene.EventManager.TriggerRemoveScript(LocalID, itemId);
m_parentGroup.AddActiveScriptCount(-1);
}
else
{
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2}",
itemId, Name, UUID);
}
}
/// <summary>
@ -152,54 +229,152 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="item"></param>
public void AddInventoryItem(TaskInventoryItem item)
{
item.parent_id = m_folderID;
item.creation_date = 1000;
item.ParentID = m_folderID;
item.CreationDate = 1000;
item.ParentPartID = UUID;
m_taskInventory.Add(item.item_id, item);
lock (m_taskInventory)
{
m_taskInventory.Add(item.ItemID, item);
TriggerScriptChangedEvent(Changed.INVENTORY);
}
m_inventorySerial++;
HasInventoryChanged = true;
}
/// <summary>
/// Restore a whole collection of items to the prim's inventory at once.
/// We assume that the items already have all their fields correctly filled out.
/// The items are not flagged for persistence to the database, since they are being restored
/// from persistence rather than being newly added.
/// </summary>
/// <param name="items"></param>
public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
{
lock (m_taskInventory)
{
foreach (TaskInventoryItem item in items)
{
m_taskInventory.Add(item.ItemID, item);
TriggerScriptChangedEvent(Changed.INVENTORY);
}
}
m_inventorySerial++;
}
/// <summary>
/// Add a whole collection of items to the prim's inventory at once. We assume that the items already
/// have all their fields correctly filled out.
/// Returns an existing inventory item. Returns the original, so any changes will be live.
/// </summary>
/// <param name="items"></param>
public void AddInventoryItems(ICollection<TaskInventoryItem> items)
/// <param name="itemID"></param>
/// <returns>null if the item does not exist</returns>
public TaskInventoryItem GetInventoryItem(LLUUID itemID)
{
foreach (TaskInventoryItem item in items)
lock (m_taskInventory)
{
m_taskInventory.Add(item.item_id, item);
if (m_taskInventory.ContainsKey(itemID))
{
return m_taskInventory[itemID];
}
else
{
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
itemID, Name, UUID);
}
}
return null;
}
/// <summary>
/// Update an existing inventory item.
/// </summary>
/// <param name="item">The updated item. An item with the same id must already exist
/// in this prim's inventory.</param>
/// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
public bool UpdateInventoryItem(TaskInventoryItem item)
{
lock (m_taskInventory)
{
if (m_taskInventory.ContainsKey(item.ItemID))
{
m_taskInventory[item.ItemID] = item;
m_inventorySerial++;
TriggerScriptChangedEvent(Changed.INVENTORY);
HasInventoryChanged = true;
return true;
}
else
{
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
item.ItemID, Name, UUID);
}
}
return false;
}
public void AddScriptLPS(int count)
{
m_parentGroup.AddScriptLPS(count);
}
/// <summary>
/// Remove an item from this prim's inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="localID"></param>
/// <param name="itemID"></param>
/// <returns>Numeric asset type of the item removed.</returns>
public int RemoveInventoryItem(IClientAPI remoteClient, uint localID, LLUUID itemID)
/// <returns>Numeric asset type of the item removed. Returns -1 if the item did not exist
/// in this prim's inventory.</returns>
public int RemoveInventoryItem(LLUUID itemID)
{
if (localID == LocalID)
lock (m_taskInventory)
{
if (m_taskInventory.ContainsKey(itemID))
{
string type = m_taskInventory[itemID].inv_type;
int type = m_taskInventory[itemID].InvType;
m_taskInventory.Remove(itemID);
m_inventorySerial++;
if (type == "lsltext")
TriggerScriptChangedEvent(Changed.INVENTORY);
HasInventoryChanged = true;
int scriptcount = 0;
lock (m_taskInventory)
{
return 10;
foreach (TaskInventoryItem item in m_taskInventory.Values)
{
if (item.Type == 10)
{
scriptcount++;
}
}
}
if (scriptcount <= 0)
{
RemFlag(LLObject.ObjectFlags.Scripted);
ScheduleFullUpdate();
}
ScheduleFullUpdate();
return type;
}
else
{
return 0;
}
m_log.ErrorFormat(
"[PRIMINVENTORY]: " +
"Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
itemID, Name, UUID);
}
}
return -1;
}
@ -212,7 +387,7 @@ namespace OpenSim.Region.Environment.Scenes
{
if (m_inventorySerial > 0)
{
client.SendTaskInventory(m_uuid, (short) m_inventorySerial,
client.SendTaskInventory(m_uuid, (short)m_inventorySerial,
Helpers.StringToField(m_inventoryFileName));
return true;
}
@ -227,11 +402,14 @@ namespace OpenSim.Region.Environment.Scenes
{
byte[] fileData = new byte[0];
InventoryStringBuilder invString = new InventoryStringBuilder(m_folderID, UUID);
lock (m_taskInventory)
{
foreach (TaskInventoryItem item in m_taskInventory.Values)
{
invString.AddItemStart();
invString.AddNameValueLine("item_id", item.item_id.ToString());
invString.AddNameValueLine("parent_id", item.parent_id.ToString());
invString.AddNameValueLine("item_id", item.ItemID.ToString());
invString.AddNameValueLine("parent_id", item.ParentID.ToString());
invString.AddPermissionsStart();
invString.AddNameValueLine("base_mask", "0x7FFFFFFF");
@ -239,26 +417,27 @@ namespace OpenSim.Region.Environment.Scenes
invString.AddNameValueLine("group_mask", "0x7FFFFFFF");
invString.AddNameValueLine("everyone_mask", "0x7FFFFFFF");
invString.AddNameValueLine("next_owner_mask", "0x7FFFFFFF");
invString.AddNameValueLine("creator_id", item.creator_id.ToString());
invString.AddNameValueLine("owner_id", item.owner_id.ToString());
invString.AddNameValueLine("last_owner_id", item.last_owner_id.ToString());
invString.AddNameValueLine("group_id", item.group_id.ToString());
invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
invString.AddNameValueLine("owner_id", item.OwnerID.ToString());
invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
invString.AddNameValueLine("group_id", item.GroupID.ToString());
invString.AddSectionEnd();
invString.AddNameValueLine("asset_id", item.asset_id.ToString());
invString.AddNameValueLine("type", item.type);
invString.AddNameValueLine("inv_type", item.inv_type);
invString.AddNameValueLine("asset_id", item.AssetID.ToString());
invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
invString.AddNameValueLine("flags", "0x00");
invString.AddNameValueLine("name", item.name + "|");
invString.AddNameValueLine("desc", item.desc + "|");
invString.AddNameValueLine("creation_date", item.creation_date.ToString());
invString.AddNameValueLine("name", item.Name + "|");
invString.AddNameValueLine("desc", item.Description + "|");
invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
invString.AddSectionEnd();
}
}
fileData = Helpers.StringToField(invString.BuildString);
// MainLog.Instance.Verbose(
// "PRIMINVENTORY", "RequestInventoryFile fileData: {0}", Helpers.FieldToUTF8String(fileData));
// m_log.InfoFormat(
// "[PRIMINVENTORY]: RequestInventoryFile fileData: {0}", Helpers.FieldToUTF8String(fileData));
if (fileData.Length > 2)
{
@ -266,9 +445,26 @@ namespace OpenSim.Region.Environment.Scenes
}
}
/// <summary>
/// Process inventory backup
/// </summary>
/// <param name="datastore"></param>
public void ProcessInventoryBackup(IRegionDataStore datastore)
{
if (HasInventoryChanged)
{
lock (TaskInventory)
{
datastore.StorePrimInventory(UUID, TaskInventory.Values);
}
HasInventoryChanged = false;
}
}
public class InventoryStringBuilder
{
public string BuildString = "";
public string BuildString = String.Empty;
public InventoryStringBuilder(LLUUID folderID, LLUUID parentID)
{

View File

@ -39,8 +39,16 @@ namespace OpenSim.Region.Environment.Scenes
{
public class ScenePresence : EntityBase
{
public static AvatarAnimations Animations = null;
// ~ScenePresence()
// {
// System.Console.WriteLine("[ScenePresence] Destructor called");
// }
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public static AvatarAnimations Animations = new AvatarAnimations();
public static byte[] DefaultTexture;
public LLUUID currentParcelUUID = LLUUID.Zero;
private List<LLUUID> m_animations = new List<LLUUID>();
private List<int> m_animationSeqs = new List<int>();
@ -57,6 +65,9 @@ namespace OpenSim.Region.Environment.Scenes
private LLVector3 m_requestedSitOffset = new LLVector3();
private float m_sitAvatarHeight = 2.0f;
private float m_godlevel = 0;
private LLVector3 m_LastChildAgentUpdatePosition = new LLVector3();
private int m_perfMonMS = 0;
private bool m_setAlwaysRun = false;
@ -69,6 +80,10 @@ namespace OpenSim.Region.Environment.Scenes
private bool m_newCoarseLocations = true;
private bool m_gotAllObjectsInScene = false;
private bool m_lastPhysicsStoppedStatus = false;
private LLVector3 m_lastVelocity = LLVector3.Zero;
// Default AV Height
private float m_avHeight = 127.0f;
@ -90,6 +105,11 @@ namespace OpenSim.Region.Environment.Scenes
private LLQuaternion m_headrotation = new LLQuaternion();
private byte m_state = (byte) 0;
//Reuse the LLVector3 instead of creating a new one on the UpdateMovement method
private LLVector3 movementvector = new LLVector3();
private List<LLUUID> m_knownPrimUUID = new List<LLUUID>();
// Agent's Draw distance.
protected float m_DrawDistance = 0f;
@ -98,6 +118,8 @@ namespace OpenSim.Region.Environment.Scenes
private readonly List<ulong> m_knownChildRegions = new List<ulong>();
//neighbouring regions we have enabled a child agent in
private SignificantClientMovement handler001 = null; //OnSignificantClientMovement;
/// <summary>
/// Implemented Control Flags
@ -136,6 +158,17 @@ namespace OpenSim.Region.Environment.Scenes
get { return m_physicsActor; }
}
public bool KnownPrim(LLUUID primID)
{
if (m_knownPrimUUID.Contains(primID))
{
return true;
}
m_knownPrimUUID.Add(primID);
return false;
}
public bool Updated
{
set { m_updateflag = value; }
@ -331,14 +364,14 @@ namespace OpenSim.Region.Environment.Scenes
}
catch (KeyNotFoundException)
{
MainLog.Instance.Warn("AVATAR", "KeyNotFound Exception playing avatar stand animation");
m_log.Warn("[AVATAR]: KeyNotFound Exception playing avatar stand animation");
}
m_animationSeqs.Add(1);
RegisterToEvents();
SetDirectionVectors();
m_scene.LandManager.sendLandUpdate(this);
m_scene.LandManager.sendLandUpdate(this, true);
}
public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams,
@ -402,12 +435,16 @@ namespace OpenSim.Region.Environment.Scenes
public void SendPrimUpdates()
{
m_perfMonMS = System.Environment.TickCount;
if (!m_gotAllObjectsInScene)
{
if (!m_isChildAgent || m_scene.m_sendTasksToChild)
if (!m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor)
{
m_scene.SendAllSceneObjectsToClient(this);
m_gotAllObjectsInScene = true;
}
}
@ -460,6 +497,8 @@ namespace OpenSim.Region.Environment.Scenes
updateCount++;
}
}
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
}
public void forceAvatarMovement(Vector3 position, Quaternion rotation)
@ -487,7 +526,9 @@ namespace OpenSim.Region.Environment.Scenes
m_scene.CommsManager.UserProfileCacheService.UpdateUserInventory(m_uuid);
//if (!m_gotAllObjectsInScene)
//{
//m_scene.SendAllSceneObjectsToClient(this);
m_scene.SendAllSceneObjectsToClient(this);
m_scene.LandManager.sendLandUpdate(this, true);
//m_gotAllObjectsInScene = true;
//}
}
@ -577,6 +618,11 @@ namespace OpenSim.Region.Environment.Scenes
}
}
public List<ulong> GetKnownRegionList()
{
return m_knownChildRegions;
}
#endregion
#region Event Handlers
@ -630,6 +676,8 @@ namespace OpenSim.Region.Environment.Scenes
// Must check for standing up even when PhysicsActor is null,
// since sitting currently removes avatar from physical scene
m_perfMonMS = System.Environment.TickCount;
uint flags = agentData.AgentData.ControlFlags;
LLQuaternion bodyRotation = agentData.AgentData.BodyRotation;
@ -708,7 +756,14 @@ namespace OpenSim.Region.Environment.Scenes
if ((flags & (uint) DCF) != 0)
{
DCFlagKeyPressed = true;
try
{
agent_control_v3 += Dir_Vectors[i];
}
catch (IndexOutOfRangeException)
{
// Why did I get this?
}
if ((m_movementflag & (uint) DCF) == 0)
{
m_movementflag += (byte) (uint) DCF;
@ -742,6 +797,8 @@ namespace OpenSim.Region.Environment.Scenes
// Are the collision requirements fulfilled?
bool colliding = (m_physicsActor.IsColliding == true);
if (m_physicsActor.Flying && colliding && controlland)
{
StopFlying();
@ -756,6 +813,8 @@ namespace OpenSim.Region.Environment.Scenes
}
m_scene.EventManager.TriggerOnClientMovement(this);
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
}
/// <summary>
@ -772,16 +831,28 @@ namespace OpenSim.Region.Environment.Scenes
// Reset sit target.
if (part.GetAvatarOnSitTarget() == UUID)
part.SetAvatarOnSitTarget(LLUUID.Zero);
m_parentPosition = part.GetWorldPosition();
}
if (m_physicsActor == null)
{
AddToPhysicalScene();
}
m_pos += m_parentPosition + new LLVector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight);
m_parentPosition = new LLVector3();
if (m_physicsActor == null)
AddToPhysicalScene();
m_parentID = 0;
SendFullUpdateToAllClients();
if (m_physicsActor != null)
{
SetHeight(m_avHeight);
}
}
SetMovementAnimation(Animations.AnimsLLUUID["STAND"], 1);
@ -803,7 +874,6 @@ namespace OpenSim.Region.Environment.Scenes
// TODO: determine position to sit at based on scene geometry; don't trust offset from client
// see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
// Is a sit target available?
Vector3 avSitOffSet = part.GetSitTargetPosition();
Quaternion avSitOrientation = part.GetSitTargetOrientation();
@ -823,15 +893,12 @@ namespace OpenSim.Region.Environment.Scenes
autopilot = false;
}
pos = part.AbsolutePosition + offset;
if (m_physicsActor != null)
{
//
// If we're not using the client autopilot, we're immediately warping the avatar to the location
// We can remove the physicsActor until they stand up.
//
m_sitAvatarHeight = m_physicsActor.Size.Z;
if (autopilot)
@ -843,17 +910,13 @@ namespace OpenSim.Region.Environment.Scenes
RemoveFromPhysicalScene();
AbsolutePosition = pos + new LLVector3(0.0f, 0.0f, m_sitAvatarHeight);
}
else
{
}
}
else
{
RemoveFromPhysicalScene();
}
} // Physactor != null
} // part != null
}
}
avatarSitResponse.SitTransform.AutoPilot = autopilot;
avatarSitResponse.SitTransform.SitPosition = offset;
@ -886,7 +949,7 @@ namespace OpenSim.Region.Environment.Scenes
}
else
{
MainLog.Instance.Warn("Sit requested on unknown object: " + targetID.ToString());
m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
}
SendSitResponse(remoteClient, targetID, offset);
}
@ -988,6 +1051,8 @@ namespace OpenSim.Region.Environment.Scenes
/// like flying and sitting, for example.
/// </summary>
protected void SetMovementAnimation(LLUUID anim, int seq)
{
try
{
if (m_animations[0] != anim)
{
@ -996,12 +1061,22 @@ namespace OpenSim.Region.Environment.Scenes
SendAnimPack();
}
}
catch
{
m_log.Warn("[AVATAR]: SetMovementAnimation for avatar failed. Attempting recovery...");
m_animations[0] = anim;
m_animationSeqs[0] = seq;
SendAnimPack();
}
}
/// <summary>
/// This method handles agent movement related animations
/// </summary>
protected void UpdateMovementAnimations(bool update_movementflag)
{
if (update_movementflag)
{
// Are we moving?
@ -1029,18 +1104,34 @@ namespace OpenSim.Region.Environment.Scenes
(m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0)
{
// Client is moving, and colliding and pressing the page up button but isn't flying
try
{
SetMovementAnimation(Animations.AnimsLLUUID["JUMP"], 1);
}
catch (KeyNotFoundException)
{ }
}
else if (m_setAlwaysRun)
{
// We are running
try
{
SetMovementAnimation(Animations.AnimsLLUUID["RUN"], 1);
}
catch (KeyNotFoundException)
{ }
}
else
{
// We're moving, but we're not doing anything else.. so play the stand animation
try
{
SetMovementAnimation(Animations.AnimsLLUUID["WALK"], 1);
}
catch (KeyNotFoundException)
{ }
}
}
else
{
@ -1071,12 +1162,19 @@ namespace OpenSim.Region.Environment.Scenes
else
{
// We're not moving.. and we're not doing anything.. so play the stand animation
try
{
SetMovementAnimation(Animations.AnimsLLUUID["STAND"], 1);
}
catch (KeyNotFoundException)
{ }
}
}
}
}
/// <summary>
/// Adds a new movement
/// </summary>
@ -1087,6 +1185,9 @@ namespace OpenSim.Region.Environment.Scenes
Console.WriteLine("DEBUG: AddNewMovement: child agent");
return;
}
m_perfMonMS = System.Environment.TickCount;
m_rotation = rotation;
NewForce newVelocity = new NewForce();
Vector3 direc = rotation*vec;
@ -1099,13 +1200,13 @@ namespace OpenSim.Region.Environment.Scenes
//bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
//bool colliding = (m_physicsActor.IsColliding==true);
//if (controlland)
// MainLog.Instance.Verbose("AGENT","landCommand");
// m_log.Info("[AGENT]: landCommand");
//if (colliding )
// MainLog.Instance.Verbose("AGENT","colliding");
// m_log.Info("[AGENT]: colliding");
//if (m_physicsActor.Flying && colliding && controlland)
//{
// StopFlying();
// MainLog.Instance.Verbose("AGENT", "Stop FLying");
// m_log.Info("[AGENT]: Stop FLying");
//}
}
else
@ -1118,9 +1219,14 @@ namespace OpenSim.Region.Environment.Scenes
direc.z *= 3;
//System.Console.WriteLine("Jump");
// PreJump and jump happen too quickly. Many times prejump gets ignored.
try
{
SetMovementAnimation(Animations.AnimsLLUUID["PREJUMP"], 1);
SetMovementAnimation(Animations.AnimsLLUUID["JUMP"], 1);
}
catch (KeyNotFoundException)
{ }
}
}
}
@ -1128,6 +1234,8 @@ namespace OpenSim.Region.Environment.Scenes
newVelocity.Y = direc.y;
newVelocity.Z = direc.z;
m_forcesList.Add(newVelocity);
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
}
#endregion
@ -1163,14 +1271,23 @@ namespace OpenSim.Region.Environment.Scenes
m_updateCount = 0;
}
}
else if (Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02) // physics-related movement
else if ((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02) || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02)) // physics-related movement
{
// Send Terse Update to all clients updates lastPhysPos and m_lastVelocity
// doing the above assures us that we know what we sent the clients last
SendTerseUpdateToAllClients();
m_updateCount = 0;
lastPhysPos = AbsolutePosition;
}
CheckForSignificantMovement();
// followed suggestion from mic bowman. reversed the two lines below.
CheckForBorderCrossing();
CheckForSignificantMovement(); // sends update to the modules.
}
}
@ -1184,11 +1301,16 @@ namespace OpenSim.Region.Environment.Scenes
/// <param name="remoteClient"></param>
public void SendTerseUpdateToClient(IClientAPI remoteClient)
{
m_perfMonMS = System.Environment.TickCount;
LLVector3 pos = m_pos;
LLVector3 vel = Velocity;
LLQuaternion rot = new LLQuaternion(m_bodyRot.x, m_bodyRot.y, m_bodyRot.z, m_bodyRot.w);
remoteClient.SendAvatarTerseUpdate(m_regionHandle, 64096, LocalId, new LLVector3(pos.X, pos.Y, pos.Z),
remoteClient.SendAvatarTerseUpdate(m_regionHandle, (ushort)(m_scene.TimeDilation * (float)ushort.MaxValue), LocalId, new LLVector3(pos.X, pos.Y, pos.Z),
new LLVector3(vel.X, vel.Y, vel.Z), rot);
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
m_scene.AddAgentUpdates(1);
}
/// <summary>
@ -1196,11 +1318,21 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary>
public void SendTerseUpdateToAllClients()
{
m_perfMonMS = System.Environment.TickCount;
m_scene.Broadcast(SendTerseUpdateToClient);
m_lastVelocity = m_velocity;
lastPhysPos = AbsolutePosition;
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
}
public void SendCoarseLocations()
{
m_perfMonMS = System.Environment.TickCount;
List<LLVector3> CoarseLocations = new List<LLVector3>();
List<ScenePresence> avatars = m_scene.GetAvatars();
for (int i = 0; i < avatars.Count; i++)
@ -1212,6 +1344,8 @@ namespace OpenSim.Region.Environment.Scenes
}
m_controllingClient.SendCoarseLocationUpdate(CoarseLocations);
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
}
public void CoarseLocationChange()
@ -1228,6 +1362,7 @@ namespace OpenSim.Region.Environment.Scenes
remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_uuid,
LocalId, m_pos, m_appearance.TextureEntry.ToBytes(),
m_parentID);
m_scene.AddAgentUpdates(1);
}
/// <summary>
@ -1235,19 +1370,23 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary>
public void SendFullUpdateToAllClients()
{
m_perfMonMS = System.Environment.TickCount;
List<ScenePresence> avatars = m_scene.GetScenePresences();
foreach (ScenePresence avatar in avatars)
{
SendFullUpdateToOtherClient(avatar);
if (avatar.LocalId != LocalId)
{
if (!avatar.m_isChildAgent || m_scene.m_sendTasksToChild)
if (!avatar.m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor)
{
avatar.SendFullUpdateToOtherClient(this);
avatar.SendAppearanceToOtherAgent(this);
}
}
}
m_scene.AddAgentUpdates(avatars.Count);
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
}
/// <summary>
@ -1283,6 +1422,8 @@ namespace OpenSim.Region.Environment.Scenes
/// </summary>
public void SendAppearanceToAllOtherAgents()
{
m_perfMonMS=System.Environment.TickCount;
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
{
if (scenePresence.UUID != UUID)
@ -1290,6 +1431,7 @@ namespace OpenSim.Region.Environment.Scenes
m_appearance.SendAppearanceToOtherAgent(scenePresence);
}
});
m_scene.AddAgentTime(System.Environment.TickCount - m_perfMonMS);
}
public void SendAppearanceToOtherAgent(ScenePresence avatar)
@ -1341,12 +1483,36 @@ namespace OpenSim.Region.Environment.Scenes
if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > 0.5)
{
posLastSignificantMove = AbsolutePosition;
if (OnSignificantClientMovement != null)
if (handler001 != null)
{
OnSignificantClientMovement(m_controllingClient);
handler001(m_controllingClient);
m_scene.NotifyMyCoarseLocationChange();
}
}
// Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m
if (Util.GetDistanceTo(AbsolutePosition,m_LastChildAgentUpdatePosition) > 32)
{
ChildAgentDataUpdate cadu = new ChildAgentDataUpdate();
cadu.ActiveGroupID=LLUUID.Zero.UUID;
cadu.AgentID = UUID.UUID;
cadu.alwaysrun = m_setAlwaysRun;
cadu.AVHeight = m_avHeight;
LLVector3 tempCameraCenter = new LLVector3(m_CameraCenter.x, m_CameraCenter.y, m_CameraCenter.z);
cadu.cameraPosition = new sLLVector3(tempCameraCenter);
cadu.drawdistance = m_DrawDistance;
cadu.godlevel = m_godlevel;
cadu.GroupAccess = 0;
cadu.Position = new sLLVector3(AbsolutePosition);
cadu.regionHandle = m_scene.RegionInfo.RegionHandle;
cadu.throttles = ControllingClient.GetThrottlesPacked(1f);
cadu.Velocity = new sLLVector3(Velocity);
m_scene.SendOutChildAgentUpdates(cadu,this);
m_LastChildAgentUpdatePosition.X = AbsolutePosition.X;
m_LastChildAgentUpdatePosition.Y = AbsolutePosition.Y;
m_LastChildAgentUpdatePosition.Z = AbsolutePosition.Z;
}
}
#endregion
@ -1366,12 +1532,12 @@ namespace OpenSim.Region.Environment.Scenes
pos2.Y = pos2.Y + (vel.Y*timeStep);
pos2.Z = pos2.Z + (vel.Z*timeStep);
if ((pos2.X < 0) || (pos2.X > 256))
if ((pos2.X < 0) || (pos2.X > Constants.RegionSize))
{
CrossToNewRegion();
}
if ((pos2.Y < 0) || (pos2.Y > 256))
if ((pos2.Y < 0) || (pos2.Y > Constants.RegionSize))
{
CrossToNewRegion();
}
@ -1396,17 +1562,12 @@ namespace OpenSim.Region.Environment.Scenes
// distance into new region to place avatar
const float enterDistance = 0.1f;
// region size
// TODO: this should be hard-coded in some common place
const float regionWidth = 256;
const float regionHeight = 256;
if (pos.X < boundaryDistance)
{
neighbourx--;
newpos.X = regionWidth - enterDistance;
newpos.X = Constants.RegionSize - enterDistance;
}
else if (pos.X > regionWidth - boundaryDistance)
else if (pos.X > Constants.RegionSize - boundaryDistance)
{
neighbourx++;
newpos.X = enterDistance;
@ -1415,16 +1576,16 @@ namespace OpenSim.Region.Environment.Scenes
if (pos.Y < boundaryDistance)
{
neighboury--;
newpos.Y = regionHeight - enterDistance;
newpos.Y = Constants.RegionSize - enterDistance;
}
else if (pos.Y > regionHeight - boundaryDistance)
else if (pos.Y > Constants.RegionSize - boundaryDistance)
{
neighboury++;
newpos.Y = enterDistance;
}
LLVector3 vel = m_velocity;
ulong neighbourHandle = Helpers.UIntsToLong((uint) (neighbourx*256), (uint) (neighboury*256));
ulong neighbourHandle = Helpers.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
SimpleRegionInfo neighbourRegion = m_scene.RequestNeighbouringRegionInfo(neighbourHandle);
if (neighbourRegion != null)
{
@ -1459,7 +1620,7 @@ namespace OpenSim.Region.Environment.Scenes
adb.AgentID = agentID;
adb.SessionID = sessionID; // More security
gdb.GodLevel = (byte) 100;
gdb.GodLevel = (byte) 250;
gdb.Token = token;
//respondPacket.AgentData = (GrantGodlikePowersPacket.AgentDataBlock)ablock;
respondPacket.GrantData = gdb;
@ -1471,27 +1632,35 @@ namespace OpenSim.Region.Environment.Scenes
/// This updates important decision making data about a child agent
/// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region
/// </summary>
public void ChildAgentDataUpdate(ChildAgentDataUpdate cAgentData)
public void ChildAgentDataUpdate(ChildAgentDataUpdate cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY)
{
//
int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize;
int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize;
m_DrawDistance = cAgentData.drawdistance;
m_pos = new LLVector3(cAgentData.Position.x, cAgentData.Position.y, cAgentData.Position.z);
m_pos = new LLVector3(cAgentData.Position.x + shiftx, cAgentData.Position.y + shifty, cAgentData.Position.z);
// It's hard to say here.. We can't really tell where the camera position is unless it's in world cordinates from the sending region
m_CameraCenter =
new Vector3(cAgentData.cameraPosition.x, cAgentData.cameraPosition.y, cAgentData.cameraPosition.z);
m_godlevel = cAgentData.godlevel;
SetHeight(cAgentData.AVHeight);
ControllingClient.SetChildAgentThrottle(cAgentData.throttles);
// Sends out the objects in the user's draw distance if m_sendTasksToChild is true.
if (m_scene.m_seeIntoRegionFromNeighbor)
m_scene.SendAllSceneObjectsToClient(this);
//cAgentData.AVHeight;
//cAgentData.regionHandle;
//m_velocity = cAgentData.Velocity;
}
/// <summary>
///
/// </summary>
public static void LoadAnims()
{
}
/// <summary>
/// Handles part of the PID controller function for moving an avatar.
/// </summary>
@ -1507,8 +1676,19 @@ namespace OpenSim.Region.Environment.Scenes
NewForce force = m_forcesList[i];
m_updateflag = true;
Velocity = new LLVector3(force.X, force.Y, force.Z);
try
{
movementvector.X = force.X;
movementvector.Y = force.Y;
movementvector.Z = force.Z;
Velocity = movementvector;
}
catch (System.NullReferenceException)
{
// Under extreme load, this returns a NullReference Exception that we can ignore.
// Ignoring this causes no movement to be sent to the physics engine...
// which when the scene is moving at 1 frame every 10 seconds, it doesn't really matter!
}
m_newForce = true;
}
for (int i = 0; i < m_forcesList.Count; i++)
@ -1565,9 +1745,15 @@ namespace OpenSim.Region.Environment.Scenes
PhysicsVector pVec =
new PhysicsVector(AbsolutePosition.X, AbsolutePosition.Y,
AbsolutePosition.Z);
m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec,LocalId); // rex, LocalId added
m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
if (m_avHeight == 127.0f)
{
m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, 1.56f));
}
else
{
m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new PhysicsVector(0, 0, m_avHeight));
}
//m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
}
@ -1580,7 +1766,25 @@ namespace OpenSim.Region.Environment.Scenes
internal void Close()
{
lock (m_knownPrimUUID)
{
m_knownPrimUUID.Clear();
}
lock (m_knownChildRegions)
{
m_knownChildRegions.Clear();
}
lock (m_updateTimes)
{
m_updateTimes.Clear();
}
lock (m_partsUpdateQueue)
{
m_partsUpdateQueue.Clear();
}
RemoveFromPhysicalScene();
GC.Collect();
}
}
}

View File

@ -68,7 +68,7 @@ namespace OpenSim.Region.Environment.Scenes
m_regInfo.RegionHandle, aPrimNode.OuterXml);
if (newIDS)
{
obj.GenerateNewIDs();
obj.ResetIDs();
}
//if we want this to be a import method then we need new uuids for the object to avoid any clashes
//obj.RegenerateFullIDs();
@ -123,6 +123,33 @@ namespace OpenSim.Region.Environment.Scenes
file.Close();
}
public string SavePrimGroupToXML2String(SceneObjectGroup grp)
{
string returnstring = "";
returnstring += "<scene>\n";
returnstring += grp.ToXmlString2();
returnstring += "</scene>\n";
return returnstring;
}
public void LoadGroupFromXml2String(string xmlString)
{
XmlDocument doc = new XmlDocument();
XmlNode rootNode;
XmlTextReader reader = new XmlTextReader(new StringReader(xmlString));
reader.WhitespaceHandling = WhitespaceHandling.None;
doc.Load(reader);
reader.Close();
rootNode = doc.FirstChild;
foreach (XmlNode aPrimNode in rootNode.ChildNodes)
{
CreatePrimFromXml(aPrimNode.OuterXml);
}
}
public void LoadPrimsFromXml2(string fileName)
{
XmlDocument doc = new XmlDocument();
@ -148,6 +175,8 @@ namespace OpenSim.Region.Environment.Scenes
public void CreatePrimFromXml(string xmlData)
{
SceneObjectGroup obj = new SceneObjectGroup(xmlData);
LLVector3 receivedVelocity = obj.RootPart.Velocity;
//System.Console.WriteLine(obj.RootPart.Velocity.ToString());
m_innerScene.AddEntityFromStorage(obj);
SceneObjectPart rootPart = obj.GetChildPart(obj.UUID);
@ -164,7 +193,10 @@ namespace OpenSim.Region.Environment.Scenes
new Quaternion(rootPart.RotationOffset.W, rootPart.RotationOffset.X,
rootPart.RotationOffset.Y, rootPart.RotationOffset.Z), UsePhysics, rootPart.LocalID);
rootPart.DoPhysicsPropertyUpdate(UsePhysics, true);
rootPart.Velocity = receivedVelocity;
}
obj.ScheduleGroupForFullUpdate();
}
public void SavePrimsToXml2(string fileName)

View File

@ -13,7 +13,7 @@
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY

View File

@ -13,7 +13,7 @@
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
@ -44,19 +44,19 @@ namespace OpenSim.Region.Environment.Scenes.Scripting
public string SitName
{
get { return ""; }
get { return String.Empty; }
set { }
}
public string TouchName
{
get { return ""; }
get { return String.Empty; }
set { }
}
public string Description
{
get { return ""; }
get { return String.Empty; }
set { }
}

View File

@ -33,7 +33,7 @@ namespace OpenSim.Region.Environment.Scenes.Scripting
{
public interface ScriptEngineInterface
{
void InitializeEngine(Scene Sceneworld, LogBase logger);
void InitializeEngine(Scene Sceneworld);
void Shutdown();
// void StartScript(string ScriptID, IScriptHost ObjectID);
}

View File

@ -35,12 +35,7 @@ namespace OpenSim.Region.Environment.Scenes.Scripting
{
public class ScriptEngineLoader
{
private LogBase m_log;
public ScriptEngineLoader(LogBase logger)
{
m_log = logger;
}
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public ScriptEngineInterface LoadScriptEngine(string EngineName)
{
@ -54,7 +49,7 @@ namespace OpenSim.Region.Environment.Scenes.Scripting
}
catch (Exception e)
{
m_log.Error("ScriptEngine",
m_log.Error("[ScriptEngine]: " +
"Error loading assembly \"" + EngineName + "\": " + e.Message + ", " +
e.StackTrace.ToString());
}
@ -88,7 +83,7 @@ namespace OpenSim.Region.Environment.Scenes.Scripting
//}
//catch (Exception e)
//{
// m_log.Error("ScriptEngine", "Error loading assembly \"" + FileName + "\": " + e.ToString());
// m_log.Error("[ScriptEngine]: Error loading assembly \String.Empty + FileName + "\": " + e.ToString());
//}
@ -105,7 +100,7 @@ namespace OpenSim.Region.Environment.Scenes.Scripting
//}
//catch (Exception e)
//{
// m_log.Error("ScriptEngine", "Error initializing type \"" + NameSpace + "\" from \"" + FileName + "\": " + e.ToString());
// m_log.Error("[ScriptEngine]: Error initializing type \String.Empty + NameSpace + "\" from \String.Empty + FileName + "\": " + e.ToString());
//}
ScriptEngineInterface ret;
@ -115,7 +110,7 @@ namespace OpenSim.Region.Environment.Scenes.Scripting
//}
//catch (Exception e)
//{
// m_log.Error("ScriptEngine", "Error initializing type \"" + NameSpace + "\" from \"" + FileName + "\": " + e.ToString());
// m_log.Error("[ScriptEngine]: Error initializing type \String.Empty + NameSpace + "\" from \String.Empty + FileName + "\": " + e.ToString());
//}
return ret;

View File

@ -39,26 +39,55 @@ namespace OpenSim.Region.Environment.Scenes
public event SendStatResult OnSendStatsResult;
private SendStatResult handler001 = null;
private enum Stats : uint
{
TimeDilation = 0,
SimFPS = 1,
PhysicsFPS = 2,
AgentUpdates = 3,
FrameMS = 4,
NetMS = 5,
OtherMS = 6,
PhysicsMS = 7,
AgentMS = 8,
ImageMS = 9,
ScriptMS = 10,
TotalPrim = 11,
ActivePrim = 12,
Agents = 13,
ChildAgents = 14,
ActiveScripts = 15,
ScriptLinesPerSecond = 16,
InPacketsPerSecond = 17,
OutPacketsPerSecond = 18,
UnAckedBytes = 24
PendingDownloads = 19,
PendingUploads = 20,
UnAckedBytes = 24,
// Havok4 related... May or may not be in upcoming LLclients
// (kelly added them sometime late in January 2008)
NumRCCSLODReduced = 25,
NumRCCSFixed = 26
}
private int statsUpdatesEveryMS = 1000;
// Sending a stats update every 3 seconds
private int statsUpdatesEveryMS = 3000;
private float statsUpdateFactor = 0;
private float m_timeDilation = 0;
private int m_fps = 0;
private float m_pfps = 0;
private float m_agentUpdates = 0;
private int m_agentUpdates = 0;
private int m_frameMS = 0;
private int m_netMS = 0;
private int m_agentMS = 0;
private int m_physicsMS = 0;
private int m_imageMS = 0;
private int m_otherMS = 0;
private int m_scriptMS = 0;
private int m_rootAgents = 0;
private int m_childAgents = 0;
private int m_numPrim = 0;
@ -66,6 +95,17 @@ namespace OpenSim.Region.Environment.Scenes
private int m_outPacketsPerSecond = 0;
private int m_activePrim = 0;
private int m_unAckedBytes = 0;
private int m_pendingDownloads = 0;
private int m_pendingUploads = 0;
private int m_activeScripts = 0;
private int m_scriptLinesPerSecond = 0;
SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[21];
SimStatsPacket.RegionBlock rb = new SimStatsPacket.RegionBlock();
SimStatsPacket statpack = (SimStatsPacket)PacketPool.Instance.GetPacket(PacketType.SimStats);
private RegionInfo ReportingRegion;
private Timer m_report = new Timer();
@ -73,21 +113,34 @@ namespace OpenSim.Region.Environment.Scenes
public SimStatsReporter(RegionInfo regionData)
{
statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000);
ReportingRegion = regionData;
for (int i = 0; i<21;i++)
{
sb[i] = new SimStatsPacket.StatBlock();
}
m_report.AutoReset = true;
m_report.Interval = statsUpdatesEveryMS;
m_report.Elapsed += new ElapsedEventHandler(statsHeartBeat);
m_report.Enabled = true;
}
public void SetUpdateMS(int ms)
{
statsUpdatesEveryMS = ms;
statsUpdateFactor = (float)(statsUpdatesEveryMS / 1000);
m_report.Interval = statsUpdatesEveryMS;
}
private void statsHeartBeat(object sender, EventArgs e)
{
m_report.Enabled = false;
SimStatsPacket statpack = (SimStatsPacket) PacketPool.Instance.GetPacket(PacketType.SimStats);
// TODO: don't create new blocks if recycling an old packet
SimStatsPacket.StatBlock[] sb = new SimStatsPacket.StatBlock[11];
statpack.Region = new SimStatsPacket.RegionBlock();
// Packet is already initialized and ready for data insert
statpack.Region = rb;
statpack.Region.RegionX = ReportingRegion.RegionLocX;
statpack.Region.RegionY = ReportingRegion.RegionLocY;
try
@ -102,72 +155,102 @@ namespace OpenSim.Region.Environment.Scenes
#region various statistic googly moogly
float simfps = (int) (m_fps*5);
// Our FPS is actually 10fps, so multiplying by 5 to get the amount that people expect there
// 0-50 is pretty close to 0-45
float simfps = (int) ((m_fps * 5));
if (simfps > 45)
simfps = simfps - (simfps - 45);
if (simfps < 0)
simfps = 0;
//if (simfps > 45)
//simfps = simfps - (simfps - 45);
//if (simfps < 0)
//simfps = 0;
float physfps = (m_pfps/statsUpdatesEveryMS);
//
float physfps = ((m_pfps / 1000));
if (physfps > 50)
physfps = physfps - (physfps - 50);
//if (physfps > 600)
//physfps = physfps - (physfps - 600);
if (physfps < 0)
physfps = 0;
#endregion
sb[0] = new SimStatsPacket.StatBlock();
//Our time dilation is 0.91 when we're running a full speed,
// therefore to make sure we get an appropriate range,
// we have to factor in our error. (0.10f * statsUpdateFactor)
// multiplies the fix for the error times the amount of times it'll occur a second
// / 10 divides the value by the number of times the sim heartbeat runs (10fps)
// Then we divide the whole amount by the amount of seconds pass in between stats updates.
sb[0].StatID = (uint) Stats.TimeDilation;
sb[0].StatValue = (m_timeDilation);
sb[0].StatValue = m_timeDilation ; //((((m_timeDilation + (0.10f * statsUpdateFactor)) /10) / statsUpdateFactor));
sb[1] = new SimStatsPacket.StatBlock();
sb[1].StatID = (uint) Stats.SimFPS;
sb[1].StatValue = simfps;
sb[1].StatValue = simfps/statsUpdateFactor;
sb[2] = new SimStatsPacket.StatBlock();
sb[2].StatID = (uint) Stats.PhysicsFPS;
sb[2].StatValue = physfps;
sb[2].StatValue = physfps / statsUpdateFactor;
sb[3] = new SimStatsPacket.StatBlock();
sb[3].StatID = (uint) Stats.AgentUpdates;
sb[3].StatValue = (m_agentUpdates/statsUpdatesEveryMS);
sb[3].StatValue = (m_agentUpdates / statsUpdateFactor);
sb[4] = new SimStatsPacket.StatBlock();
sb[4].StatID = (uint) Stats.Agents;
sb[4].StatValue = m_rootAgents;
sb[5] = new SimStatsPacket.StatBlock();
sb[5].StatID = (uint) Stats.ChildAgents;
sb[5].StatValue = m_childAgents;
sb[6] = new SimStatsPacket.StatBlock();
sb[6].StatID = (uint) Stats.TotalPrim;
sb[6].StatValue = m_numPrim;
sb[7] = new SimStatsPacket.StatBlock();
sb[7].StatID = (uint) Stats.ActivePrim;
sb[7].StatValue = m_activePrim;
sb[8] = new SimStatsPacket.StatBlock();
sb[8].StatID = (uint) Stats.InPacketsPerSecond;
sb[8].StatValue = (int) (m_inPacketsPerSecond/statsUpdatesEveryMS);
sb[8].StatID = (uint)Stats.FrameMS;
sb[8].StatValue = m_frameMS / statsUpdateFactor;
sb[9] = new SimStatsPacket.StatBlock();
sb[9].StatID = (uint) Stats.OutPacketsPerSecond;
sb[9].StatValue = (int) (m_outPacketsPerSecond/statsUpdatesEveryMS);
sb[9].StatID = (uint)Stats.NetMS;
sb[9].StatValue = m_netMS / statsUpdateFactor;
sb[10] = new SimStatsPacket.StatBlock();
sb[10].StatID = (uint) Stats.UnAckedBytes;
sb[10].StatValue = (int) (m_unAckedBytes/statsUpdatesEveryMS);
sb[10].StatID = (uint)Stats.PhysicsMS;
sb[10].StatValue = m_physicsMS / statsUpdateFactor;
sb[11].StatID = (uint)Stats.ImageMS ;
sb[11].StatValue = m_imageMS / statsUpdateFactor;
sb[12].StatID = (uint)Stats.OtherMS;
sb[12].StatValue = m_otherMS / statsUpdateFactor;
sb[13].StatID = (uint)Stats.InPacketsPerSecond;
sb[13].StatValue = (m_inPacketsPerSecond);
sb[14].StatID = (uint)Stats.OutPacketsPerSecond;
sb[14].StatValue = (m_outPacketsPerSecond / statsUpdateFactor);
sb[15].StatID = (uint)Stats.UnAckedBytes;
sb[15].StatValue = m_unAckedBytes;
sb[16].StatID = (uint)Stats.AgentMS;
sb[16].StatValue = m_agentMS / statsUpdateFactor;
sb[17].StatID = (uint)Stats.PendingDownloads;
sb[17].StatValue = m_pendingDownloads;
sb[18].StatID = (uint)Stats.PendingUploads;
sb[18].StatValue = m_pendingUploads;
sb[19].StatID = (uint)Stats.ActiveScripts;
sb[19].StatValue = m_activeScripts;
sb[20].StatID = (uint)Stats.ScriptLinesPerSecond;
sb[20].StatValue = m_scriptLinesPerSecond / statsUpdateFactor;
statpack.Stat = sb;
if (OnSendStatsResult != null)
handler001 = OnSendStatsResult;
if (handler001 != null)
{
OnSendStatsResult(statpack);
handler001(statpack);
}
resetvalues();
m_report.Enabled = true;
@ -175,22 +258,38 @@ namespace OpenSim.Region.Environment.Scenes
private void resetvalues()
{
m_timeDilation = 0;
m_fps = 0;
m_pfps = 0;
m_agentUpdates = 0;
m_inPacketsPerSecond = 0;
m_outPacketsPerSecond = 0;
m_unAckedBytes = 0;
m_scriptLinesPerSecond = 0;
m_frameMS = 0;
m_agentMS = 0;
m_netMS = 0;
m_physicsMS = 0;
m_imageMS = 0;
m_otherMS = 0;
m_scriptMS = 0;
}
public void SetTimeDilation(float td)
{
m_timeDilation = td;
if (m_timeDilation > 1.0f)
m_timeDilation = (m_timeDilation - (m_timeDilation - 0.91f));
# region methods called from Scene
// The majority of these functions are additive
// so that you can easily change the amount of
// seconds in between sim stats updates
if (m_timeDilation < 0)
m_timeDilation = 0.0f;
public void AddTimeDilation(float td)
{
//float tdsetting = td;
//if (tdsetting > 1.0f)
//tdsetting = (tdsetting - (tdsetting - 0.91f));
//if (tdsetting < 0)
//tdsetting = 0.0f;
m_timeDilation = td;
}
public void SetRootAgents(int rootAgents)
@ -223,7 +322,7 @@ namespace OpenSim.Region.Environment.Scenes
m_pfps += frames;
}
public void AddAgentUpdates(float numUpdates)
public void AddAgentUpdates(int numUpdates)
{
m_agentUpdates += numUpdates;
}
@ -242,5 +341,52 @@ namespace OpenSim.Region.Environment.Scenes
{
m_unAckedBytes += numBytes;
}
public void addFrameMS(int ms)
{
m_frameMS += ms;
}
public void addNetMS(int ms)
{
m_netMS += ms;
}
public void addAgentMS(int ms)
{
m_agentMS += ms;
}
public void addPhysicsMS(int ms)
{
m_physicsMS += ms;
}
public void addImageMS(int ms)
{
m_imageMS += ms;
}
public void addOtherMS(int ms)
{
m_otherMS += ms;
}
// private static readonly log4net.ILog m_log
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public void addPendingDownload(int count)
{
m_pendingDownloads += count;
//m_log.InfoFormat("[stats]: Adding {0} to pending downloads to make {1}", count, m_pendingDownloads);
}
public void addScriptLines(int count)
{
m_scriptLinesPerSecond += count;
}
public void SetActiveScripts(int count)
{
m_activeScripts = count;
}
#endregion
}
}