Remove the unmaintained 'CMS' framework, which was really a 'source-control' experiment from 2008.
This hasn't been touched for about 2 years and I haven't being using it. If this is wrong then please let me know.bulletsim
parent
fe471b6424
commit
205b2f7ea4
|
@ -1,161 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// AuraMetaEntity.cs created with MonoDevelop
|
|
||||||
// User: bongiojp at 3:03 PM 8/6/2008
|
|
||||||
//
|
|
||||||
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class AuraMetaEntity : PointMetaEntity
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
//transparency of root part, NOT particle system. Should probably add support for changing particle system transparency.
|
|
||||||
public AuraMetaEntity(Scene scene, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
|
|
||||||
: base(scene, groupPos, transparency)
|
|
||||||
{
|
|
||||||
SetAura(color, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuraMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
|
|
||||||
: base(scene, uuid, groupPos, transparency)
|
|
||||||
{
|
|
||||||
SetAura(color, scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
private float Average(Vector3 values)
|
|
||||||
{
|
|
||||||
return (values.X + values.Y + values.Z)/3f;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public void SetAura(Vector3 color, Vector3 scale)
|
|
||||||
{
|
|
||||||
SetAura(color, Average(scale) * 2.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAura(Vector3 color, float radius)
|
|
||||||
{
|
|
||||||
SceneObjectPart From = m_Entity.RootPart;
|
|
||||||
|
|
||||||
//m_log.Debug("[META ENTITY] BEFORE: radius = " + radius);
|
|
||||||
float burstRadius = 0.1f;
|
|
||||||
Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None;
|
|
||||||
float age = 1.5f;
|
|
||||||
float burstRate = 0.4f;
|
|
||||||
if (radius >= 8.0f)
|
|
||||||
{
|
|
||||||
//float sizeOfObject = radius / 2.0f;
|
|
||||||
burstRadius = (radius - 8.0f)/3f;
|
|
||||||
burstRate = 1.5f;
|
|
||||||
radius = 7.99f;
|
|
||||||
patternFlags = Primitive.ParticleSystem.SourcePattern.Explode;
|
|
||||||
age = 4.0f;
|
|
||||||
}
|
|
||||||
SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetAura(SceneObjectPart From, Vector3 color, float radius, float burstRadius, float age, float burstRate, Primitive.ParticleSystem.SourcePattern patternFlags)
|
|
||||||
{
|
|
||||||
Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
|
|
||||||
//prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
|
|
||||||
// Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
|
|
||||||
//prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
|
|
||||||
// Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
|
|
||||||
prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
|
|
||||||
prules.PartStartColor.G = color.Y;
|
|
||||||
prules.PartStartColor.B = color.Z;
|
|
||||||
prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency
|
|
||||||
prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
|
|
||||||
prules.PartEndColor.G = color.Y;
|
|
||||||
prules.PartEndColor.B = color.Z;
|
|
||||||
prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency
|
|
||||||
/*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE
|
|
||||||
prules.PartStartScaleY = 0.5f;
|
|
||||||
prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE
|
|
||||||
prules.PartEndScaleY = 0.5f;
|
|
||||||
*/
|
|
||||||
prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE
|
|
||||||
prules.PartStartScaleY = radius;
|
|
||||||
prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE
|
|
||||||
prules.PartEndScaleY = radius;
|
|
||||||
prules.PartMaxAge = age; //PSYS_PART_MAX_AGE
|
|
||||||
prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
|
|
||||||
prules.PartAcceleration.Y = 0.0f;
|
|
||||||
prules.PartAcceleration.Z = 0.0f;
|
|
||||||
prules.Pattern = patternFlags; //PSYS_SRC_PATTERN
|
|
||||||
//prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
|
|
||||||
prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE
|
|
||||||
prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT
|
|
||||||
//prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS
|
|
||||||
prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS
|
|
||||||
prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN
|
|
||||||
prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX
|
|
||||||
prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
|
|
||||||
//prules.Target = To; //PSYS_SRC_TARGET_KEY
|
|
||||||
prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
|
|
||||||
prules.AngularVelocity.Y = 0.0f;
|
|
||||||
prules.AngularVelocity.Z = 0.0f;
|
|
||||||
prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
|
|
||||||
prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
|
|
||||||
|
|
||||||
prules.CRC = 1; //activates the particle system??
|
|
||||||
From.AddNewParticleSystem(prules);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// BeamMetaEntity.cs created with MonoDevelop
|
|
||||||
// User: bongiojp at 3:03 PM 8/6/2008
|
|
||||||
//
|
|
||||||
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class BeamMetaEntity : PointMetaEntity
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public BeamMetaEntity(Scene scene, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
|
|
||||||
: base(scene, groupPos, transparency)
|
|
||||||
{
|
|
||||||
SetBeamToUUID(To, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BeamMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
|
|
||||||
: base(scene, uuid, groupPos, transparency)
|
|
||||||
{
|
|
||||||
SetBeamToUUID(To, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public void SetBeamToUUID(SceneObjectPart To, Vector3 color)
|
|
||||||
{
|
|
||||||
SceneObjectPart From = m_Entity.RootPart;
|
|
||||||
//Scale size of particles to distance objects are apart (for better visibility)
|
|
||||||
Vector3 FromPos = From.GetWorldPosition();
|
|
||||||
Vector3 ToPos = From.GetWorldPosition();
|
|
||||||
// UUID toUUID = To.UUID;
|
|
||||||
float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) +
|
|
||||||
Math.Pow(FromPos.X-ToPos.Y, 2) +
|
|
||||||
Math.Pow(FromPos.X-ToPos.Z, 2)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
//float rate = (float) (distance/4f);
|
|
||||||
float rate = 0.5f;
|
|
||||||
float scale = (float) (distance/128f);
|
|
||||||
float speed = (float) (2.0f - distance/128f);
|
|
||||||
|
|
||||||
SetBeamToUUID(From, To, color, rate, scale, speed);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, Vector3 color, float rate, float scale, float speed)
|
|
||||||
{
|
|
||||||
Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
|
|
||||||
//prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
|
|
||||||
// Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
|
|
||||||
prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
|
|
||||||
Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
|
|
||||||
prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
|
|
||||||
prules.PartStartColor.G = color.Y;
|
|
||||||
prules.PartStartColor.B = color.Z;
|
|
||||||
prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency
|
|
||||||
prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
|
|
||||||
prules.PartEndColor.G = color.Y;
|
|
||||||
prules.PartEndColor.B = color.Z;
|
|
||||||
prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency
|
|
||||||
prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE
|
|
||||||
prules.PartStartScaleY = scale;
|
|
||||||
prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE
|
|
||||||
prules.PartEndScaleY = scale;
|
|
||||||
prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE
|
|
||||||
prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
|
|
||||||
prules.PartAcceleration.Y = 0.0f;
|
|
||||||
prules.PartAcceleration.Z = 0.0f;
|
|
||||||
//prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN
|
|
||||||
//prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
|
|
||||||
prules.BurstRate = rate; //PSYS_SRC_BURST_RATE
|
|
||||||
prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT
|
|
||||||
prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS
|
|
||||||
prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN
|
|
||||||
prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX
|
|
||||||
prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
|
|
||||||
prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY
|
|
||||||
prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
|
|
||||||
prules.AngularVelocity.Y = 0.0f;
|
|
||||||
prules.AngularVelocity.Z = 0.0f;
|
|
||||||
prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
|
|
||||||
prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
|
|
||||||
|
|
||||||
prules.CRC = 1; //activates the particle system??
|
|
||||||
From.AddNewParticleSystem(prules);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,756 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// CMController.cs
|
|
||||||
// User: bongiojp
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The controller in a Model-View-Controller framework. This controller catches actions by the avatars, creates work packets, loops through these work packets in a separate thread,
|
|
||||||
/// then dictates to the model how the data should change and dictates to the view which data should be displayed. The main mechanism for interaction is through the simchat system.
|
|
||||||
/// </summary>
|
|
||||||
public class CMController
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue.
|
|
||||||
/// </value>
|
|
||||||
private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>();
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
//bool init = false;
|
|
||||||
int m_channel = -1;
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers.
|
|
||||||
/// </value>
|
|
||||||
IEstateModule m_estateModule = null;
|
|
||||||
|
|
||||||
//These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop)
|
|
||||||
CMModel m_model = null;
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region.
|
|
||||||
/// </value>
|
|
||||||
Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable());
|
|
||||||
State m_state = State.NONE;
|
|
||||||
CMView m_view = null;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="model">
|
|
||||||
/// <see cref="CMModel"/>
|
|
||||||
/// </param>
|
|
||||||
/// <param name="view">
|
|
||||||
/// <see cref="CMView"/>
|
|
||||||
/// </param>
|
|
||||||
/// <param name="scene">
|
|
||||||
/// The first scene to keep track of. <see cref="Scene"/>
|
|
||||||
/// </param>
|
|
||||||
/// <param name="channel">
|
|
||||||
/// The simchat channel number to listen to for instructions <see cref="System.Int32"/>
|
|
||||||
/// </param>
|
|
||||||
public CMController(CMModel model, CMView view, Scene scene, int channel)
|
|
||||||
{
|
|
||||||
m_model = model; m_view = view; m_channel = channel;
|
|
||||||
RegisterNewRegion(scene);
|
|
||||||
Initialize(model, view, scene, channel);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
//------------------------------------------------ EVENTS ----------------------------------------------------//
|
|
||||||
// private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
|
|
||||||
// {
|
|
||||||
// }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Searches in all scenes for a SceneObjectGroup that contains a part with a specific localID. If found, the object is returned. Else null is returned.
|
|
||||||
/// </summary>
|
|
||||||
private SceneObjectGroup GetGroupByPrim(uint localID)
|
|
||||||
{
|
|
||||||
foreach (Object currScene in m_sceneList.Values)
|
|
||||||
{
|
|
||||||
foreach (EntityBase ent in ((Scene)currScene).GetEntities())
|
|
||||||
{
|
|
||||||
if (ent is SceneObjectGroup)
|
|
||||||
{
|
|
||||||
if (((SceneObjectGroup)ent).HasChildPrim(localID))
|
|
||||||
return (SceneObjectGroup)ent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initialize(CMModel model, CMView view, Scene scene, int channel)
|
|
||||||
{
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
m_estateModule = scene.RequestModuleInterface<IEstateModule>();
|
|
||||||
Watchdog.StartThread(MainLoop, "Content Management", ThreadPriority.Normal, true);
|
|
||||||
m_state = State.NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Run in a thread of its own. A endless loop that consumes (or blocks on) and work queue. Thw work queue is filled through client actions.
|
|
||||||
/// </summary>
|
|
||||||
private void MainLoop()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
CMModel model = m_model; CMView view = m_view; int channel = m_channel;
|
|
||||||
Work currentJob = new Work();
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
currentJob = m_WorkQueue.Dequeue();
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request");
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type);
|
|
||||||
switch (currentJob.Type)
|
|
||||||
{
|
|
||||||
case WorkType.NONE:
|
|
||||||
break;
|
|
||||||
case WorkType.OBJECTATTRIBUTECHANGE:
|
|
||||||
ObjectAttributeChanged(model, view, currentJob.LocalId);
|
|
||||||
break;
|
|
||||||
case WorkType.PRIMITIVEADDED:
|
|
||||||
PrimitiveAdded(model, view, currentJob);
|
|
||||||
break;
|
|
||||||
case WorkType.OBJECTDUPLICATED:
|
|
||||||
ObjectDuplicated(model, view, currentJob.LocalId);
|
|
||||||
break;
|
|
||||||
case WorkType.OBJECTKILLED:
|
|
||||||
ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1);
|
|
||||||
break;
|
|
||||||
case WorkType.UNDODID:
|
|
||||||
UndoDid(model, view, currentJob.UUID);
|
|
||||||
break;
|
|
||||||
case WorkType.NEWCLIENT:
|
|
||||||
NewClient(view, (IClientAPI) currentJob.Data1);
|
|
||||||
break;
|
|
||||||
case WorkType.SIMCHAT:
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message);
|
|
||||||
SimChat(model, view, (OSChatMessage) currentJob.Data1, channel);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Watchdog.UpdateThread();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened
|
|
||||||
m_log.ErrorFormat(
|
|
||||||
"[CONTENT MANAGEMENT]: Content management thread terminating with exception. PLEASE REBOOT YOUR SIM - CONTENT MANAGEMENT WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}",
|
|
||||||
e);
|
|
||||||
}
|
|
||||||
|
|
||||||
Watchdog.RemoveThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled.
|
|
||||||
/// </summary>
|
|
||||||
private void NewClient(CMView view, IClientAPI client)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
view.SendMetaEntitiesToNewClient(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop.
|
|
||||||
/// </summary>
|
|
||||||
private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId)
|
|
||||||
{
|
|
||||||
SceneObjectGroup group = null;
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
group = GetGroupByPrim(LocalId);
|
|
||||||
if (group != null)
|
|
||||||
{
|
|
||||||
view.DisplayAuras(model.UpdateNormalEntityEffects(group)); //Might be a normal entity (green aura)
|
|
||||||
m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied.
|
|
||||||
/// </summary>
|
|
||||||
private void ObjectDuplicated(CMModel model, CMView view, uint localId)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
view.DisplayAuras(model.CheckForNewEntitiesMissingAuras(GetGroupByPrim(localId).Scene));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop.
|
|
||||||
/// </summary>
|
|
||||||
private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
view.RemoveOrUpdateDeletedEntity(group);
|
|
||||||
model.RemoveOrUpdateDeletedEntity(group);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop.
|
|
||||||
/// </summary>
|
|
||||||
private void PrimitiveAdded(CMModel model, CMView view, Work currentJob)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
foreach (Object scene in m_sceneList.Values)
|
|
||||||
m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop.
|
|
||||||
/// </summary>
|
|
||||||
private void UndoDid(CMModel model, CMView view, UUID uuid)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid);
|
|
||||||
if (ent != null)
|
|
||||||
view.DisplayEntity(ent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Protected Methods
|
|
||||||
|
|
||||||
protected void GroupBeingDeleted(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!");
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTKILLED;
|
|
||||||
moreWork.Data1 = group.Copy();
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void ObjectDuplicated(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID, UUID GroupID)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTDUPLICATED;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] dup queue");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
|
|
||||||
UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
|
|
||||||
bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTDUPLICATED;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] dup queue");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.NEWCLIENT;
|
|
||||||
moreWork.Data1 = client;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] new client");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void OnUnDid(IClientAPI remoteClient, UUID primId)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.UNDODID;
|
|
||||||
moreWork.UUID = primId;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] undid");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument.
|
|
||||||
/// </summary>
|
|
||||||
protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity(Hashtable sceneList, Scene scene)
|
|
||||||
{
|
|
||||||
int somethingAddedToList = 1;
|
|
||||||
System.Collections.Generic.List<Scene> newList = new List<Scene>();
|
|
||||||
newList.Add(scene);
|
|
||||||
|
|
||||||
if (!sceneList.ContainsValue(scene))
|
|
||||||
{
|
|
||||||
foreach (Object sceneObj in sceneList)
|
|
||||||
newList.Add((Scene) sceneObj);
|
|
||||||
return newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (somethingAddedToList > 0)
|
|
||||||
{
|
|
||||||
somethingAddedToList = 0;
|
|
||||||
for (int i = 0; i < newList.Count; i++)
|
|
||||||
{
|
|
||||||
foreach (Object sceneObj in sceneList.Values)
|
|
||||||
{
|
|
||||||
if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (!newList.Contains((Scene)sceneObj)))
|
|
||||||
{
|
|
||||||
newList.Add((Scene)sceneObj);
|
|
||||||
somethingAddedToList++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Object sceneObj in sceneList.Values)
|
|
||||||
if (!newList.Contains((Scene)sceneObj))
|
|
||||||
newList.Add((Scene)sceneObj);
|
|
||||||
|
|
||||||
return newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
//This is stupid, the same information is contained in the first and second argument
|
|
||||||
protected void SimChatSent(Object x, OSChatMessage e)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!");
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message);
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.SIMCHAT;
|
|
||||||
moreWork.Data1 = e;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions.
|
|
||||||
/// </summary>
|
|
||||||
protected void StartManaging(IClientAPI client)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services.");
|
|
||||||
// client.OnChatFromClient += SimChatSent;
|
|
||||||
//init = true;
|
|
||||||
|
|
||||||
OnNewClient(client);
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client.");
|
|
||||||
client.OnUpdatePrimScale += UpdateSingleScale;
|
|
||||||
client.OnUpdatePrimGroupScale += UpdateMultipleScale;
|
|
||||||
client.OnUpdatePrimGroupPosition += UpdateMultiplePosition;
|
|
||||||
client.OnUpdatePrimSinglePosition += UpdateSinglePosition;
|
|
||||||
client.OnUpdatePrimGroupRotation += UpdateMultipleRotation;
|
|
||||||
client.OnUpdatePrimSingleRotation += UpdateSingleRotation;
|
|
||||||
client.OnAddPrim += UpdateNewParts;
|
|
||||||
client.OnObjectDuplicate += ObjectDuplicated;
|
|
||||||
client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay;
|
|
||||||
client.OnUndo += OnUnDid;
|
|
||||||
//client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
protected void StopManaging(UUID clientUUID)
|
|
||||||
{
|
|
||||||
foreach (Object sceneobj in m_sceneList.Values)
|
|
||||||
{
|
|
||||||
ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID);
|
|
||||||
if (presence != null)
|
|
||||||
{
|
|
||||||
IClientAPI client = presence.ControllingClient;
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services.");
|
|
||||||
// client.OnChatFromViewer -= SimChatSent;
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client");
|
|
||||||
client.OnUpdatePrimScale -= UpdateSingleScale;
|
|
||||||
client.OnUpdatePrimGroupScale -= UpdateMultipleScale;
|
|
||||||
client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition;
|
|
||||||
client.OnUpdatePrimSinglePosition -= UpdateSinglePosition;
|
|
||||||
client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation;
|
|
||||||
client.OnUpdatePrimSingleRotation -= UpdateSingleRotation;
|
|
||||||
client.OnAddPrim -= UpdateNewParts;
|
|
||||||
client.OnObjectDuplicate -= ObjectDuplicated;
|
|
||||||
client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay;
|
|
||||||
client.OnUndo -= OnUnDid;
|
|
||||||
//client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateMultiplePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] pos");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateMultipleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] rot");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateMultipleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT]scale");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateNewParts(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
|
|
||||||
byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
|
|
||||||
byte RayEndIsIntersection)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.PRIMITIVEADDED;
|
|
||||||
moreWork.UUID = ownerID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] new parts");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateSinglePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] move");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
protected void UpdateSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] rot");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void UpdateSingleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
|
|
||||||
{
|
|
||||||
Work moreWork = new Work();
|
|
||||||
moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
|
|
||||||
moreWork.LocalId = localID;
|
|
||||||
m_WorkQueue.Enqueue(moreWork);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] scale");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called from within the SimChat method.
|
|
||||||
/// </summary>
|
|
||||||
protected void commit(string message, Scene scene, CMModel model, CMView view)
|
|
||||||
{
|
|
||||||
System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
|
|
||||||
|
|
||||||
string[] args = message.Split(new char[] {' '});
|
|
||||||
|
|
||||||
char[] logMessage = {' '};
|
|
||||||
if (args.Length > 1)
|
|
||||||
{
|
|
||||||
logMessage = new char[message.Length - (args[0].Length)];
|
|
||||||
message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region.");
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
{
|
|
||||||
model.CommitRegion(currScene, new String(logMessage));
|
|
||||||
view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.SendSimChatMessage(scene, "Successfully saved all regions.");
|
|
||||||
m_state |= State.DIRTY;
|
|
||||||
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES
|
|
||||||
{
|
|
||||||
view.SendSimChatMessage(scene, "Updating differences between new revision and current environment.");
|
|
||||||
//Hide objects from users and Forget about them
|
|
||||||
view.HideAllMetaEntities();
|
|
||||||
view.HideAllAuras();
|
|
||||||
model.DeleteAllMetaObjects();
|
|
||||||
|
|
||||||
//Recreate them from backend files
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
{
|
|
||||||
model.UpdateCMEntities(currScene);
|
|
||||||
view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Display new objects to users1
|
|
||||||
view.DisplayRecentChanges();
|
|
||||||
view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE.");
|
|
||||||
m_state &= ~(State.DIRTY);
|
|
||||||
m_state |= State.SHOWING_CHANGES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called from within the SimChat method.
|
|
||||||
/// </summary>
|
|
||||||
protected void diffmode(Scene scene, CMModel model, CMView view)
|
|
||||||
{
|
|
||||||
System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
|
|
||||||
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF
|
|
||||||
{
|
|
||||||
view.SendSimChatMessage(scene, "Hiding all meta objects.");
|
|
||||||
view.HideAllMetaEntities();
|
|
||||||
view.HideAllAuras();
|
|
||||||
view.SendSimChatMessage(scene, "Diff-mode = OFF");
|
|
||||||
|
|
||||||
m_state &= ~State.SHOWING_CHANGES;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else // TURN ON
|
|
||||||
{
|
|
||||||
if ((m_state & State.DIRTY) != 0 || m_state == State.NONE)
|
|
||||||
{
|
|
||||||
view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision");
|
|
||||||
//Hide objects from users and Forget about them
|
|
||||||
view.HideAllMetaEntities();
|
|
||||||
view.HideAllAuras();
|
|
||||||
model.DeleteAllMetaObjects();
|
|
||||||
//Recreate them from backend files
|
|
||||||
foreach (Object currScene in m_sceneList.Values)
|
|
||||||
model.UpdateCMEntities((Scene) currScene);
|
|
||||||
}
|
|
||||||
else if ((m_state & State.DIRTY) != 0) {
|
|
||||||
view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision");
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
model.UpdateCMEntities(currScene);
|
|
||||||
}
|
|
||||||
|
|
||||||
view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment");
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
model.CheckForNewEntitiesMissingAuras(currScene);
|
|
||||||
view.DisplayRecentChanges();
|
|
||||||
|
|
||||||
view.SendSimChatMessage(scene, "Diff-mode = ON");
|
|
||||||
m_state |= State.SHOWING_CHANGES;
|
|
||||||
m_state &= ~State.DIRTY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called from within the SimChat method. Hides all auras and meta entities,
|
|
||||||
/// retrieves the current scene object list with the most recent revision retrieved from the model for each scene,
|
|
||||||
/// then lets the view update the clients of the new objects.
|
|
||||||
/// </summary>
|
|
||||||
protected void rollback(Scene scene, CMModel model, CMView view)
|
|
||||||
{
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
{
|
|
||||||
view.HideAllAuras();
|
|
||||||
view.HideAllMetaEntities();
|
|
||||||
}
|
|
||||||
|
|
||||||
System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
model.RollbackRegion(currScene);
|
|
||||||
|
|
||||||
if ((m_state & State.DIRTY) != 0)
|
|
||||||
{
|
|
||||||
model.DeleteAllMetaObjects();
|
|
||||||
foreach (Scene currScene in proximitySceneList)
|
|
||||||
model.UpdateCMEntities(currScene);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((m_state & State.SHOWING_CHANGES) > 0)
|
|
||||||
view.DisplayRecentChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Protected Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="scene">
|
|
||||||
/// A <see cref="Scene"/>
|
|
||||||
/// </param>
|
|
||||||
public void RegisterNewRegion(Scene scene)
|
|
||||||
{
|
|
||||||
m_sceneList.Add(scene.RegionInfo.RegionID, scene);
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID);
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System.");
|
|
||||||
|
|
||||||
scene.EventManager.OnNewClient += StartManaging;
|
|
||||||
scene.EventManager.OnChatFromClient += SimChatSent;
|
|
||||||
scene.EventManager.OnRemovePresence += StopManaging;
|
|
||||||
// scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
|
|
||||||
scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command.
|
|
||||||
/// </summary>
|
|
||||||
public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel)
|
|
||||||
{
|
|
||||||
if (e.Channel != channel)
|
|
||||||
return;
|
|
||||||
if (e.Sender == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message);
|
|
||||||
|
|
||||||
IClientAPI client = e.Sender;
|
|
||||||
Scene scene = (Scene) e.Scene;
|
|
||||||
string message = e.Message;
|
|
||||||
string[] args = e.Message.Split(new char[] {' '});
|
|
||||||
|
|
||||||
ScenePresence avatar = scene.GetScenePresence(client.AgentId);
|
|
||||||
|
|
||||||
if (!(m_estateModule.IsManager(avatar.UUID)))
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring.");
|
|
||||||
view.SendSimChatMessage(scene, "You must be an estate manager to perform that action.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args[0])
|
|
||||||
{
|
|
||||||
case "ci":
|
|
||||||
case "commit":
|
|
||||||
commit(message, scene, model, view);
|
|
||||||
break;
|
|
||||||
case "dm":
|
|
||||||
case "diff-mode":
|
|
||||||
diffmode(scene, model, view);
|
|
||||||
break;
|
|
||||||
case "rb":
|
|
||||||
case "rollback":
|
|
||||||
rollback(scene, model, view);
|
|
||||||
break;
|
|
||||||
case "help":
|
|
||||||
m_view.DisplayHelpMenu(scene);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
view.SendSimChatMessage(scene, "Command not found: " + args[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
|
|
||||||
#region Other
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// Used to keep track of whether a list has been produced yet and whether that list is up-to-date compard to latest revision on disk.
|
|
||||||
/// </value>
|
|
||||||
[Flags]
|
|
||||||
private enum State
|
|
||||||
{
|
|
||||||
NONE = 0,
|
|
||||||
DIRTY = 1, // The meta entities may not correctly represent the last revision.
|
|
||||||
SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem.
|
|
||||||
/// </value>
|
|
||||||
private struct Work
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
public Object Data1; //Just space for holding data.
|
|
||||||
public Object Data2; //Just more space for holding data.
|
|
||||||
public uint LocalId; //Convenient
|
|
||||||
public WorkType Type;
|
|
||||||
public UUID UUID; //Convenient
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// Identifies what the data in struct Work should be used for.
|
|
||||||
/// </value>
|
|
||||||
private enum WorkType
|
|
||||||
{
|
|
||||||
NONE,
|
|
||||||
OBJECTATTRIBUTECHANGE,
|
|
||||||
PRIMITIVEADDED,
|
|
||||||
OBJECTDUPLICATED,
|
|
||||||
OBJECTKILLED,
|
|
||||||
UNDODID,
|
|
||||||
NEWCLIENT,
|
|
||||||
SIMCHAT
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Other
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,193 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// CMEntityCollection.cs created with MonoDevelop
|
|
||||||
// User: bongiojp at 10:09 AM 7/7/2008
|
|
||||||
//
|
|
||||||
// Creates, Deletes, Stores ContentManagementEntities
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class CMEntityCollection
|
|
||||||
{
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
// private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
// Any ContentManagementEntities that represent old versions of current SceneObjectGroups or
|
|
||||||
// old versions of deleted SceneObjectGroups will be stored in this hash table.
|
|
||||||
// The UUID keys are from the SceneObjectGroup RootPart UUIDs
|
|
||||||
protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //UUID to ContentManagementEntity
|
|
||||||
|
|
||||||
// SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable
|
|
||||||
// The UUID keys are from the SceneObjectPart that they are supposed to be on.
|
|
||||||
protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //UUID to AuraMetaEntity
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public CMEntityCollection()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public Hashtable Auras
|
|
||||||
{
|
|
||||||
get {return m_NewlyCreatedEntityAura; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Hashtable Entities
|
|
||||||
{
|
|
||||||
get { return m_CMEntityHash; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public bool AddAura(ContentManagementEntity aura)
|
|
||||||
{
|
|
||||||
if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID))
|
|
||||||
return false;
|
|
||||||
m_NewlyCreatedEntityAura.Add(aura.UUID, aura);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool AddEntity(ContentManagementEntity ent)
|
|
||||||
{
|
|
||||||
if (m_CMEntityHash.ContainsKey(ent.UUID))
|
|
||||||
return false;
|
|
||||||
m_CMEntityHash.Add(ent.UUID, ent);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash
|
|
||||||
public System.Collections.ArrayList CheckForMissingEntities(EntityBase[] currList)
|
|
||||||
{
|
|
||||||
System.Collections.ArrayList missingList = new System.Collections.ArrayList();
|
|
||||||
SceneObjectGroup temp = null;
|
|
||||||
foreach (EntityBase currObj in currList)
|
|
||||||
{
|
|
||||||
if (!(currObj is SceneObjectGroup))
|
|
||||||
continue;
|
|
||||||
temp = (SceneObjectGroup) currObj;
|
|
||||||
|
|
||||||
if (m_CMEntityHash.ContainsKey(temp.UUID))
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in temp.Parts)
|
|
||||||
if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
|
|
||||||
missingList.Add(part);
|
|
||||||
}
|
|
||||||
else //Entire group is missing from revision. (and is a new part in region)
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in temp.Parts)
|
|
||||||
missingList.Add(part);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return missingList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearAll()
|
|
||||||
{
|
|
||||||
m_CMEntityHash.Clear();
|
|
||||||
m_NewlyCreatedEntityAura.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Old uuid and new sceneobjectgroup
|
|
||||||
public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part)
|
|
||||||
{
|
|
||||||
AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene,
|
|
||||||
part.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(0,254,0),
|
|
||||||
part.Scale
|
|
||||||
);
|
|
||||||
m_NewlyCreatedEntityAura.Add(part.UUID, ent);
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Old uuid and new sceneobjectgroup
|
|
||||||
public ContentManagementEntity CreateNewEntity(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
ContentManagementEntity ent = new ContentManagementEntity(group, false);
|
|
||||||
m_CMEntityHash.Add(group.UUID, ent);
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentManagementEntity CreateNewEntity(String xml, Scene scene)
|
|
||||||
{
|
|
||||||
ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false);
|
|
||||||
if (ent == null)
|
|
||||||
return null;
|
|
||||||
m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent);
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveEntity(UUID uuid)
|
|
||||||
{
|
|
||||||
if (!m_CMEntityHash.ContainsKey(uuid))
|
|
||||||
return false;
|
|
||||||
m_CMEntityHash.Remove(uuid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool RemoveNewlyCreatedEntityAura(UUID uuid)
|
|
||||||
{
|
|
||||||
if (!m_NewlyCreatedEntityAura.ContainsKey(uuid))
|
|
||||||
return false;
|
|
||||||
m_NewlyCreatedEntityAura.Remove(uuid);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,365 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class CMModel
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
static float TimeToUpdate = 0;
|
|
||||||
static float TimeToConvertXml = 0;
|
|
||||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// The class that contains all auras and metaentities used in the CMS.
|
|
||||||
/// </value>
|
|
||||||
CMEntityCollection m_MetaEntityCollection = new CMEntityCollection();
|
|
||||||
IContentDatabase m_database = null;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public CMModel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public CMEntityCollection MetaEntityCollection
|
|
||||||
{
|
|
||||||
get { return m_MetaEntityCollection; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compares the scene's object group list to the list of meta entities. If there is an object group that does not have a corresponding meta entity
|
|
||||||
/// it is a new part that must have a green aura (for diff mode).
|
|
||||||
/// Returns list of ContentManagementEntities
|
|
||||||
/// </summary>
|
|
||||||
public ArrayList CheckForNewEntitiesMissingAuras(Scene scene)
|
|
||||||
{
|
|
||||||
ArrayList missingList = null;
|
|
||||||
ArrayList newList = new ArrayList();
|
|
||||||
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName);
|
|
||||||
|
|
||||||
//Check if the current scene has groups not included in the current list of MetaEntities
|
|
||||||
//If so, then the current scene's parts that are new should be marked green.
|
|
||||||
missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities());
|
|
||||||
|
|
||||||
foreach (Object missingPart in missingList)
|
|
||||||
{
|
|
||||||
if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID))
|
|
||||||
continue;
|
|
||||||
newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart));
|
|
||||||
}
|
|
||||||
m_log.Info("Number of missing objects found: " + newList.Count);
|
|
||||||
return newList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message.
|
|
||||||
/// </summary>
|
|
||||||
public void CommitRegion(Scene scene, String logMessage)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length);
|
|
||||||
m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage);
|
|
||||||
m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteAllMetaObjects()
|
|
||||||
{
|
|
||||||
m_MetaEntityCollection.ClearAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentManagementEntity FindMetaEntityAffectedByUndo(UUID uuid)
|
|
||||||
{
|
|
||||||
ContentManagementEntity ent = GetMetaGroupByPrim(uuid);
|
|
||||||
return ent;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------- HELPERS --------------------------------------------------------------------//
|
|
||||||
public ContentManagementEntity GetMetaGroupByPrim(UUID uuid)
|
|
||||||
{
|
|
||||||
foreach (Object ent in m_MetaEntityCollection.Entities.Values)
|
|
||||||
{
|
|
||||||
if (((ContentManagementEntity)ent).HasChildPrim(uuid))
|
|
||||||
return (ContentManagementEntity)ent;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(string database)
|
|
||||||
{
|
|
||||||
if (database == "FileSystemDatabase")
|
|
||||||
m_database = new FileSystemDatabase();
|
|
||||||
else if (database == "GitDatabase")
|
|
||||||
m_database = new GitDatabase();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InitialiseDatabase(Scene scene, string dir)
|
|
||||||
{
|
|
||||||
m_database.Initialise(scene, dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should be called just once to finish initializing the database.
|
|
||||||
/// </summary>
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
m_database.PostInitialise();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Removes the green aura when an a new scene object group is deleted.
|
|
||||||
/// </summary>
|
|
||||||
public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
// Deal with new parts not revisioned that have been deleted.
|
|
||||||
SceneObjectPart[] parts = group.Parts;
|
|
||||||
for (int i = 0; i < parts.Length; i++)
|
|
||||||
{
|
|
||||||
if (m_MetaEntityCollection.Auras.ContainsKey(parts[i].UUID))
|
|
||||||
m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(parts[i].UUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves the latest revision of a region in xml form,
|
|
||||||
/// converts it to scene object groups and scene presences,
|
|
||||||
/// swaps the current scene's entity list with the revision's list.
|
|
||||||
/// Note: Since deleted objects while
|
|
||||||
/// </summary>
|
|
||||||
public void RollbackRegion(Scene scene)
|
|
||||||
{
|
|
||||||
System.Collections.ArrayList xmllist = null;
|
|
||||||
SceneObjectGroup temp = null;
|
|
||||||
System.Collections.Hashtable deleteListUUIDs = new Hashtable();
|
|
||||||
// Dictionary<LLUUID, EntityBase> SearchList = new Dictionary<LLUUID,EntityBase>();
|
|
||||||
Dictionary<UUID, EntityBase> ReplacementList = new Dictionary<UUID,EntityBase>();
|
|
||||||
int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID);
|
|
||||||
// EntityBase[] searchArray;
|
|
||||||
|
|
||||||
xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision);
|
|
||||||
if (xmllist == null)
|
|
||||||
{
|
|
||||||
m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ").");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ").");
|
|
||||||
m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count);
|
|
||||||
m_log.Info("[CMMODEL]: Converting scene entities list to specified revision.");
|
|
||||||
|
|
||||||
m_log.ErrorFormat("[CMMODEL]: 1");
|
|
||||||
|
|
||||||
foreach (string xml in xmllist)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
temp = SceneObjectSerializer.FromXml2Format(xml);
|
|
||||||
temp.SetScene(scene);
|
|
||||||
|
|
||||||
SceneObjectPart[] parts = temp.Parts;
|
|
||||||
for (int i = 0; i < parts.Length; i++)
|
|
||||||
parts[i].RegionHandle = scene.RegionInfo.RegionHandle;
|
|
||||||
|
|
||||||
ReplacementList.Add(temp.UUID, (EntityBase)temp);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//If in scene but not in revision and not a client, remove them
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (EntityBase entity in scene.GetEntities())
|
|
||||||
{
|
|
||||||
if (entity == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (entity is ScenePresence)
|
|
||||||
{
|
|
||||||
ReplacementList.Add(entity.UUID, entity);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else //if (!ReplacementList.ContainsKey(entity.UUID))
|
|
||||||
deleteListUUIDs.Add(entity.UUID, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[CMMODEL]: " + e);
|
|
||||||
deleteListUUIDs.Clear();
|
|
||||||
ReplacementList.Clear();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (UUID uuid in deleteListUUIDs.Keys)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles.
|
|
||||||
((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup();
|
|
||||||
scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor);
|
|
||||||
scene.SendKillObject(scene.Entities[uuid].LocalId);
|
|
||||||
scene.SceneGraph.DeleteSceneObject(uuid, false);
|
|
||||||
((SceneObjectGroup)scene.Entities[uuid]).DeleteGroupFromScene(false);
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (scene)
|
|
||||||
{
|
|
||||||
scene.Entities.Clear();
|
|
||||||
|
|
||||||
foreach (KeyValuePair<UUID,EntityBase> kvp in ReplacementList)
|
|
||||||
{
|
|
||||||
scene.Entities.Add(kvp.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (EntityBase ent in ReplacementList.Values)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!(ent is SceneObjectGroup))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) PrimFlags.Phantom) == 0)
|
|
||||||
((SceneObjectGroup)ent).ApplyPhysics(true);
|
|
||||||
((SceneObjectGroup)ent).AttachToBackup();
|
|
||||||
((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected.
|
|
||||||
((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup.");
|
|
||||||
scene.Backup(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences
|
|
||||||
/// and display the differences to clients.
|
|
||||||
/// </summary>
|
|
||||||
public void UpdateCMEntities(Scene scene)
|
|
||||||
{
|
|
||||||
Stopwatch x = new Stopwatch();
|
|
||||||
x.Start();
|
|
||||||
|
|
||||||
System.Collections.ArrayList xmllist = null;
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Retrieving object xml files for region: " + scene.RegionInfo.RegionID);
|
|
||||||
xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID);
|
|
||||||
m_log.Info("[FSDB]: got list");
|
|
||||||
if (xmllist == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Stopwatch y = new Stopwatch();
|
|
||||||
y.Start();
|
|
||||||
foreach (string xml in xmllist)
|
|
||||||
m_MetaEntityCollection.CreateNewEntity(xml, scene);
|
|
||||||
y.Stop();
|
|
||||||
TimeToConvertXml += y.ElapsedMilliseconds;
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds);
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml);
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras");
|
|
||||||
CheckForNewEntitiesMissingAuras(scene);
|
|
||||||
|
|
||||||
x.Stop();
|
|
||||||
TimeToUpdate += x.ElapsedMilliseconds;
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds);
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Detects if a scene object group from the scene list has moved or changed scale. The green aura
|
|
||||||
/// that surrounds the object is then moved or scaled with the group.
|
|
||||||
/// </summary>
|
|
||||||
public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
System.Collections.ArrayList auraList = new System.Collections.ArrayList();
|
|
||||||
if (group == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
SceneObjectPart[] parts = group.Parts;
|
|
||||||
for (int i = 0; i < parts.Length; i++)
|
|
||||||
{
|
|
||||||
SceneObjectPart part = parts[i];
|
|
||||||
if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
|
||||||
{
|
|
||||||
((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0, 254, 0), part.Scale);
|
|
||||||
((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
|
|
||||||
auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return auraList;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,206 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// CMView.cs created with MonoDevelop
|
|
||||||
// User: bongiojp at 11:57 AM 7/3/2008
|
|
||||||
//
|
|
||||||
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class CMView
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
CMModel m_model = null;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public CMView()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
// Auras To
|
|
||||||
public void DisplayAuras(CMEntityCollection auraCollection)
|
|
||||||
{
|
|
||||||
foreach (Object ent in auraCollection.Auras.Values)
|
|
||||||
((AuraMetaEntity)ent).SendFullUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auras To Client
|
|
||||||
public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client)
|
|
||||||
{
|
|
||||||
foreach (Object ent in auraCollection.Auras.Values)
|
|
||||||
((AuraMetaEntity)ent).SendFullUpdate(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auras from List To ALL
|
|
||||||
public void DisplayAuras(ArrayList list)
|
|
||||||
{
|
|
||||||
foreach (Object ent in list)
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW");
|
|
||||||
((AuraMetaEntity)ent).SendFullUpdateToAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entities to ALL
|
|
||||||
public void DisplayEntities(CMEntityCollection entityCollection)
|
|
||||||
{
|
|
||||||
foreach (Object ent in entityCollection.Entities.Values)
|
|
||||||
((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entities to Client
|
|
||||||
public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client)
|
|
||||||
{
|
|
||||||
foreach (Object ent in entityCollection.Entities.Values)
|
|
||||||
((ContentManagementEntity)ent).SendFullDiffUpdate(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entities from List to ALL
|
|
||||||
public void DisplayEntities(ArrayList list)
|
|
||||||
{
|
|
||||||
foreach (Object ent in list)
|
|
||||||
((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entity to ALL
|
|
||||||
public void DisplayEntity(ContentManagementEntity ent)
|
|
||||||
{
|
|
||||||
ent.SendFullDiffUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisplayHelpMenu(Scene scene)
|
|
||||||
{
|
|
||||||
string menu = "Menu:\n";
|
|
||||||
menu += "commit (ci) - saves current state of the region to a database on the server\n";
|
|
||||||
menu += "diff-mode (dm) - displays those aspects of region that have not been saved but changed since the very last revision. Will dynamically update as you change environment.\n";
|
|
||||||
SendSimChatMessage(scene, menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DisplayMetaEntity(UUID uuid)
|
|
||||||
{
|
|
||||||
ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid);
|
|
||||||
if (group != null)
|
|
||||||
group.SendFullDiffUpdateToAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// update all clients of red/green/blue auras and meta entities that the model knows about.
|
|
||||||
/// </summary>
|
|
||||||
public void DisplayRecentChanges()
|
|
||||||
{
|
|
||||||
m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects.");
|
|
||||||
DisplayEntities(m_model.MetaEntityCollection);
|
|
||||||
DisplayAuras(m_model.MetaEntityCollection);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Hide(ContentManagementEntity ent)
|
|
||||||
{
|
|
||||||
ent.HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HideAllAuras()
|
|
||||||
{
|
|
||||||
foreach (Object obj in m_model.MetaEntityCollection.Auras.Values)
|
|
||||||
((MetaEntity)obj).HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HideAllMetaEntities()
|
|
||||||
{
|
|
||||||
foreach (Object obj in m_model.MetaEntityCollection.Entities.Values)
|
|
||||||
((ContentManagementEntity)obj).HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(CMModel model)
|
|
||||||
{
|
|
||||||
m_model = model;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted.
|
|
||||||
/// If it's a new scene object, any green aura attached to it is deleted.
|
|
||||||
/// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will
|
|
||||||
/// figure out that there should be a red aura and not a blue aura/beam.
|
|
||||||
/// </summary>
|
|
||||||
public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
|
|
||||||
{
|
|
||||||
// Deal with revisioned parts that have been deleted.
|
|
||||||
if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID))
|
|
||||||
((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
|
|
||||||
|
|
||||||
// Deal with new parts not revisioned that have been deleted.
|
|
||||||
foreach (SceneObjectPart part in group.Parts)
|
|
||||||
if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
|
|
||||||
((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendMetaEntitiesToNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendSimChatMessage(Scene scene, string message)
|
|
||||||
{
|
|
||||||
scene.SimChat(Utils.StringToBytes(message),
|
|
||||||
ChatTypeEnum.Broadcast, 0, new Vector3(0,0,0), "Content Manager", UUID.Zero, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,375 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class ContentManagementEntity : MetaEntity
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
// static float TimeToDiff = 0;
|
|
||||||
// static float TimeToCreateEntities = 0;
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
protected Dictionary<UUID, AuraMetaEntity> m_AuraEntities = new Dictionary<UUID, AuraMetaEntity>();
|
|
||||||
protected Dictionary<UUID, BeamMetaEntity> m_BeamEntities = new Dictionary<UUID, BeamMetaEntity>();
|
|
||||||
|
|
||||||
// The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different.
|
|
||||||
// This can come in handy.
|
|
||||||
protected SceneObjectGroup m_UnchangedEntity = null;
|
|
||||||
|
|
||||||
/// <value>
|
|
||||||
/// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list.
|
|
||||||
/// </value>
|
|
||||||
bool DiffersFromSceneGroup = false;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics)
|
|
||||||
: base(Unchanged, false)
|
|
||||||
{
|
|
||||||
m_UnchangedEntity = Unchanged.Copy(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ContentManagementEntity(string objectXML, Scene scene, bool physics)
|
|
||||||
: base(objectXML, scene, false)
|
|
||||||
{
|
|
||||||
m_UnchangedEntity = SceneObjectSerializer.FromXml2Format(objectXML);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public SceneObjectGroup UnchangedEntity
|
|
||||||
{
|
|
||||||
get { return m_UnchangedEntity; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if an entitybase list (like that returned by scene.GetEntities()) contains a group with the rootpart uuid that matches the current uuid.
|
|
||||||
/// </summary>
|
|
||||||
private bool ContainsKey(List<EntityBase> list, UUID uuid)
|
|
||||||
{
|
|
||||||
foreach (EntityBase part in list)
|
|
||||||
if (part.UUID == uuid)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, UUID uuid)
|
|
||||||
{
|
|
||||||
foreach (EntityBase ent in list)
|
|
||||||
{
|
|
||||||
if (ent is SceneObjectGroup)
|
|
||||||
if (ent.UUID == uuid)
|
|
||||||
return (SceneObjectGroup)ent;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Search for a corresponding group UUID in the scene. If not found, then the revisioned group this CMEntity represents has been deleted. Mark the metaentity appropriately.
|
|
||||||
/// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately.
|
|
||||||
/// </summary>
|
|
||||||
public void FindDifferences()
|
|
||||||
{
|
|
||||||
List<EntityBase> sceneEntityList = new List<EntityBase>(m_Entity.Scene.GetEntities());
|
|
||||||
DiffersFromSceneGroup = false;
|
|
||||||
// if group is not contained in scene's list
|
|
||||||
if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in m_UnchangedEntity.Parts)
|
|
||||||
{
|
|
||||||
// if scene list no longer contains this part, display translucent part and mark with red aura
|
|
||||||
if (!ContainsKey(sceneEntityList, part.UUID))
|
|
||||||
{
|
|
||||||
// if already displaying a red aura over part, make sure its red
|
|
||||||
if (m_AuraEntities.ContainsKey(part.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[part.UUID].SetAura(new Vector3(254, 0, 0), part.Scale);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
|
||||||
part.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(254, 0, 0),
|
|
||||||
part.Scale
|
|
||||||
);
|
|
||||||
m_AuraEntities.Add(part.UUID, auraGroup);
|
|
||||||
}
|
|
||||||
SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
|
|
||||||
SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
|
|
||||||
}
|
|
||||||
// otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
|
|
||||||
}
|
|
||||||
|
|
||||||
// a deleted part has no where to point a beam particle system,
|
|
||||||
// if a metapart had a particle system (maybe it represented a moved part) remove it
|
|
||||||
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
|
||||||
{
|
|
||||||
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
|
||||||
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
|
||||||
}
|
|
||||||
|
|
||||||
DiffersFromSceneGroup = true;
|
|
||||||
}
|
|
||||||
// if scene list does contain group, compare each part in group for differences and display beams and auras appropriately
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID.
|
|
||||||
/// </summary>
|
|
||||||
public bool HasChildPrim(UUID uuid)
|
|
||||||
{
|
|
||||||
return m_UnchangedEntity.ContainsPart(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
|
|
||||||
/// </summary>
|
|
||||||
public bool HasChildPrim(uint localID)
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in m_UnchangedEntity.Parts)
|
|
||||||
if (part.LocalId == localID)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Hide(IClientAPI client)
|
|
||||||
{
|
|
||||||
base.Hide(client);
|
|
||||||
foreach (MetaEntity group in m_AuraEntities.Values)
|
|
||||||
group.Hide(client);
|
|
||||||
foreach (MetaEntity group in m_BeamEntities.Values)
|
|
||||||
group.Hide(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void HideFromAll()
|
|
||||||
{
|
|
||||||
base.HideFromAll();
|
|
||||||
foreach (MetaEntity group in m_AuraEntities.Values)
|
|
||||||
group.HideFromAll();
|
|
||||||
foreach (MetaEntity group in m_BeamEntities.Values)
|
|
||||||
group.HideFromAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns true if there was a change between meta entity and the entity group, false otherwise.
|
|
||||||
/// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated).
|
|
||||||
/// </summary>
|
|
||||||
public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup)
|
|
||||||
{
|
|
||||||
SceneObjectPart sceneEntityPart;
|
|
||||||
SceneObjectPart metaEntityPart;
|
|
||||||
Diff differences;
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
// Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
|
|
||||||
// had originally saved.
|
|
||||||
// m_Entity will NOT necessarily be the same entity as the user had saved.
|
|
||||||
foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Parts)
|
|
||||||
{
|
|
||||||
//This is the part that we use to show changes.
|
|
||||||
metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
|
|
||||||
if (sceneEntityGroup.ContainsPart(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
sceneEntityPart = sceneEntityGroup.GetChildPart(UnchangedPart.UUID);
|
|
||||||
differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
|
|
||||||
if (differences != Diff.NONE)
|
|
||||||
metaEntityPart.Text = "CHANGE: " + differences.ToString();
|
|
||||||
if (differences != 0)
|
|
||||||
{
|
|
||||||
// Root Part that has been modified
|
|
||||||
if ((differences & Diff.POSITION) > 0)
|
|
||||||
{
|
|
||||||
// If the position of any part has changed, make sure the RootPart of the
|
|
||||||
// meta entity is pointing with a beam particle system
|
|
||||||
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
|
||||||
{
|
|
||||||
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
|
||||||
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
|
||||||
}
|
|
||||||
BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
|
|
||||||
m_UnchangedEntity.RootPart.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
sceneEntityPart,
|
|
||||||
new Vector3(0, 0, 254)
|
|
||||||
);
|
|
||||||
m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
|
||||||
m_AuraEntities.Remove(UnchangedPart.UUID);
|
|
||||||
}
|
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
|
||||||
UnchangedPart.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(0, 0, 254),
|
|
||||||
UnchangedPart.Scale
|
|
||||||
);
|
|
||||||
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
|
|
||||||
SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
|
|
||||||
|
|
||||||
DiffersFromSceneGroup = true;
|
|
||||||
}
|
|
||||||
else // no differences between scene part and meta part
|
|
||||||
{
|
|
||||||
if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
|
|
||||||
{
|
|
||||||
m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
|
|
||||||
m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
|
|
||||||
}
|
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
|
||||||
m_AuraEntities.Remove(UnchangedPart.UUID);
|
|
||||||
}
|
|
||||||
SetPartTransparency(metaEntityPart, MetaEntity.NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
|
|
||||||
{
|
|
||||||
if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
|
|
||||||
{
|
|
||||||
m_AuraEntities[UnchangedPart.UUID].HideFromAll();
|
|
||||||
m_AuraEntities.Remove(UnchangedPart.UUID);
|
|
||||||
}
|
|
||||||
AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
|
|
||||||
UnchangedPart.GetWorldPosition(),
|
|
||||||
MetaEntity.TRANSLUCENT,
|
|
||||||
new Vector3(254, 0, 0),
|
|
||||||
UnchangedPart.Scale
|
|
||||||
);
|
|
||||||
m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
|
|
||||||
SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
|
|
||||||
|
|
||||||
DiffersFromSceneGroup = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullAuraUpdate(IClientAPI client)
|
|
||||||
{
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
foreach (AuraMetaEntity group in m_AuraEntities.Values)
|
|
||||||
group.SendFullUpdate(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullAuraUpdateToAll()
|
|
||||||
{
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
foreach (AuraMetaEntity group in m_AuraEntities.Values)
|
|
||||||
group.SendFullUpdateToAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullBeamUpdate(IClientAPI client)
|
|
||||||
{
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
foreach (BeamMetaEntity group in m_BeamEntities.Values)
|
|
||||||
group.SendFullUpdate(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullBeamUpdateToAll()
|
|
||||||
{
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
foreach (BeamMetaEntity group in m_BeamEntities.Values)
|
|
||||||
group.SendFullUpdateToAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullDiffUpdate(IClientAPI client)
|
|
||||||
{
|
|
||||||
FindDifferences();
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
SendFullUpdate(client);
|
|
||||||
SendFullAuraUpdate(client);
|
|
||||||
SendFullBeamUpdate(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullDiffUpdateToAll()
|
|
||||||
{
|
|
||||||
FindDifferences();
|
|
||||||
if (DiffersFromSceneGroup)
|
|
||||||
{
|
|
||||||
SendFullUpdateToAll();
|
|
||||||
SendFullAuraUpdateToAll();
|
|
||||||
SendFullBeamUpdateToAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,163 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// ContentManagementModule.cs
|
|
||||||
// User: bongiojp
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class ContentManagementModule : IRegionModule
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
bool initialised = false;
|
|
||||||
CMController m_control = null;
|
|
||||||
bool m_enabled = false;
|
|
||||||
CMModel m_model = null;
|
|
||||||
bool m_posted = false;
|
|
||||||
CMView m_view = null;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public bool IsSharedModule
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "ContentManagementModule"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(Scene scene, IConfigSource source)
|
|
||||||
{
|
|
||||||
string databaseDir = "./";
|
|
||||||
string database = "FileSystemDatabase";
|
|
||||||
int channel = 345;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (source.Configs["CMS"] == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_enabled = source.Configs["CMS"].GetBoolean("enabled", false);
|
|
||||||
databaseDir = source.Configs["CMS"].GetString("directory", databaseDir);
|
|
||||||
database = source.Configs["CMS"].GetString("database", database);
|
|
||||||
channel = source.Configs["CMS"].GetInt("channel", channel);
|
|
||||||
|
|
||||||
if (database != "FileSystemDatabase" && database != "GitDatabase")
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[Content Management]: The Database attribute must be defined as either FileSystemDatabase or GitDatabase");
|
|
||||||
m_enabled = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e);
|
|
||||||
m_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_enabled)
|
|
||||||
{
|
|
||||||
m_log.Info("[Content Management]: Content Management System is not Enabled.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
if (!initialised) //only init once
|
|
||||||
{
|
|
||||||
m_view = new CMView();
|
|
||||||
m_model = new CMModel();
|
|
||||||
m_control = new CMController(m_model, m_view, scene, channel);
|
|
||||||
m_model.Initialise(database);
|
|
||||||
m_view.Initialise(m_model);
|
|
||||||
|
|
||||||
initialised = true;
|
|
||||||
m_model.InitialiseDatabase(scene, databaseDir);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_model.InitialiseDatabase(scene, databaseDir);
|
|
||||||
m_control.RegisterNewRegion(scene);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
if (! m_enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
if (!m_posted) //only post once
|
|
||||||
{
|
|
||||||
m_model.PostInitialise();
|
|
||||||
m_posted = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,317 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// FileSystemDatabase.cs
|
|
||||||
// User: bongiojp
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using Slash = System.IO.Path;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
|
||||||
using OpenSim.Region.CoreModules.World.Terrain;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class FileSystemDatabase : IContentDatabase
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
public static float TimeToDownload = 0;
|
|
||||||
public static float TimeToSave = 0;
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
private string m_repodir = null;
|
|
||||||
private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
|
|
||||||
private Dictionary<UUID, IRegionSerialiserModule> m_serialiser = new Dictionary<UUID, IRegionSerialiserModule>();
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public FileSystemDatabase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
// called by postinitialise
|
|
||||||
private void CreateDirectory()
|
|
||||||
{
|
|
||||||
string scenedir;
|
|
||||||
if (!Directory.Exists(m_repodir))
|
|
||||||
Directory.CreateDirectory(m_repodir);
|
|
||||||
|
|
||||||
foreach (UUID region in m_scenes.Keys)
|
|
||||||
{
|
|
||||||
scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar;
|
|
||||||
if (!Directory.Exists(scenedir))
|
|
||||||
Directory.CreateDirectory(scenedir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// called by postinitialise
|
|
||||||
private void SetupSerialiser()
|
|
||||||
{
|
|
||||||
if (m_serialiser.Count == 0)
|
|
||||||
{
|
|
||||||
foreach (UUID region in m_scenes.Keys)
|
|
||||||
{
|
|
||||||
m_serialiser.Add(region, m_scenes[region].RequestModuleInterface<IRegionSerialiserModule>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public int GetMostRecentRevision(UUID regionid)
|
|
||||||
{
|
|
||||||
return NumOfRegionRev(regionid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectHeightMap(UUID regionid)
|
|
||||||
{
|
|
||||||
String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
|
|
||||||
Slash.DirectorySeparatorChar + "heightmap.r32";
|
|
||||||
FileStream fs = new FileStream(filename, FileMode.Open);
|
|
||||||
StreamReader sr = new StreamReader(fs);
|
|
||||||
String result = sr.ReadToEnd();
|
|
||||||
sr.Close();
|
|
||||||
fs.Close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectHeightMap(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
|
|
||||||
Slash.DirectorySeparatorChar + "heightmap.r32";
|
|
||||||
FileStream fs = new FileStream(filename, FileMode.Open);
|
|
||||||
StreamReader sr = new StreamReader(fs);
|
|
||||||
String result = sr.ReadToEnd();
|
|
||||||
sr.Close();
|
|
||||||
fs.Close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
System.Collections.ArrayList objectList = new System.Collections.ArrayList();
|
|
||||||
string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
|
|
||||||
+ revision + Slash.DirectorySeparatorChar + "objects.xml";
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
XmlNode rootNode;
|
|
||||||
//int primCount = 0;
|
|
||||||
//SceneObjectGroup obj = null;
|
|
||||||
|
|
||||||
if (File.Exists(filename))
|
|
||||||
{
|
|
||||||
XmlTextReader reader = new XmlTextReader(filename);
|
|
||||||
reader.WhitespaceHandling = WhitespaceHandling.None;
|
|
||||||
doc.Load(reader);
|
|
||||||
reader.Close();
|
|
||||||
rootNode = doc.FirstChild;
|
|
||||||
foreach (XmlNode aPrimNode in rootNode.ChildNodes)
|
|
||||||
{
|
|
||||||
objectList.Add(aPrimNode.OuterXml);
|
|
||||||
}
|
|
||||||
return objectList;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
|
|
||||||
{
|
|
||||||
int revision = NumOfRegionRev(regionid);
|
|
||||||
m_log.Info("[FSDB]: found revisions:" + revision);
|
|
||||||
System.Collections.ArrayList xmlList = new System.Collections.ArrayList();
|
|
||||||
string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
|
|
||||||
+ revision + Slash.DirectorySeparatorChar + "objects.xml";
|
|
||||||
XmlDocument doc = new XmlDocument();
|
|
||||||
XmlNode rootNode;
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: Checking if " + filename + " exists.");
|
|
||||||
if (File.Exists(filename))
|
|
||||||
{
|
|
||||||
Stopwatch x = new Stopwatch();
|
|
||||||
x.Start();
|
|
||||||
|
|
||||||
XmlTextReader reader = new XmlTextReader(filename);
|
|
||||||
reader.WhitespaceHandling = WhitespaceHandling.None;
|
|
||||||
doc.Load(reader);
|
|
||||||
reader.Close();
|
|
||||||
rootNode = doc.FirstChild;
|
|
||||||
|
|
||||||
foreach (XmlNode aPrimNode in rootNode.ChildNodes)
|
|
||||||
{
|
|
||||||
xmlList.Add(aPrimNode.OuterXml);
|
|
||||||
}
|
|
||||||
|
|
||||||
x.Stop();
|
|
||||||
TimeToDownload += x.ElapsedMilliseconds;
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload);
|
|
||||||
|
|
||||||
return xmlList;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(Scene scene, string dir)
|
|
||||||
{
|
|
||||||
lock (this)
|
|
||||||
{
|
|
||||||
if (m_repodir == null)
|
|
||||||
m_repodir = dir;
|
|
||||||
}
|
|
||||||
lock (m_scenes)
|
|
||||||
m_scenes.Add(scene.RegionInfo.RegionID, scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID regionid)
|
|
||||||
{
|
|
||||||
SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>();
|
|
||||||
|
|
||||||
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
||||||
string[] directories = Directory.GetDirectories(scenedir);
|
|
||||||
|
|
||||||
FileStream fs = null;
|
|
||||||
StreamReader sr = null;
|
|
||||||
String logMessage = "";
|
|
||||||
String logLocation = "";
|
|
||||||
foreach (string revisionDir in directories)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
logLocation = revisionDir + Slash.DirectorySeparatorChar + "log";
|
|
||||||
fs = new FileStream(logLocation, FileMode.Open);
|
|
||||||
sr = new StreamReader(fs);
|
|
||||||
logMessage = sr.ReadToEnd();
|
|
||||||
sr.Close();
|
|
||||||
fs.Close();
|
|
||||||
revisionDict.Add(revisionDir, logMessage);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return revisionDict;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NumOfRegionRev(UUID regionid)
|
|
||||||
{
|
|
||||||
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
||||||
m_log.Info("[FSDB]: Reading scene dir: " + scenedir);
|
|
||||||
string[] directories = Directory.GetDirectories(scenedir);
|
|
||||||
return directories.Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run once and only once.
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
SetupSerialiser();
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: Creating repository in " + m_repodir + ".");
|
|
||||||
CreateDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveRegion(UUID regionid, string regionName, string logMessage)
|
|
||||||
{
|
|
||||||
m_log.Info("[FSDB]: ...............................");
|
|
||||||
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir);
|
|
||||||
if (!Directory.Exists(scenedir))
|
|
||||||
Directory.CreateDirectory(scenedir);
|
|
||||||
|
|
||||||
int newRevisionNum = GetMostRecentRevision(regionid)+1;
|
|
||||||
string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar;
|
|
||||||
|
|
||||||
m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir);
|
|
||||||
if (!Directory.Exists(revisiondir))
|
|
||||||
Directory.CreateDirectory(revisiondir);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Stopwatch x = new Stopwatch();
|
|
||||||
x.Start();
|
|
||||||
if (m_scenes.ContainsKey(regionid))
|
|
||||||
{
|
|
||||||
m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir);
|
|
||||||
}
|
|
||||||
x.Stop();
|
|
||||||
TimeToSave += x.ElapsedMilliseconds;
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds);
|
|
||||||
m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Finish by writing log message.
|
|
||||||
FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite);
|
|
||||||
StreamWriter sw = new StreamWriter(file);
|
|
||||||
sw.Write(logMessage);
|
|
||||||
sw.Close();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// GitDatabase.cs
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using Slash = System.IO.Path;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Xml;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.CoreModules.World.Serialiser;
|
|
||||||
using OpenSim.Region.CoreModules.World.Terrain;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Just a stub :-(
|
|
||||||
/// </summary>
|
|
||||||
public class GitDatabase : IContentDatabase
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public GitDatabase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
public SceneObjectGroup GetMostRecentObjectRevision(UUID id)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetMostRecentRevision(UUID regionid)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneObjectGroup GetObjectRevision(UUID id, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetObjectsFromRegion(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectHeightMap(UUID regionid)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectHeightMap(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectXML(UUID regionid)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetRegionObjectXML(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool InRepository(UUID id)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialise(Scene scene, String dir)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(UUID id)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NumOfObjectRev(UUID id)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int NumOfRegionRev(UUID regionid)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveObject(SceneObjectGroup entity)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SaveRegion(UUID regionid, string regionName, string logMessage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// IContentDatabase.cs
|
|
||||||
// User: bongiojp
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using OpenMetaverse;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public interface IContentDatabase
|
|
||||||
{
|
|
||||||
#region Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the most recent revision number of a region.
|
|
||||||
/// </summary>
|
|
||||||
int GetMostRecentRevision(UUID regionid);
|
|
||||||
|
|
||||||
string GetRegionObjectHeightMap(UUID regionid);
|
|
||||||
|
|
||||||
string GetRegionObjectHeightMap(UUID regionid, int revision);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region.
|
|
||||||
/// </summary>
|
|
||||||
System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid);
|
|
||||||
|
|
||||||
System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database.
|
|
||||||
/// Initialise should be called one for each region to be contained in the database. The directory should be the full path
|
|
||||||
/// to the repository and will only be defined once, regardless of how many times the method is called.
|
|
||||||
/// </summary>
|
|
||||||
void Initialise(Scene scene, String dir);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a list of the revision numbers and corresponding log messages for a given region.
|
|
||||||
/// </summary>
|
|
||||||
System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns the total number of revisions saved for a specific region.
|
|
||||||
/// </summary>
|
|
||||||
int NumOfRegionRev(UUID regionid);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Should be called once after Initialise has been called.
|
|
||||||
/// </summary>
|
|
||||||
void PostInitialise();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Saves the Region terrain map and objects within the region as xml to the database.
|
|
||||||
/// </summary>
|
|
||||||
void SaveRegion(UUID regionid, string regionName, string logMessage);
|
|
||||||
|
|
||||||
#endregion Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,270 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class MetaEntity
|
|
||||||
{
|
|
||||||
#region Constants
|
|
||||||
|
|
||||||
public const float INVISIBLE = .95f;
|
|
||||||
|
|
||||||
// Settings for transparency of metaentity
|
|
||||||
public const float NONE = 0f;
|
|
||||||
public const float TRANSLUCENT = .5f;
|
|
||||||
|
|
||||||
#endregion Constants
|
|
||||||
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
//private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Fields
|
|
||||||
|
|
||||||
protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity.
|
|
||||||
protected uint m_metaLocalid;
|
|
||||||
|
|
||||||
#endregion Fields
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public MetaEntity()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes a new meta entity by copying the given scene object group.
|
|
||||||
/// The physics boolean is just a stub right now.
|
|
||||||
/// </summary>
|
|
||||||
public MetaEntity(SceneObjectGroup orig, bool physics)
|
|
||||||
{
|
|
||||||
m_Entity = orig.Copy(false);
|
|
||||||
Initialize(physics);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Takes an XML description of a scene object group and converts it to a meta entity.
|
|
||||||
/// </summary>
|
|
||||||
public MetaEntity(string objectXML, Scene scene, bool physics)
|
|
||||||
{
|
|
||||||
m_Entity = SceneObjectSerializer.FromXml2Format(objectXML);
|
|
||||||
m_Entity.SetScene(scene);
|
|
||||||
Initialize(physics);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Public Properties
|
|
||||||
|
|
||||||
public SceneObjectPart[] Parts
|
|
||||||
{
|
|
||||||
get { return m_Entity.Parts; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint LocalId
|
|
||||||
{
|
|
||||||
get { return m_Entity.LocalId; }
|
|
||||||
set { m_Entity.LocalId = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneObjectGroup ObjectGroup
|
|
||||||
{
|
|
||||||
get { return m_Entity; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public int PrimCount
|
|
||||||
{
|
|
||||||
get { return m_Entity.PrimCount; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public SceneObjectPart RootPart
|
|
||||||
{
|
|
||||||
get { return m_Entity.RootPart; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Scene Scene
|
|
||||||
{
|
|
||||||
get { return m_Entity.Scene; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID UUID
|
|
||||||
{
|
|
||||||
get { return m_Entity.UUID; }
|
|
||||||
set { m_Entity.UUID = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Properties
|
|
||||||
|
|
||||||
#region Protected Methods
|
|
||||||
|
|
||||||
// The metaentity objectgroup must have unique localids as well as unique uuids.
|
|
||||||
// localids are used by the client to refer to parts.
|
|
||||||
// uuids are sent to the client and back to the server to identify parts on the server side.
|
|
||||||
/// <summary>
|
|
||||||
/// Changes localids and uuids of m_Entity.
|
|
||||||
/// </summary>
|
|
||||||
protected void Initialize(bool physics)
|
|
||||||
{
|
|
||||||
//make new uuids
|
|
||||||
Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
|
|
||||||
|
|
||||||
foreach (SceneObjectPart part in m_Entity.Parts)
|
|
||||||
{
|
|
||||||
part.ResetIDs(part.LinkNum);
|
|
||||||
parts.Add(part.UUID, part);
|
|
||||||
}
|
|
||||||
|
|
||||||
//finalize
|
|
||||||
m_Entity.RootPart.PhysActor = null;
|
|
||||||
foreach (SceneObjectPart part in parts.Values)
|
|
||||||
m_Entity.AddPart(part);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Protected Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Hides the metaentity from a single client.
|
|
||||||
/// </summary>
|
|
||||||
public virtual void Hide(IClientAPI client)
|
|
||||||
{
|
|
||||||
//This deletes the group without removing from any databases.
|
|
||||||
//This is important because we are not IN any database.
|
|
||||||
//m_Entity.FakeDeleteGroup();
|
|
||||||
foreach (SceneObjectPart part in m_Entity.Parts)
|
|
||||||
client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server.
|
|
||||||
/// </summary>
|
|
||||||
public virtual void HideFromAll()
|
|
||||||
{
|
|
||||||
foreach (SceneObjectPart part in m_Entity.Parts)
|
|
||||||
{
|
|
||||||
m_Entity.Scene.ForEachClient(
|
|
||||||
delegate(IClientAPI controller)
|
|
||||||
{ controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullUpdate(IClientAPI client)
|
|
||||||
{
|
|
||||||
// Not sure what clientFlags should be but 0 seems to work
|
|
||||||
SendFullUpdate(client, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullUpdate(IClientAPI client, uint clientFlags)
|
|
||||||
{
|
|
||||||
m_Entity.SendFullUpdateToClient(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SendFullUpdateToAll()
|
|
||||||
{
|
|
||||||
m_Entity.Scene.ForEachClient(
|
|
||||||
delegate(IClientAPI controller)
|
|
||||||
{ m_Entity.SendFullUpdateToClient(controller); }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Makes a single SceneObjectPart see through.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="part">
|
|
||||||
/// A <see cref="SceneObjectPart"/>
|
|
||||||
/// The part to make see through
|
|
||||||
/// </param>
|
|
||||||
/// <param name="transparencyAmount">
|
|
||||||
/// A <see cref="System.Single"/>
|
|
||||||
/// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible.
|
|
||||||
/// </param>
|
|
||||||
public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount)
|
|
||||||
{
|
|
||||||
Primitive.TextureEntry tex = null;
|
|
||||||
Color4 texcolor;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
tex = part.Shape.Textures;
|
|
||||||
texcolor = new Color4();
|
|
||||||
}
|
|
||||||
catch(Exception)
|
|
||||||
{
|
|
||||||
//m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint i = 0; i < tex.FaceTextures.Length; i++)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if (tex.FaceTextures[i] != null)
|
|
||||||
{
|
|
||||||
texcolor = tex.FaceTextures[i].RGBA;
|
|
||||||
texcolor.A = transparencyAmount;
|
|
||||||
tex.FaceTextures[i].RGBA = texcolor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
//m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
texcolor = tex.DefaultTexture.RGBA;
|
|
||||||
texcolor.A = transparencyAmount;
|
|
||||||
tex.DefaultTexture.RGBA = texcolor;
|
|
||||||
part.Shape.TextureEntry = tex.GetBytes();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
//m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,104 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
public class PointMetaEntity : MetaEntity
|
|
||||||
{
|
|
||||||
#region Constructors
|
|
||||||
|
|
||||||
public PointMetaEntity(Scene scene, Vector3 groupPos, float transparency)
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
CreatePointEntity(scene, UUID.Random(), groupPos);
|
|
||||||
SetPartTransparency(m_Entity.RootPart, transparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
public PointMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency)
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
CreatePointEntity(scene, uuid, groupPos);
|
|
||||||
SetPartTransparency(m_Entity.RootPart, transparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Constructors
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos)
|
|
||||||
{
|
|
||||||
SceneObjectPart y = new SceneObjectPart();
|
|
||||||
|
|
||||||
//Initialize part
|
|
||||||
y.Name = "Very Small Point";
|
|
||||||
y.RegionHandle = scene.RegionInfo.RegionHandle;
|
|
||||||
y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
|
|
||||||
y.OwnerID = UUID.Zero;
|
|
||||||
y.CreatorID = UUID.Zero;
|
|
||||||
y.LastOwnerID = UUID.Zero;
|
|
||||||
y.UUID = uuid;
|
|
||||||
|
|
||||||
y.Shape = PrimitiveBaseShape.CreateBox();
|
|
||||||
y.Scale = new Vector3(0.01f,0.01f,0.01f);
|
|
||||||
y.LastOwnerID = UUID.Zero;
|
|
||||||
y.GroupPosition = groupPos;
|
|
||||||
y.OffsetPosition = Vector3.Zero;
|
|
||||||
y.RotationOffset = Quaternion.Identity;
|
|
||||||
y.Velocity = Vector3.Zero;
|
|
||||||
y.AngularVelocity = Vector3.Zero;
|
|
||||||
y.Acceleration = Vector3.Zero;
|
|
||||||
|
|
||||||
y.Flags = 0;
|
|
||||||
y.TrimPermissions();
|
|
||||||
|
|
||||||
//Initialize group and add part as root part
|
|
||||||
SceneObjectGroup x = new SceneObjectGroup(y);
|
|
||||||
x.SetScene(scene);
|
|
||||||
x.RegionHandle = scene.RegionInfo.RegionHandle;
|
|
||||||
x.SetScene(scene);
|
|
||||||
|
|
||||||
m_Entity = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
This module is meant to be built alone and not added to the Opensim code base. References are made to required dlls through a
|
|
||||||
reference file, ContentManagement.mdp. Originally, for development, this project was contained in the Opensim/Region/Modules/
|
|
||||||
directory.
|
|
||||||
|
|
||||||
To compile: nant
|
|
||||||
To use: Copy ContentManagement.dll into the bin directory of your Opensim build. You should find many other dlls in the same directory.
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------------------------------------------
|
|
||||||
To build the libgit.so file:
|
|
||||||
|
|
||||||
#Download GIT git repository
|
|
||||||
$ git clone git://git2.kernel.org/pub/OpenSim/Region/Environment/Modules/ContentManagementSystem/scm/git/git.git
|
|
||||||
$ cd git
|
|
||||||
|
|
||||||
#Compile GIT
|
|
||||||
#Note that we are adding two extra flags to pass to gcc while compiling (-c and -fPIC)
|
|
||||||
$ autoconf
|
|
||||||
$ ./configure
|
|
||||||
$ CFLAGS="-g -O2 -Wall -c -fPIC" make
|
|
||||||
|
|
||||||
#Copy necessary object files (and some not so necessary) to their own directory for shared object file creation
|
|
||||||
$ mkdir ../libgit-objects
|
|
||||||
$ cp builtin*.o ../libgit-objects
|
|
||||||
$ cp xdiff/*.o ../libgit-objects
|
|
||||||
$ cp libgit.a ../libgit-objects
|
|
||||||
|
|
||||||
#Remove the main symbol from any object files (like git.o)
|
|
||||||
$ cd ../libgit-objects
|
|
||||||
$ strip -N main *.o
|
|
||||||
|
|
||||||
#Uncompress the plumbing objects from archive created by git
|
|
||||||
$ ar x libgit.a
|
|
||||||
|
|
||||||
#Create shared object file from all objects (including the zlib library)
|
|
||||||
$ ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o
|
|
||||||
|
|
||||||
|
|
||||||
#You can also just copy the following commands into a file and run as a script inside the git directory
|
|
||||||
|
|
||||||
make clean
|
|
||||||
autoconf
|
|
||||||
./configure
|
|
||||||
CFLAGS="-g -O2 -Wall -c -fPIC" make
|
|
||||||
mkdir libgit-objects
|
|
||||||
cp builtin*.o libgit-objects
|
|
||||||
cp xdiff/*.o libgit-objects
|
|
||||||
cp libgit.a libgit-objects
|
|
||||||
cd libgit-objects
|
|
||||||
strip -N main *.o
|
|
||||||
ar x libgit.a
|
|
||||||
ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o
|
|
|
@ -1,216 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of the OpenSimulator Project nor the
|
|
||||||
* 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
|
|
||||||
* 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
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#region Header
|
|
||||||
|
|
||||||
// SceneObjectGroupDiff.cs
|
|
||||||
// User: bongiojp
|
|
||||||
|
|
||||||
#endregion Header
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using OpenMetaverse;
|
|
||||||
|
|
||||||
using Nini.Config;
|
|
||||||
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
|
||||||
using OpenSim.Region.Framework.Scenes;
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
|
||||||
|
|
||||||
using log4net;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.OptionalModules.ContentManagement
|
|
||||||
{
|
|
||||||
#region Enumerations
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
public enum Diff
|
|
||||||
{
|
|
||||||
NONE = 0,
|
|
||||||
FACECOLOR = 1,
|
|
||||||
SHAPE = 1<<1,
|
|
||||||
MATERIAL = 1<<2,
|
|
||||||
TEXTURE = 1<<3,
|
|
||||||
SCALE = 1<<4,
|
|
||||||
POSITION = 1<<5,
|
|
||||||
OFFSETPOSITION = 1<<6,
|
|
||||||
ROTATIONOFFSET = 1<<7,
|
|
||||||
ROTATIONALVELOCITY = 1<<8,
|
|
||||||
ACCELERATION = 1<<9,
|
|
||||||
ANGULARVELOCITY = 1<<10,
|
|
||||||
VELOCITY = 1<<11,
|
|
||||||
OBJECTOWNER = 1<<12,
|
|
||||||
PERMISSIONS = 1<<13,
|
|
||||||
DESCRIPTION = 1<<14,
|
|
||||||
NAME = 1<<15,
|
|
||||||
SCRIPT = 1<<16,
|
|
||||||
CLICKACTION = 1<<17,
|
|
||||||
PARTICLESYSTEM = 1<<18,
|
|
||||||
GLOW = 1<<19,
|
|
||||||
SALEPRICE = 1<<20,
|
|
||||||
SITNAME = 1<<21,
|
|
||||||
SITTARGETORIENTATION = 1<<22,
|
|
||||||
SITTARGETPOSITION = 1<<23,
|
|
||||||
TEXT = 1<<24,
|
|
||||||
TOUCHNAME = 1<<25
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Enumerations
|
|
||||||
|
|
||||||
public static class Difference
|
|
||||||
{
|
|
||||||
#region Static Fields
|
|
||||||
|
|
||||||
static float TimeToDiff = 0;
|
|
||||||
// private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
||||||
|
|
||||||
#endregion Static Fields
|
|
||||||
|
|
||||||
#region Private Methods
|
|
||||||
|
|
||||||
private static bool AreQuaternionsEquivalent(Quaternion first, Quaternion second)
|
|
||||||
{
|
|
||||||
Vector3 firstVector = llRot2Euler(first);
|
|
||||||
Vector3 secondVector = llRot2Euler(second);
|
|
||||||
return AreVectorsEquivalent(firstVector, secondVector);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static bool AreVectorsEquivalent(Vector3 first, Vector3 second)
|
|
||||||
{
|
|
||||||
if (TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2)
|
|
||||||
&& TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2)
|
|
||||||
&& TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2)
|
|
||||||
)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
|
|
||||||
private static double NormalizeAngle(double angle)
|
|
||||||
{
|
|
||||||
angle = angle % (Math.PI * 2);
|
|
||||||
if (angle < 0) angle = angle + Math.PI * 2;
|
|
||||||
return angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int TruncateSignificant(float num, int digits)
|
|
||||||
{
|
|
||||||
return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits));
|
|
||||||
// return (int) ((num * (10*digits))/10*digits);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
|
|
||||||
// Also changed the original function from LSL_Types to LL types
|
|
||||||
private static Vector3 llRot2Euler(Quaternion r)
|
|
||||||
{
|
|
||||||
Quaternion t = new Quaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W);
|
|
||||||
double m = (t.X + t.Y + t.Z + t.W);
|
|
||||||
if (m == 0) return new Vector3();
|
|
||||||
double n = 2 * (r.Y * r.W + r.X * r.Z);
|
|
||||||
double p = m * m - n * n;
|
|
||||||
if (p > 0)
|
|
||||||
return new Vector3((float)NormalizeAngle(Math.Atan2(2.0 * (r.X * r.W - r.Y * r.Z), (-t.X - t.Y + t.Z + t.W))),
|
|
||||||
(float)NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))),
|
|
||||||
(float)NormalizeAngle(Math.Atan2(2.0 * (r.Z * r.W - r.X * r.Y), (t.X - t.Y - t.Z + t.W))));
|
|
||||||
else if (n > 0)
|
|
||||||
return new Vector3(0.0f, (float)(Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
|
|
||||||
else
|
|
||||||
return new Vector3(0.0f, (float)(-Math.PI / 2), (float)NormalizeAngle(Math.Atan2((r.Z * r.W + r.X * r.Y), 0.5 - t.X - t.Z)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Private Methods
|
|
||||||
|
|
||||||
#region Public Methods
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts
|
|
||||||
/// and returns a Diff bitmask which details what the differences are.
|
|
||||||
/// </summary>
|
|
||||||
public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second)
|
|
||||||
{
|
|
||||||
Stopwatch x = new Stopwatch();
|
|
||||||
x.Start();
|
|
||||||
|
|
||||||
Diff result = 0;
|
|
||||||
|
|
||||||
// VECTOR COMPARISONS
|
|
||||||
if (!AreVectorsEquivalent(first.Acceleration, second.Acceleration))
|
|
||||||
result |= Diff.ACCELERATION;
|
|
||||||
if (!AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition))
|
|
||||||
result |= Diff.POSITION;
|
|
||||||
if (!AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity))
|
|
||||||
result |= Diff.ANGULARVELOCITY;
|
|
||||||
if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition))
|
|
||||||
result |= Diff.OFFSETPOSITION;
|
|
||||||
if (!AreVectorsEquivalent(first.Scale, second.Scale))
|
|
||||||
result |= Diff.SCALE;
|
|
||||||
if (!AreVectorsEquivalent(first.Velocity, second.Velocity))
|
|
||||||
result |= Diff.VELOCITY;
|
|
||||||
|
|
||||||
|
|
||||||
// QUATERNION COMPARISONS
|
|
||||||
if (!AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset))
|
|
||||||
result |= Diff.ROTATIONOFFSET;
|
|
||||||
|
|
||||||
|
|
||||||
// MISC COMPARISONS (UUID, Byte)
|
|
||||||
if (first.ClickAction != second.ClickAction)
|
|
||||||
result |= Diff.CLICKACTION;
|
|
||||||
if (first.OwnerID != second.OwnerID)
|
|
||||||
result |= Diff.OBJECTOWNER;
|
|
||||||
|
|
||||||
|
|
||||||
// STRING COMPARISONS
|
|
||||||
if (first.Description != second.Description)
|
|
||||||
result |= Diff.DESCRIPTION;
|
|
||||||
if (first.Material != second.Material)
|
|
||||||
result |= Diff.MATERIAL;
|
|
||||||
if (first.Name != second.Name)
|
|
||||||
result |= Diff.NAME;
|
|
||||||
if (first.SitName != second.SitName)
|
|
||||||
result |= Diff.SITNAME;
|
|
||||||
if (first.Text != second.Text)
|
|
||||||
result |= Diff.TEXT;
|
|
||||||
if (first.TouchName != second.TouchName)
|
|
||||||
result |= Diff.TOUCHNAME;
|
|
||||||
|
|
||||||
x.Stop();
|
|
||||||
TimeToDiff += x.ElapsedMilliseconds;
|
|
||||||
//m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion Public Methods
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue