aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/ContentManagementSystem
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/ContentManagementSystem')
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs161
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs139
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs757
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs193
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs362
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs206
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs383
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs163
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs317
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs167
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs94
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs274
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs116
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/README52
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs218
15 files changed, 3602 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs
new file mode 100644
index 0000000..d4acc34
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/AuraMetaEntity.cs
@@ -0,0 +1,161 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// AuraMetaEntity.cs created with MonoDevelop
31// User: bongiojp at 3:03 PMĀ 8/6/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections.Generic;
40using System.Drawing;
41
42using OpenMetaverse;
43
44using Nini.Config;
45
46using OpenSim.Framework;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Physics.Manager;
50
51using log4net;
52
53namespace OpenSim.Region.OptionalModules.ContentManagement
54{
55 public class AuraMetaEntity : PointMetaEntity
56 {
57 #region Constructors
58
59 //transparency of root part, NOT particle system. Should probably add support for changing particle system transparency.
60 public AuraMetaEntity(Scene scene, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
61 : base(scene, groupPos, transparency)
62 {
63 SetAura(color, scale);
64 }
65
66 public AuraMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, Vector3 color, Vector3 scale)
67 : base(scene, uuid, groupPos, transparency)
68 {
69 SetAura(color, scale);
70 }
71
72 #endregion Constructors
73
74 #region Private Methods
75
76 private float Average(Vector3 values)
77 {
78 return (values.X + values.Y + values.Z)/3f;
79 }
80
81 #endregion Private Methods
82
83 #region Public Methods
84
85 public void SetAura(Vector3 color, Vector3 scale)
86 {
87 SetAura(color, Average(scale) * 2.0f);
88 }
89
90 public void SetAura(Vector3 color, float radius)
91 {
92 SceneObjectPart From = m_Entity.RootPart;
93
94 //m_log.Debug("[META ENTITY] BEFORE: radius = " + radius);
95 float burstRadius = 0.1f;
96 Primitive.ParticleSystem.SourcePattern patternFlags = Primitive.ParticleSystem.SourcePattern.None;
97 float age = 1.5f;
98 float burstRate = 0.4f;
99 if (radius >= 8.0f)
100 {
101 //float sizeOfObject = radius / 2.0f;
102 burstRadius = (radius - 8.0f)/3f;
103 burstRate = 1.5f;
104 radius = 7.99f;
105 patternFlags = Primitive.ParticleSystem.SourcePattern.Explode;
106 age = 4.0f;
107 }
108 SetAura(From, color, radius, burstRadius, age, burstRate, patternFlags);
109 }
110
111 public void SetAura(SceneObjectPart From, Vector3 color, float radius, float burstRadius, float age, float burstRate, Primitive.ParticleSystem.SourcePattern patternFlags)
112 {
113 Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
114 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
115 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
116 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
117 // Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
118 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
119 prules.PartStartColor.G = color.Y;
120 prules.PartStartColor.B = color.Z;
121 prules.PartStartColor.A = 0.5f; //PSYS_PART_START_ALPHA, transparency
122 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
123 prules.PartEndColor.G = color.Y;
124 prules.PartEndColor.B = color.Z;
125 prules.PartEndColor.A = 0.5f; //PSYS_PART_END_ALPHA, transparency
126 /*prules.PartStartScaleX = 0.5f; //PSYS_PART_START_SCALE
127 prules.PartStartScaleY = 0.5f;
128 prules.PartEndScaleX = 0.5f; //PSYS_PART_END_SCALE
129 prules.PartEndScaleY = 0.5f;
130 */
131 prules.PartStartScaleX = radius; //PSYS_PART_START_SCALE
132 prules.PartStartScaleY = radius;
133 prules.PartEndScaleX = radius; //PSYS_PART_END_SCALE
134 prules.PartEndScaleY = radius;
135 prules.PartMaxAge = age; //PSYS_PART_MAX_AGE
136 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
137 prules.PartAcceleration.Y = 0.0f;
138 prules.PartAcceleration.Z = 0.0f;
139 prules.Pattern = patternFlags; //PSYS_SRC_PATTERN
140 //prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
141 prules.BurstRate = burstRate; //PSYS_SRC_BURST_RATE
142 prules.BurstPartCount = 2; //PSYS_SRC_BURST_PART_COUNT
143 //prules.BurstRadius = radius; //PSYS_SRC_BURST_RADIUS
144 prules.BurstRadius = burstRadius; //PSYS_SRC_BURST_RADIUS
145 prules.BurstSpeedMin = 0.001f; //PSYS_SRC_BURST_SPEED_MIN
146 prules.BurstSpeedMax = 0.001f; //PSYS_SRC_BURST_SPEED_MAX
147 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
148 //prules.Target = To; //PSYS_SRC_TARGET_KEY
149 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
150 prules.AngularVelocity.Y = 0.0f;
151 prules.AngularVelocity.Z = 0.0f;
152 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
153 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
154
155 prules.CRC = 1; //activates the particle system??
156 From.AddNewParticleSystem(prules);
157 }
158
159 #endregion Public Methods
160 }
161}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs
new file mode 100644
index 0000000..c0a0603
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/BeamMetaEntity.cs
@@ -0,0 +1,139 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// BeamMetaEntity.cs created with MonoDevelop
31// User: bongiojp at 3:03 PMĀ 8/6/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections.Generic;
40using System.Drawing;
41
42using OpenMetaverse;
43
44using Nini.Config;
45
46using OpenSim.Framework;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Physics.Manager;
50
51using log4net;
52
53namespace OpenSim.Region.OptionalModules.ContentManagement
54{
55 public class BeamMetaEntity : PointMetaEntity
56 {
57 #region Constructors
58
59 public BeamMetaEntity(Scene scene, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
60 : base(scene, groupPos, transparency)
61 {
62 SetBeamToUUID(To, color);
63 }
64
65 public BeamMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency, SceneObjectPart To, Vector3 color)
66 : base(scene, uuid, groupPos, transparency)
67 {
68 SetBeamToUUID(To, color);
69 }
70
71 #endregion Constructors
72
73 #region Public Methods
74
75 public void SetBeamToUUID(SceneObjectPart To, Vector3 color)
76 {
77 SceneObjectPart From = m_Entity.RootPart;
78 //Scale size of particles to distance objects are apart (for better visibility)
79 Vector3 FromPos = From.GetWorldPosition();
80 Vector3 ToPos = From.GetWorldPosition();
81 // UUID toUUID = To.UUID;
82 float distance = (float) (Math.Sqrt(Math.Pow(FromPos.X-ToPos.X, 2) +
83 Math.Pow(FromPos.X-ToPos.Y, 2) +
84 Math.Pow(FromPos.X-ToPos.Z, 2)
85 )
86 );
87 //float rate = (float) (distance/4f);
88 float rate = 0.5f;
89 float scale = (float) (distance/128f);
90 float speed = (float) (2.0f - distance/128f);
91
92 SetBeamToUUID(From, To, color, rate, scale, speed);
93 }
94
95 public void SetBeamToUUID(SceneObjectPart From, SceneObjectPart To, Vector3 color, float rate, float scale, float speed)
96 {
97 Primitive.ParticleSystem prules = new Primitive.ParticleSystem();
98 //prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Emissive |
99 // Primitive.ParticleSystem.ParticleDataFlags.FollowSrc; //PSYS_PART_FLAGS
100 prules.PartDataFlags = Primitive.ParticleSystem.ParticleDataFlags.Beam |
101 Primitive.ParticleSystem.ParticleDataFlags.TargetPos;
102 prules.PartStartColor.R = color.X; //PSYS_PART_START_COLOR
103 prules.PartStartColor.G = color.Y;
104 prules.PartStartColor.B = color.Z;
105 prules.PartStartColor.A = 1.0f; //PSYS_PART_START_ALPHA, transparency
106 prules.PartEndColor.R = color.X; //PSYS_PART_END_COLOR
107 prules.PartEndColor.G = color.Y;
108 prules.PartEndColor.B = color.Z;
109 prules.PartEndColor.A = 1.0f; //PSYS_PART_END_ALPHA, transparency
110 prules.PartStartScaleX = scale; //PSYS_PART_START_SCALE
111 prules.PartStartScaleY = scale;
112 prules.PartEndScaleX = scale; //PSYS_PART_END_SCALE
113 prules.PartEndScaleY = scale;
114 prules.PartMaxAge = 1.0f; //PSYS_PART_MAX_AGE
115 prules.PartAcceleration.X = 0.0f; //PSYS_SRC_ACCEL
116 prules.PartAcceleration.Y = 0.0f;
117 prules.PartAcceleration.Z = 0.0f;
118 //prules.Pattern = Primitive.ParticleSystem.SourcePattern.Explode; //PSYS_SRC_PATTERN
119 //prules.Texture = UUID.Zero;//= UUID //PSYS_SRC_TEXTURE, default used if blank
120 prules.BurstRate = rate; //PSYS_SRC_BURST_RATE
121 prules.BurstPartCount = 1; //PSYS_SRC_BURST_PART_COUNT
122 prules.BurstRadius = 0.5f; //PSYS_SRC_BURST_RADIUS
123 prules.BurstSpeedMin = speed; //PSYS_SRC_BURST_SPEED_MIN
124 prules.BurstSpeedMax = speed; //PSYS_SRC_BURST_SPEED_MAX
125 prules.MaxAge = 0.0f; //PSYS_SRC_MAX_AGE
126 prules.Target = To.UUID; //PSYS_SRC_TARGET_KEY
127 prules.AngularVelocity.X = 0.0f; //PSYS_SRC_OMEGA
128 prules.AngularVelocity.Y = 0.0f;
129 prules.AngularVelocity.Z = 0.0f;
130 prules.InnerAngle = 0.0f; //PSYS_SRC_ANGLE_BEGIN
131 prules.OuterAngle = 0.0f; //PSYS_SRC_ANGLE_END
132
133 prules.CRC = 1; //activates the particle system??
134 From.AddNewParticleSystem(prules);
135 }
136
137 #endregion Public Methods
138 }
139}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs
new file mode 100644
index 0000000..80989a7
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMController.cs
@@ -0,0 +1,757 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// CMController.cs
31// User: bongiojp
32//
33
34#endregion Header
35
36using System;
37using System.Collections;
38using System.Collections.Generic;
39using System.Diagnostics;
40using System.Threading;
41
42using OpenMetaverse;
43
44using OpenSim;
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 /// <summary>
55 /// 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,
56 /// 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.
57 /// </summary>
58 public class CMController
59 {
60 #region Static Fields
61
62 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
63
64 /// <value>
65 /// The queue that keeps track of which actions have happened. The MainLoop thread eats through this queue.
66 /// </value>
67 private static OpenSim.Framework.BlockingQueue<Work> m_WorkQueue = new OpenSim.Framework.BlockingQueue<Work>();
68
69 #endregion Static Fields
70
71 #region Fields
72
73 //bool init = false;
74 int m_channel = -1;
75
76 /// <value>
77 /// The estate module is used to identify which clients are estateManagers. Presently, the controller only pays attention to estate managers.
78 /// </value>
79 IEstateModule m_estateModule = null;
80
81 //These have to be global variables, threading doesn't allow for passing parameters. (Used in MainLoop)
82 CMModel m_model = null;
83
84 /// <value>
85 /// A list of all the scenes that should be revisioned. Controller is the only class that keeps track of all scenes in the region.
86 /// </value>
87 Hashtable m_sceneList = Hashtable.Synchronized(new Hashtable());
88 State m_state = State.NONE;
89 Thread m_thread = null;
90 CMView m_view = null;
91
92 #endregion Fields
93
94 #region Constructors
95
96 /// <summary>
97 /// Initializes a work thread with an initial scene. Additional scenes should be added through the RegisterNewRegion method.
98 /// </summary>
99 /// <param name="model">
100 /// <see cref="CMModel"/>
101 /// </param>
102 /// <param name="view">
103 /// <see cref="CMView"/>
104 /// </param>
105 /// <param name="scene">
106 /// The first scene to keep track of. <see cref="Scene"/>
107 /// </param>
108 /// <param name="channel">
109 /// The simchat channel number to listen to for instructions <see cref="System.Int32"/>
110 /// </param>
111 public CMController(CMModel model, CMView view, Scene scene, int channel)
112 {
113 m_model = model; m_view = view; m_channel = channel;
114 RegisterNewRegion(scene);
115 Initialize(model, view, scene, channel);
116 }
117
118 #endregion Constructors
119
120 #region Private Methods
121
122 //------------------------------------------------ EVENTS ----------------------------------------------------//
123// private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
124// {
125// }
126
127 /// <summary>
128 /// 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.
129 /// </summary>
130 private SceneObjectGroup GetGroupByPrim(uint localID)
131 {
132 foreach (Object currScene in m_sceneList.Values)
133 {
134 foreach (EntityBase ent in ((Scene)currScene).GetEntities())
135 {
136 if (ent is SceneObjectGroup)
137 {
138 if (((SceneObjectGroup)ent).HasChildPrim(localID))
139 return (SceneObjectGroup)ent;
140 }
141 }
142 }
143 return null;
144 }
145
146 private void Initialize(CMModel model, CMView view, Scene scene, int channel)
147 {
148 lock (this)
149 {
150 m_estateModule = scene.RequestModuleInterface<IEstateModule>();
151 m_thread = new Thread(MainLoop);
152 m_thread.Name = "Content Management";
153 m_thread.IsBackground = true;
154 m_thread.Start();
155 ThreadTracker.Add(m_thread);
156 m_state = State.NONE;
157 }
158 }
159
160 /// <summary>
161 /// 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.
162 /// </summary>
163 private void MainLoop()
164 {
165 try
166 {
167 CMModel model = m_model; CMView view = m_view; int channel = m_channel;
168 Work currentJob = new Work();
169 while (true)
170 {
171 currentJob = m_WorkQueue.Dequeue();
172 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- DeQueued a request");
173 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Work type: " + currentJob.Type);
174 switch (currentJob.Type)
175 {
176 case WorkType.NONE:
177 break;
178 case WorkType.OBJECTATTRIBUTECHANGE:
179 ObjectAttributeChanged(model, view, currentJob.LocalId);
180 break;
181 case WorkType.PRIMITIVEADDED:
182 PrimitiveAdded(model, view, currentJob);
183 break;
184 case WorkType.OBJECTDUPLICATED:
185 ObjectDuplicated(model, view, currentJob.LocalId);
186 break;
187 case WorkType.OBJECTKILLED:
188 ObjectKilled(model, view, (SceneObjectGroup) currentJob.Data1);
189 break;
190 case WorkType.UNDODID:
191 UndoDid(model, view, currentJob.UUID);
192 break;
193 case WorkType.NEWCLIENT:
194 NewClient(view, (IClientAPI) currentJob.Data1);
195 break;
196 case WorkType.SIMCHAT:
197 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- Message received: " + ((OSChatMessage) currentJob.Data1).Message);
198 SimChat(model, view, (OSChatMessage) currentJob.Data1, channel);
199 break;
200 default:
201 m_log.Debug("[CONTENT MANAGEMENT] MAIN LOOP -- uuuuuuuuuh, what?");
202 break;
203 }
204 }
205 }
206 catch (Exception e)
207 {
208 // TODO: Let users in the sim and those entering it and possibly an external watchdog know what has happened
209 m_log.ErrorFormat(
210 "[CONTENT MANAGEMENT]: Content management thread terminating with exception. PLEASE REBOOT YOUR SIM - CONTENT MANAGEMENT WILL NOT BE AVAILABLE UNTIL YOU DO. Exception is {0}",
211 e);
212 }
213 }
214
215 /// <summary>
216 /// Only called by the MainLoop. Updates the view of a new client with metaentities if diff-mode is currently enabled.
217 /// </summary>
218 private void NewClient(CMView view, IClientAPI client)
219 {
220 if ((m_state & State.SHOWING_CHANGES) > 0)
221 view.SendMetaEntitiesToNewClient(client);
222 }
223
224 /// <summary>
225 /// Only called by the MainLoop.
226 /// </summary>
227 private void ObjectAttributeChanged(CMModel model, CMView view, uint LocalId)
228 {
229 SceneObjectGroup group = null;
230 if ((m_state & State.SHOWING_CHANGES) > 0)
231 {
232 group = GetGroupByPrim(LocalId);
233 if (group != null)
234 {
235 view.DisplayAuras(model.UpdateNormalEntityEffects(group)); //Might be a normal entity (green aura)
236 m_view.DisplayMetaEntity(group.UUID); //Might be a meta entity (blue aura)
237 }
238 }
239 }
240
241 /// <summary>
242 /// Only called by the MainLoop. Displays new green auras over the newly created part when a part is shift copied.
243 /// </summary>
244 private void ObjectDuplicated(CMModel model, CMView view, uint localId)
245 {
246 if ((m_state & State.SHOWING_CHANGES) > 0)
247 view.DisplayAuras(model.CheckForNewEntitiesMissingAuras(GetGroupByPrim(localId).Scene));
248 }
249
250 /// <summary>
251 /// Only called by the MainLoop.
252 /// </summary>
253 private void ObjectKilled(CMModel model, CMView view, SceneObjectGroup group)
254 {
255 if ((m_state & State.SHOWING_CHANGES) > 0)
256 {
257 view.RemoveOrUpdateDeletedEntity(group);
258 model.RemoveOrUpdateDeletedEntity(group);
259 }
260 }
261
262 /// <summary>
263 /// Only called by the MainLoop.
264 /// </summary>
265 private void PrimitiveAdded(CMModel model, CMView view, Work currentJob)
266 {
267 if ((m_state & State.SHOWING_CHANGES) > 0)
268 {
269 foreach (Object scene in m_sceneList.Values)
270 m_view.DisplayAuras(model.CheckForNewEntitiesMissingAuras((Scene) scene));
271 }
272 }
273
274 /// <summary>
275 /// Only called by the MainLoop.
276 /// </summary>
277 private void UndoDid(CMModel model, CMView view, UUID uuid)
278 {
279 if ((m_state & State.SHOWING_CHANGES) > 0)
280 {
281 ContentManagementEntity ent = model.FindMetaEntityAffectedByUndo(uuid);
282 if (ent != null)
283 view.DisplayEntity(ent);
284 }
285 }
286
287 #endregion Private Methods
288
289 #region Protected Methods
290
291 protected void GroupBeingDeleted(SceneObjectGroup group)
292 {
293 m_log.Debug("[CONTENT MANAGEMENT] Something was deleted!!!");
294 Work moreWork = new Work();
295 moreWork.Type = WorkType.OBJECTKILLED;
296 moreWork.Data1 = group.Copy();
297 m_WorkQueue.Enqueue(moreWork);
298 }
299
300 protected void ObjectDuplicated(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID, UUID GroupID)
301 {
302 Work moreWork = new Work();
303 moreWork.Type = WorkType.OBJECTDUPLICATED;
304 moreWork.LocalId = localID;
305 m_WorkQueue.Enqueue(moreWork);
306 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
307 }
308
309 protected void ObjectDuplicatedOnRay(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID,
310 UUID RayTargetObj, Vector3 RayEnd, Vector3 RayStart,
311 bool BypassRaycast, bool RayEndIsIntersection, bool CopyCenters, bool CopyRotates)
312 {
313 Work moreWork = new Work();
314 moreWork.Type = WorkType.OBJECTDUPLICATED;
315 moreWork.LocalId = localID;
316 m_WorkQueue.Enqueue(moreWork);
317 m_log.Debug("[CONTENT MANAGEMENT] dup queue");
318 }
319
320 protected void OnNewClient(IClientAPI client)
321 {
322 Work moreWork = new Work();
323 moreWork.Type = WorkType.NEWCLIENT;
324 moreWork.Data1 = client;
325 m_WorkQueue.Enqueue(moreWork);
326 m_log.Debug("[CONTENT MANAGEMENT] new client");
327 }
328
329 protected void OnUnDid(IClientAPI remoteClient, UUID primId)
330 {
331 Work moreWork = new Work();
332 moreWork.Type = WorkType.UNDODID;
333 moreWork.UUID = primId;
334 m_WorkQueue.Enqueue(moreWork);
335 m_log.Debug("[CONTENT MANAGEMENT] undid");
336 }
337
338 /// <summary>
339 /// Takes a list of scenes and forms a new orderd list according to the proximity of scenes to the second argument.
340 /// </summary>
341 protected static System.Collections.Generic.List<Scene> ScenesInOrderOfProximity(Hashtable sceneList, Scene scene)
342 {
343 int somethingAddedToList = 1;
344 System.Collections.Generic.List<Scene> newList = new List<Scene>();
345 newList.Add(scene);
346
347 if (!sceneList.ContainsValue(scene))
348 {
349 foreach (Object sceneObj in sceneList)
350 newList.Add((Scene) sceneObj);
351 return newList;
352 }
353
354 while (somethingAddedToList > 0)
355 {
356 somethingAddedToList = 0;
357 for (int i = 0; i < newList.Count; i++)
358 {
359 foreach (Object sceneObj in sceneList.Values)
360 {
361 if (newList[i].CheckNeighborRegion(((Scene)sceneObj).RegionInfo) && (!newList.Contains((Scene)sceneObj)))
362 {
363 newList.Add((Scene)sceneObj);
364 somethingAddedToList++;
365 }
366 }
367 }
368 }
369
370 foreach (Object sceneObj in sceneList.Values)
371 if (!newList.Contains((Scene)sceneObj))
372 newList.Add((Scene)sceneObj);
373
374 return newList;
375 }
376
377 //This is stupid, the same information is contained in the first and second argument
378 protected void SimChatSent(Object x, OSChatMessage e)
379 {
380 m_log.Debug("[CONTENT MANAGEMENT] SIMCHAT SENT !!!!!!!");
381 m_log.Debug("[CONTENT MANAGEMENT] message was: " + e.Message);
382 Work moreWork = new Work();
383 moreWork.Type = WorkType.SIMCHAT;
384 moreWork.Data1 = e;
385 m_WorkQueue.Enqueue(moreWork);
386 }
387
388 /// <summary>
389 /// Adds extra handlers to a number of events so that the controller can produce work based on the client's actions.
390 /// </summary>
391 protected void StartManaging(IClientAPI client)
392 {
393 m_log.Debug("[CONTENT MANAGEMENT] Registering channel with chat services.");
394 // client.OnChatFromClient += SimChatSent;
395 //init = true;
396
397 OnNewClient(client);
398
399 m_log.Debug("[CONTENT MANAGEMENT] Adding handlers to client.");
400 client.OnUpdatePrimScale += UpdateSingleScale;
401 client.OnUpdatePrimGroupScale += UpdateMultipleScale;
402 client.OnUpdatePrimGroupPosition += UpdateMultiplePosition;
403 client.OnUpdatePrimSinglePosition += UpdateSinglePosition;
404 client.OnUpdatePrimGroupRotation += UpdateMultipleRotation;
405 client.OnUpdatePrimSingleRotation += UpdateSingleRotation;
406 client.OnAddPrim += UpdateNewParts;
407 client.OnObjectDuplicate += ObjectDuplicated;
408 client.OnObjectDuplicateOnRay += ObjectDuplicatedOnRay;
409 client.OnUndo += OnUnDid;
410 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
411 }
412
413 /// <summary>
414 ///
415 /// </summary>
416 protected void StopManaging(UUID clientUUID)
417 {
418 foreach (Object sceneobj in m_sceneList.Values)
419 {
420 ScenePresence presence = ((Scene)sceneobj).GetScenePresence(clientUUID);
421 if (presence != null)
422 {
423 IClientAPI client = presence.ControllingClient;
424 m_log.Debug("[CONTENT MANAGEMENT] Unregistering channel with chat services.");
425 // client.OnChatFromViewer -= SimChatSent;
426
427 m_log.Debug("[CONTENT MANAGEMENT] Removing handlers to client");
428 client.OnUpdatePrimScale -= UpdateSingleScale;
429 client.OnUpdatePrimGroupScale -= UpdateMultipleScale;
430 client.OnUpdatePrimGroupPosition -= UpdateMultiplePosition;
431 client.OnUpdatePrimSinglePosition -= UpdateSinglePosition;
432 client.OnUpdatePrimGroupRotation -= UpdateMultipleRotation;
433 client.OnUpdatePrimSingleRotation -= UpdateSingleRotation;
434 client.OnAddPrim -= UpdateNewParts;
435 client.OnObjectDuplicate -= ObjectDuplicated;
436 client.OnObjectDuplicateOnRay -= ObjectDuplicatedOnRay;
437 client.OnUndo -= OnUnDid;
438 //client.OnUpdatePrimGroupMouseRotation += m_innerScene.UpdatePrimRotation;
439 return;
440 }
441 }
442 }
443
444 protected void UpdateMultiplePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
445 {
446 Work moreWork = new Work();
447 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
448 moreWork.LocalId = localID;
449 m_WorkQueue.Enqueue(moreWork);
450 m_log.Debug("[CONTENT MANAGEMENT] pos");
451 }
452
453 protected void UpdateMultipleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
454 {
455 Work moreWork = new Work();
456 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
457 moreWork.LocalId = localID;
458 m_WorkQueue.Enqueue(moreWork);
459 m_log.Debug("[CONTENT MANAGEMENT] rot");
460 }
461
462 protected void UpdateMultipleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
463 {
464 Work moreWork = new Work();
465 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
466 moreWork.LocalId = localID;
467 m_WorkQueue.Enqueue(moreWork);
468 m_log.Debug("[CONTENT MANAGEMENT]scale");
469 }
470
471 protected void UpdateNewParts(UUID ownerID, UUID groupID, Vector3 RayEnd, Quaternion rot, PrimitiveBaseShape shape,
472 byte bypassRaycast, Vector3 RayStart, UUID RayTargetID,
473 byte RayEndIsIntersection)
474 {
475 Work moreWork = new Work();
476 moreWork.Type = WorkType.PRIMITIVEADDED;
477 moreWork.UUID = ownerID;
478 m_WorkQueue.Enqueue(moreWork);
479 m_log.Debug("[CONTENT MANAGEMENT] new parts");
480 }
481
482 protected void UpdateSinglePosition(uint localID, Vector3 pos, IClientAPI remoteClient)
483 {
484 Work moreWork = new Work();
485 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
486 moreWork.LocalId = localID;
487 m_WorkQueue.Enqueue(moreWork);
488 m_log.Debug("[CONTENT MANAGEMENT] move");
489 }
490
491 /// <summary>
492 ///
493 /// </summary>
494 protected void UpdateSingleRotation(uint localID, Quaternion rot, IClientAPI remoteClient)
495 {
496 Work moreWork = new Work();
497 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
498 moreWork.LocalId = localID;
499 m_WorkQueue.Enqueue(moreWork);
500 m_log.Debug("[CONTENT MANAGEMENT] rot");
501 }
502
503 protected void UpdateSingleScale(uint localID, Vector3 scale, IClientAPI remoteClient)
504 {
505 Work moreWork = new Work();
506 moreWork.Type = WorkType.OBJECTATTRIBUTECHANGE;
507 moreWork.LocalId = localID;
508 m_WorkQueue.Enqueue(moreWork);
509 m_log.Debug("[CONTENT MANAGEMENT] scale");
510 }
511
512 /// <summary>
513 /// Only called from within the SimChat method.
514 /// </summary>
515 protected void commit(string message, Scene scene, CMModel model, CMView view)
516 {
517 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
518
519 string[] args = message.Split(new char[] {' '});
520
521 char[] logMessage = {' '};
522 if (args.Length > 1)
523 {
524 logMessage = new char[message.Length - (args[0].Length)];
525 message.CopyTo(args[0].Length, logMessage, 0, message.Length - (args[0].Length));
526 }
527
528 m_log.Debug("[CONTENT MANAGEMENT] Saving terrain and objects of region.");
529 foreach (Scene currScene in proximitySceneList)
530 {
531 model.CommitRegion(currScene, new String(logMessage));
532 view.SendSimChatMessage(scene, "Region Saved Successfully: " + currScene.RegionInfo.RegionName);
533 }
534
535 view.SendSimChatMessage(scene, "Successfully saved all regions.");
536 m_state |= State.DIRTY;
537
538 if ((m_state & State.SHOWING_CHANGES) > 0) //DISPLAY NEW CHANGES INSTEAD OF OLD CHANGES
539 {
540 view.SendSimChatMessage(scene, "Updating differences between new revision and current environment.");
541 //Hide objects from users and Forget about them
542 view.HideAllMetaEntities();
543 view.HideAllAuras();
544 model.DeleteAllMetaObjects();
545
546 //Recreate them from backend files
547 foreach (Scene currScene in proximitySceneList)
548 {
549 model.UpdateCMEntities(currScene);
550 view.SendSimChatMessage(scene, "Finished updating differences between current scene and last revision: " + currScene.RegionInfo.RegionName);
551 }
552
553 //Display new objects to users1
554 view.DisplayRecentChanges();
555 view.SendSimChatMessage(scene, "Finished updating for DIFF-MODE.");
556 m_state &= ~(State.DIRTY);
557 m_state |= State.SHOWING_CHANGES;
558 }
559 }
560
561 /// <summary>
562 /// Only called from within the SimChat method.
563 /// </summary>
564 protected void diffmode(Scene scene, CMModel model, CMView view)
565 {
566 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
567
568 if ((m_state & State.SHOWING_CHANGES) > 0) // TURN OFF
569 {
570 view.SendSimChatMessage(scene, "Hiding all meta objects.");
571 view.HideAllMetaEntities();
572 view.HideAllAuras();
573 view.SendSimChatMessage(scene, "Diff-mode = OFF");
574
575 m_state &= ~State.SHOWING_CHANGES;
576 return;
577 }
578 else // TURN ON
579 {
580 if ((m_state & State.DIRTY) != 0 || m_state == State.NONE)
581 {
582 view.SendSimChatMessage(scene, "Hiding meta objects and replacing with latest revision");
583 //Hide objects from users and Forget about them
584 view.HideAllMetaEntities();
585 view.HideAllAuras();
586 model.DeleteAllMetaObjects();
587 //Recreate them from backend files
588 foreach (Object currScene in m_sceneList.Values)
589 model.UpdateCMEntities((Scene) currScene);
590 }
591 else if ((m_state & State.DIRTY) != 0) {
592 view.SendSimChatMessage(scene, "Forming list of meta entities with latest revision");
593 foreach (Scene currScene in proximitySceneList)
594 model.UpdateCMEntities(currScene);
595 }
596
597 view.SendSimChatMessage(scene, "Displaying differences between last revision and current environment");
598 foreach (Scene currScene in proximitySceneList)
599 model.CheckForNewEntitiesMissingAuras(currScene);
600 view.DisplayRecentChanges();
601
602 view.SendSimChatMessage(scene, "Diff-mode = ON");
603 m_state |= State.SHOWING_CHANGES;
604 m_state &= ~State.DIRTY;
605 }
606 }
607
608 /// <summary>
609 /// Only called from within the SimChat method. Hides all auras and meta entities,
610 /// retrieves the current scene object list with the most recent revision retrieved from the model for each scene,
611 /// then lets the view update the clients of the new objects.
612 /// </summary>
613 protected void rollback(Scene scene, CMModel model, CMView view)
614 {
615 if ((m_state & State.SHOWING_CHANGES) > 0)
616 {
617 view.HideAllAuras();
618 view.HideAllMetaEntities();
619 }
620
621 System.Collections.Generic.List<Scene> proximitySceneList = ScenesInOrderOfProximity(m_sceneList, scene);
622 foreach (Scene currScene in proximitySceneList)
623 model.RollbackRegion(currScene);
624
625 if ((m_state & State.DIRTY) != 0)
626 {
627 model.DeleteAllMetaObjects();
628 foreach (Scene currScene in proximitySceneList)
629 model.UpdateCMEntities(currScene);
630 }
631
632 if ((m_state & State.SHOWING_CHANGES) > 0)
633 view.DisplayRecentChanges();
634 }
635
636 #endregion Protected Methods
637
638 #region Public Methods
639
640 /// <summary>
641 /// Register a new scene object to keep track of for revisioning. Starts the controller monitoring actions of clients within the given scene.
642 /// </summary>
643 /// <param name="scene">
644 /// A <see cref="Scene"/>
645 /// </param>
646 public void RegisterNewRegion(Scene scene)
647 {
648 m_sceneList.Add(scene.RegionInfo.RegionID, scene);
649
650 m_log.Debug("[CONTENT MANAGEMENT] Registering new region: " + scene.RegionInfo.RegionID);
651 m_log.Debug("[CONTENT MANAGEMENT] Initializing Content Management System.");
652
653 scene.EventManager.OnNewClient += StartManaging;
654 scene.EventManager.OnChatFromClient += SimChatSent;
655 scene.EventManager.OnRemovePresence += StopManaging;
656 // scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
657 scene.EventManager.OnObjectBeingRemovedFromScene += GroupBeingDeleted;
658 }
659
660 /// <summary>
661 /// Only called by the MainLoop. Takes the message from a user sent to the channel and executes the proper command.
662 /// </summary>
663 public void SimChat(CMModel model, CMView view, OSChatMessage e, int channel)
664 {
665 if (e.Channel != channel)
666 return;
667 if (e.Sender == null)
668 return;
669
670 m_log.Debug("[CONTENT MANAGEMENT] Message received: " + e.Message);
671
672 IClientAPI client = e.Sender;
673 Scene scene = (Scene) e.Scene;
674 string message = e.Message;
675 string[] args = e.Message.Split(new char[] {' '});
676
677 ScenePresence avatar = scene.GetScenePresence(client.AgentId);
678
679 if (!(m_estateModule.IsManager(avatar.UUID)))
680 {
681 m_log.Debug("[CONTENT MANAGEMENT] Message sent from non Estate Manager ... ignoring.");
682 view.SendSimChatMessage(scene, "You must be an estate manager to perform that action.");
683 return;
684 }
685
686 switch (args[0])
687 {
688 case "ci":
689 case "commit":
690 commit(message, scene, model, view);
691 break;
692 case "dm":
693 case "diff-mode":
694 diffmode(scene, model, view);
695 break;
696 case "rb":
697 case "rollback":
698 rollback(scene, model, view);
699 break;
700 case "help":
701 m_view.DisplayHelpMenu(scene);
702 break;
703 default:
704 view.SendSimChatMessage(scene, "Command not found: " + args[0]);
705 break;
706 }
707 }
708
709 #endregion Public Methods
710
711 #region Other
712
713 /// <value>
714 /// 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.
715 /// </value>
716 [Flags]
717 private enum State
718 {
719 NONE = 0,
720 DIRTY = 1, // The meta entities may not correctly represent the last revision.
721 SHOWING_CHANGES = 1<<1 // The meta entities are being shown to user.
722 }
723
724 /// <value>
725 /// The structure that defines the basic unit of work which is produced when a user sends commands to the ContentMangaementSystem.
726 /// </value>
727 private struct Work
728 {
729 #region Fields
730
731 public Object Data1; //Just space for holding data.
732 public Object Data2; //Just more space for holding data.
733 public uint LocalId; //Convenient
734 public WorkType Type;
735 public UUID UUID; //Convenient
736
737 #endregion Fields
738 }
739
740 /// <value>
741 /// Identifies what the data in struct Work should be used for.
742 /// </value>
743 private enum WorkType
744 {
745 NONE,
746 OBJECTATTRIBUTECHANGE,
747 PRIMITIVEADDED,
748 OBJECTDUPLICATED,
749 OBJECTKILLED,
750 UNDODID,
751 NEWCLIENT,
752 SIMCHAT
753 }
754
755 #endregion Other
756 }
757}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
new file mode 100644
index 0000000..d5cf596
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMEntityCollection.cs
@@ -0,0 +1,193 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// CMEntityCollection.cs created with MonoDevelop
31// User: bongiojp at 10:09 AMĀ 7/7/2008
32//
33// Creates, Deletes, Stores ContentManagementEntities
34//
35
36#endregion Header
37
38using System;
39using System.Collections;
40using System.Collections.Generic;
41using System.Threading;
42
43using OpenMetaverse;
44
45using Nini.Config;
46
47using OpenSim;
48using OpenSim.Framework;
49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.Framework.Scenes;
51using OpenSim.Region.Physics.Manager;
52
53using log4net;
54
55namespace OpenSim.Region.OptionalModules.ContentManagement
56{
57 public class CMEntityCollection
58 {
59 #region Fields
60
61 // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
62 // Any ContentManagementEntities that represent old versions of current SceneObjectGroups or
63 // old versions of deleted SceneObjectGroups will be stored in this hash table.
64 // The UUID keys are from the SceneObjectGroup RootPart UUIDs
65 protected Hashtable m_CMEntityHash = Hashtable.Synchronized(new Hashtable()); //UUID to ContentManagementEntity
66
67 // SceneObjectParts that have not been revisioned will be given green auras stored in this hashtable
68 // The UUID keys are from the SceneObjectPart that they are supposed to be on.
69 protected Hashtable m_NewlyCreatedEntityAura = Hashtable.Synchronized(new Hashtable()); //UUID to AuraMetaEntity
70
71 #endregion Fields
72
73 #region Constructors
74
75 public CMEntityCollection()
76 {
77 }
78
79 #endregion Constructors
80
81 #region Public Properties
82
83 public Hashtable Auras
84 {
85 get {return m_NewlyCreatedEntityAura; }
86 }
87
88 public Hashtable Entities
89 {
90 get { return m_CMEntityHash; }
91 }
92
93 #endregion Public Properties
94
95 #region Public Methods
96
97 public bool AddAura(ContentManagementEntity aura)
98 {
99 if (m_NewlyCreatedEntityAura.ContainsKey(aura.UUID))
100 return false;
101 m_NewlyCreatedEntityAura.Add(aura.UUID, aura);
102 return true;
103 }
104
105 public bool AddEntity(ContentManagementEntity ent)
106 {
107 if (m_CMEntityHash.ContainsKey(ent.UUID))
108 return false;
109 m_CMEntityHash.Add(ent.UUID, ent);
110 return true;
111 }
112
113 // Check if there are SceneObjectGroups in the list that do not have corresponding ContentManagementGroups in the CMEntityHash
114 public System.Collections.ArrayList CheckForMissingEntities(System.Collections.Generic.List<EntityBase> currList)
115 {
116 System.Collections.ArrayList missingList = new System.Collections.ArrayList();
117 SceneObjectGroup temp = null;
118 foreach (EntityBase currObj in currList)
119 {
120 if (!(currObj is SceneObjectGroup))
121 continue;
122 temp = (SceneObjectGroup) currObj;
123
124 if (m_CMEntityHash.ContainsKey(temp.UUID))
125 {
126 foreach (SceneObjectPart part in temp.Children.Values)
127 if (!((ContentManagementEntity)m_CMEntityHash[temp.UUID]).HasChildPrim(part.UUID))
128 missingList.Add(part);
129 }
130 else //Entire group is missing from revision. (and is a new part in region)
131 {
132 foreach (SceneObjectPart part in temp.Children.Values)
133 missingList.Add(part);
134 }
135 }
136 return missingList;
137 }
138
139 public void ClearAll()
140 {
141 m_CMEntityHash.Clear();
142 m_NewlyCreatedEntityAura.Clear();
143 }
144
145 // Old uuid and new sceneobjectgroup
146 public AuraMetaEntity CreateAuraForNewlyCreatedEntity(SceneObjectPart part)
147 {
148 AuraMetaEntity ent = new AuraMetaEntity(part.ParentGroup.Scene,
149 part.GetWorldPosition(),
150 MetaEntity.TRANSLUCENT,
151 new Vector3(0,254,0),
152 part.Scale
153 );
154 m_NewlyCreatedEntityAura.Add(part.UUID, ent);
155 return ent;
156 }
157
158 // Old uuid and new sceneobjectgroup
159 public ContentManagementEntity CreateNewEntity(SceneObjectGroup group)
160 {
161 ContentManagementEntity ent = new ContentManagementEntity(group, false);
162 m_CMEntityHash.Add(group.UUID, ent);
163 return ent;
164 }
165
166 public ContentManagementEntity CreateNewEntity(String xml, Scene scene)
167 {
168 ContentManagementEntity ent = new ContentManagementEntity(xml, scene, false);
169 if (ent == null)
170 return null;
171 m_CMEntityHash.Add(ent.UnchangedEntity.UUID, ent);
172 return ent;
173 }
174
175 public bool RemoveEntity(UUID uuid)
176 {
177 if (!m_CMEntityHash.ContainsKey(uuid))
178 return false;
179 m_CMEntityHash.Remove(uuid);
180 return true;
181 }
182
183 public bool RemoveNewlyCreatedEntityAura(UUID uuid)
184 {
185 if (!m_NewlyCreatedEntityAura.ContainsKey(uuid))
186 return false;
187 m_NewlyCreatedEntityAura.Remove(uuid);
188 return true;
189 }
190
191 #endregion Public Methods
192 }
193}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
new file mode 100644
index 0000000..761dca9
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
@@ -0,0 +1,362 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// CMModel.cs
31// User: bongiojp
32//
33//
34
35#endregion Header
36
37using System;
38using System.Collections;
39using System.Collections.Generic;
40using System.Diagnostics;
41
42using OpenMetaverse;
43
44using OpenSim;
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 public class CMModel
55 {
56 #region Static Fields
57
58 static float TimeToUpdate = 0;
59 static float TimeToConvertXml = 0;
60 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
61
62 #endregion Static Fields
63
64 #region Fields
65
66 /// <value>
67 /// The class that contains all auras and metaentities used in the CMS.
68 /// </value>
69 CMEntityCollection m_MetaEntityCollection = new CMEntityCollection();
70 IContentDatabase m_database = null;
71
72 #endregion Fields
73
74 #region Constructors
75
76 public CMModel()
77 {
78 }
79
80 #endregion Constructors
81
82 #region Public Properties
83
84 public CMEntityCollection MetaEntityCollection
85 {
86 get { return m_MetaEntityCollection; }
87 }
88
89 #endregion Public Properties
90
91 #region Public Methods
92
93 /// <summary>
94 /// 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
95 /// it is a new part that must have a green aura (for diff mode).
96 /// Returns list of ContentManagementEntities
97 /// </summary>
98 public ArrayList CheckForNewEntitiesMissingAuras(Scene scene)
99 {
100 ArrayList missingList = null;
101 ArrayList newList = new ArrayList();
102
103 m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName);
104
105 //Check if the current scene has groups not included in the current list of MetaEntities
106 //If so, then the current scene's parts that are new should be marked green.
107 missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities());
108
109 foreach (Object missingPart in missingList)
110 {
111 if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID))
112 continue;
113 newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart));
114 }
115 m_log.Info("Number of missing objects found: " + newList.Count);
116 return newList;
117 }
118
119 /// <summary>
120 /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message.
121 /// </summary>
122 public void CommitRegion(Scene scene, String logMessage)
123 {
124 m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length);
125 m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage);
126 m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName );
127 }
128
129 public void DeleteAllMetaObjects()
130 {
131 m_MetaEntityCollection.ClearAll();
132 }
133
134 public ContentManagementEntity FindMetaEntityAffectedByUndo(UUID uuid)
135 {
136 ContentManagementEntity ent = GetMetaGroupByPrim(uuid);
137 return ent;
138 }
139
140 //-------------------------------- HELPERS --------------------------------------------------------------------//
141 public ContentManagementEntity GetMetaGroupByPrim(UUID uuid)
142 {
143 foreach (Object ent in m_MetaEntityCollection.Entities.Values)
144 {
145 if (((ContentManagementEntity)ent).HasChildPrim(uuid))
146 return (ContentManagementEntity)ent;
147 }
148 return null;
149 }
150
151 public void Initialise(string database)
152 {
153 if (database == "FileSystemDatabase")
154 m_database = new FileSystemDatabase();
155 else if (database == "GitDatabase")
156 m_database = new GitDatabase();
157 }
158
159 public void InitialiseDatabase(Scene scene, string dir)
160 {
161 m_database.Initialise(scene, dir);
162 }
163
164 /// <summary>
165 /// Should be called just once to finish initializing the database.
166 /// </summary>
167 public void PostInitialise()
168 {
169 m_database.PostInitialise();
170 }
171
172 /// <summary>
173 /// Removes the green aura when an a new scene object group is deleted.
174 /// </summary>
175 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
176 {
177 // Deal with new parts not revisioned that have been deleted.
178 foreach (SceneObjectPart part in group.Children.Values)
179 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
180 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
181 }
182
183 /// <summary>
184 /// Retrieves the latest revision of a region in xml form,
185 /// converts it to scene object groups and scene presences,
186 /// swaps the current scene's entity list with the revision's list.
187 /// Note: Since deleted objects while
188 /// </summary>
189 public void RollbackRegion(Scene scene)
190 {
191 System.Collections.ArrayList xmllist = null;
192 SceneObjectGroup temp = null;
193 System.Collections.Hashtable deleteListUUIDs = new Hashtable();
194// Dictionary<LLUUID, EntityBase> SearchList = new Dictionary<LLUUID,EntityBase>();
195 Dictionary<UUID, EntityBase> ReplacementList = new Dictionary<UUID,EntityBase>();
196 int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID);
197// EntityBase[] searchArray;
198
199 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision);
200 if (xmllist == null)
201 {
202 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ").");
203 return;
204 }
205
206 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ").");
207 m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count);
208 m_log.Info("[CMMODEL]: Converting scene entities list to specified revision.");
209
210 m_log.ErrorFormat("[CMMODEL]: 1");
211
212 foreach (string xml in xmllist)
213 {
214 try{
215 temp = new SceneObjectGroup(xml);
216 temp.SetScene(scene);
217 foreach (SceneObjectPart part in temp.Children.Values)
218 part.RegionHandle = scene.RegionInfo.RegionHandle;
219 ReplacementList.Add(temp.UUID, (EntityBase)temp);
220 }
221 catch(Exception e)
222 {
223 m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e);
224 }
225 }
226
227 //If in scene but not in revision and not a client, remove them
228 while (true)
229 {
230 try
231 {
232 foreach (EntityBase entity in scene.GetEntities())
233 {
234 if (entity == null)
235 continue;
236
237 if (entity is ScenePresence)
238 {
239 ReplacementList.Add(entity.UUID, entity);
240 continue;
241 }
242 else //if (!ReplacementList.ContainsKey(entity.UUID))
243 deleteListUUIDs.Add(entity.UUID, 0);
244 }
245 }
246 catch(Exception e)
247 {
248 m_log.ErrorFormat("[CMMODEL]: " + e);
249 deleteListUUIDs.Clear();
250 ReplacementList.Clear();
251 continue;
252 }
253 break;
254 }
255
256 foreach (UUID uuid in deleteListUUIDs.Keys)
257 {
258 try
259 {
260 // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles.
261 ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup();
262 scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor);
263 scene.SendKillObject(scene.Entities[uuid].LocalId);
264 scene.m_sceneGraph.DeleteSceneObject(uuid, false);
265 ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup(false);
266 }
267 catch(Exception e)
268 {
269 m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e);
270 }
271 }
272
273 lock (scene)
274 {
275 scene.Entities.Clear();
276
277 foreach (KeyValuePair<UUID,EntityBase> kvp in ReplacementList)
278 {
279 scene.Entities.Add(kvp.Value);
280 }
281 }
282
283 foreach (EntityBase ent in ReplacementList.Values)
284 {
285 try
286 {
287 if (!(ent is SceneObjectGroup))
288 continue;
289
290 if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) PrimFlags.Phantom) == 0)
291 ((SceneObjectGroup)ent).ApplyPhysics(true);
292 ((SceneObjectGroup)ent).AttachToBackup();
293 ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected.
294 ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
295 }
296 catch(Exception e)
297 {
298 m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e);
299 }
300 }
301 m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup.");
302 scene.Backup();
303 }
304
305 /// <summary>
306 /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences
307 /// and display the differences to clients.
308 /// </summary>
309 public void UpdateCMEntities(Scene scene)
310 {
311 Stopwatch x = new Stopwatch();
312 x.Start();
313
314 System.Collections.ArrayList xmllist = null;
315 m_log.Debug("[CONTENT MANAGEMENT] Retrieving object xml files for region: " + scene.RegionInfo.RegionID);
316 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID);
317 m_log.Info("[FSDB]: got list");
318 if (xmllist == null)
319 return;
320
321 Stopwatch y = new Stopwatch();
322 y.Start();
323 foreach (string xml in xmllist)
324 m_MetaEntityCollection.CreateNewEntity(xml, scene);
325 y.Stop();
326 TimeToConvertXml += y.ElapsedMilliseconds;
327 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds);
328 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml);
329
330 m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras");
331 CheckForNewEntitiesMissingAuras(scene);
332
333 x.Stop();
334 TimeToUpdate += x.ElapsedMilliseconds;
335 m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds);
336 m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate);
337 }
338
339 /// <summary>
340 /// Detects if a scene object group from the scene list has moved or changed scale. The green aura
341 /// that surrounds the object is then moved or scaled with the group.
342 /// </summary>
343 public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group)
344 {
345 System.Collections.ArrayList auraList = new System.Collections.ArrayList();
346 if (group == null)
347 return null;
348 foreach (SceneObjectPart part in group.Children.Values)
349 {
350 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
351 {
352 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new Vector3(0,254,0), part.Scale);
353 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
354 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
355 }
356 }
357 return auraList;
358 }
359
360 #endregion Public Methods
361 }
362}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
new file mode 100644
index 0000000..a1a4d94
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMView.cs
@@ -0,0 +1,206 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// CMView.cs created with MonoDevelop
31// User: bongiojp at 11:57 AMĀ 7/3/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections;
40using System.Collections.Generic;
41
42using OpenMetaverse;
43
44using OpenSim;
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 public class CMView
55 {
56 #region Static Fields
57
58 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
59
60 #endregion Static Fields
61
62 #region Fields
63
64 CMModel m_model = null;
65
66 #endregion Fields
67
68 #region Constructors
69
70 public CMView()
71 {
72 }
73
74 #endregion Constructors
75
76 #region Public Methods
77
78 // Auras To
79 public void DisplayAuras(CMEntityCollection auraCollection)
80 {
81 foreach (Object ent in auraCollection.Auras.Values)
82 ((AuraMetaEntity)ent).SendFullUpdateToAll();
83 }
84
85 // Auras To Client
86 public void DisplayAuras(CMEntityCollection auraCollection, IClientAPI client)
87 {
88 foreach (Object ent in auraCollection.Auras.Values)
89 ((AuraMetaEntity)ent).SendFullUpdate(client);
90 }
91
92 // Auras from List To ALL
93 public void DisplayAuras(ArrayList list)
94 {
95 foreach (Object ent in list)
96 {
97 m_log.Debug("[CONTENT MANAGEMENT] displaying new aura riiiiiiiiiiiight NOW");
98 ((AuraMetaEntity)ent).SendFullUpdateToAll();
99 }
100 }
101
102 // Entities to ALL
103 public void DisplayEntities(CMEntityCollection entityCollection)
104 {
105 foreach (Object ent in entityCollection.Entities.Values)
106 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
107 }
108
109 // Entities to Client
110 public void DisplayEntities(CMEntityCollection entityCollection, IClientAPI client)
111 {
112 foreach (Object ent in entityCollection.Entities.Values)
113 ((ContentManagementEntity)ent).SendFullDiffUpdate(client);
114 }
115
116 // Entities from List to ALL
117 public void DisplayEntities(ArrayList list)
118 {
119 foreach (Object ent in list)
120 ((ContentManagementEntity)ent).SendFullDiffUpdateToAll();
121 }
122
123 // Entity to ALL
124 public void DisplayEntity(ContentManagementEntity ent)
125 {
126 ent.SendFullDiffUpdateToAll();
127 }
128
129 public void DisplayHelpMenu(Scene scene)
130 {
131 string menu = "Menu:\n";
132 menu += "commit (ci) - saves current state of the region to a database on the server\n";
133 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";
134 SendSimChatMessage(scene, menu);
135 }
136
137 public void DisplayMetaEntity(UUID uuid)
138 {
139 ContentManagementEntity group = m_model.GetMetaGroupByPrim(uuid);
140 if (group != null)
141 group.SendFullDiffUpdateToAll();
142 }
143
144 /// <summary>
145 /// update all clients of red/green/blue auras and meta entities that the model knows about.
146 /// </summary>
147 public void DisplayRecentChanges()
148 {
149 m_log.Debug("[CONTENT MANAGEMENT] Sending update to clients for " + m_model.MetaEntityCollection.Entities.Count + " objects.");
150 DisplayEntities(m_model.MetaEntityCollection);
151 DisplayAuras(m_model.MetaEntityCollection);
152 }
153
154 public void Hide(ContentManagementEntity ent)
155 {
156 ent.HideFromAll();
157 }
158
159 public void HideAllAuras()
160 {
161 foreach (Object obj in m_model.MetaEntityCollection.Auras.Values)
162 ((MetaEntity)obj).HideFromAll();
163 }
164
165 public void HideAllMetaEntities()
166 {
167 foreach (Object obj in m_model.MetaEntityCollection.Entities.Values)
168 ((ContentManagementEntity)obj).HideFromAll();
169 }
170
171 public void Initialise(CMModel model)
172 {
173 m_model = model;
174 }
175
176 /// <summary>
177 /// Figures out if the part deleted was a new scene object part or a revisioned part that's been deleted.
178 /// If it's a new scene object, any green aura attached to it is deleted.
179 /// If a revisioned part is deleted, a new full update is sent to the environment of the meta entity, which will
180 /// figure out that there should be a red aura and not a blue aura/beam.
181 /// </summary>
182 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
183 {
184 // Deal with revisioned parts that have been deleted.
185 if (m_model.MetaEntityCollection.Entities.ContainsKey(group.UUID))
186 ((ContentManagementEntity)m_model.MetaEntityCollection.Entities[group.UUID]).SendFullDiffUpdateToAll();
187
188 // Deal with new parts not revisioned that have been deleted.
189 foreach (SceneObjectPart part in group.Children.Values)
190 if (m_model.MetaEntityCollection.Auras.ContainsKey(part.UUID))
191 ((AuraMetaEntity)m_model.MetaEntityCollection.Auras[part.UUID]).HideFromAll();
192 }
193
194 public void SendMetaEntitiesToNewClient(IClientAPI client)
195 {
196 }
197
198 public void SendSimChatMessage(Scene scene, string message)
199 {
200 scene.SimChat(Utils.StringToBytes(message),
201 ChatTypeEnum.Broadcast, 0, new Vector3(0,0,0), "Content Manager", UUID.Zero, false);
202 }
203
204 #endregion Public Methods
205 }
206}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
new file mode 100644
index 0000000..4d65038
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs
@@ -0,0 +1,383 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// ContentManagementEntity.cs
31// User: bongiojp
32//
33//
34
35#endregion Header
36
37using System;
38using System.Collections.Generic;
39using System.Drawing;
40
41using OpenMetaverse;
42
43using Nini.Config;
44
45using OpenSim.Framework;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Region.Physics.Manager;
49
50using log4net;
51
52namespace OpenSim.Region.OptionalModules.ContentManagement
53{
54 public class ContentManagementEntity : MetaEntity
55 {
56 #region Static Fields
57
58// static float TimeToDiff = 0;
59// static float TimeToCreateEntities = 0;
60
61 #endregion Static Fields
62
63 #region Fields
64
65 protected Dictionary<UUID, AuraMetaEntity> m_AuraEntities = new Dictionary<UUID, AuraMetaEntity>();
66 protected Dictionary<UUID, BeamMetaEntity> m_BeamEntities = new Dictionary<UUID, BeamMetaEntity>();
67
68 // The LinkNum of parts in m_Entity and m_UnchangedEntity are the same though UUID and LocalId are different.
69 // This can come in handy.
70 protected SceneObjectGroup m_UnchangedEntity = null;
71
72 /// <value>
73 /// Should be set to true when there is a difference between m_UnchangedEntity and the corresponding scene object group in the scene entity list.
74 /// </value>
75 bool DiffersFromSceneGroup = false;
76
77 #endregion Fields
78
79 #region Constructors
80
81 public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics)
82 : base(Unchanged, false)
83 {
84 m_UnchangedEntity = Unchanged.Copy(Unchanged.RootPart.OwnerID, Unchanged.RootPart.GroupID, false);
85 }
86
87 public ContentManagementEntity(string objectXML, Scene scene, bool physics)
88 : base(objectXML, scene, false)
89 {
90 m_UnchangedEntity = new SceneObjectGroup(objectXML);
91 }
92
93 #endregion Constructors
94
95 #region Public Properties
96
97 public SceneObjectGroup UnchangedEntity
98 {
99 get { return m_UnchangedEntity; }
100 }
101
102 #endregion Public Properties
103
104 #region Private Methods
105
106 /// <summary>
107 /// Check if an entitybase list (like that returned by scene.GetEntities()) contains a group with the rootpart uuid that matches the current uuid.
108 /// </summary>
109 private bool ContainsKey(List<EntityBase> list, UUID uuid)
110 {
111 foreach (EntityBase part in list)
112 if (part.UUID == uuid)
113 return true;
114 return false;
115 }
116
117 private SceneObjectGroup GetGroupByUUID(System.Collections.Generic.List<EntityBase> list, UUID uuid)
118 {
119 foreach (EntityBase ent in list)
120 {
121 if (ent is SceneObjectGroup)
122 if (ent.UUID == uuid)
123 return (SceneObjectGroup)ent;
124 }
125 return null;
126 }
127
128 #endregion Private Methods
129
130 #region Public Methods
131
132 /// <summary>
133 /// 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.
134 /// If a matching UUID is found in a scene object group, compare the two for differences. If differences exist, Mark the metaentity appropriately.
135 /// </summary>
136 public void FindDifferences()
137 {
138 System.Collections.Generic.List<EntityBase> sceneEntityList = m_Entity.Scene.GetEntities();
139 DiffersFromSceneGroup = false;
140 // if group is not contained in scene's list
141 if (!ContainsKey(sceneEntityList, m_UnchangedEntity.UUID))
142 {
143 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
144 {
145 // if scene list no longer contains this part, display translucent part and mark with red aura
146 if (!ContainsKey(sceneEntityList, part.UUID))
147 {
148 // if already displaying a red aura over part, make sure its red
149 if (m_AuraEntities.ContainsKey(part.UUID))
150 {
151 m_AuraEntities[part.UUID].SetAura(new Vector3(254,0,0), part.Scale);
152 }
153 else
154 {
155 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
156 part.GetWorldPosition(),
157 MetaEntity.TRANSLUCENT,
158 new Vector3(254,0,0),
159 part.Scale
160 );
161 m_AuraEntities.Add(part.UUID, auraGroup);
162 }
163 SceneObjectPart metaPart = m_Entity.GetLinkNumPart(part.LinkNum);
164 SetPartTransparency(metaPart, MetaEntity.TRANSLUCENT);
165 }
166 // otherwise, scene will not contain the part. note: a group can not remove a part without changing group id
167 }
168
169 // a deleted part has no where to point a beam particle system,
170 // if a metapart had a particle system (maybe it represented a moved part) remove it
171 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
172 {
173 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
174 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
175 }
176
177 DiffersFromSceneGroup = true;
178 }
179 // if scene list does contain group, compare each part in group for differences and display beams and auras appropriately
180 else
181 {
182 MarkWithDifferences((SceneObjectGroup)GetGroupByUUID(sceneEntityList, m_UnchangedEntity.UUID));
183 }
184 }
185
186 /// <summary>
187 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given UUID.
188 /// </summary>
189 public bool HasChildPrim(UUID uuid)
190 {
191 if (m_UnchangedEntity.Children.ContainsKey(uuid))
192 return true;
193 return false;
194 }
195
196 /// <summary>
197 /// Check if the revisioned scene object group that this CMEntity is based off of contains a child with the given LocalId.
198 /// </summary>
199 public bool HasChildPrim(uint localID)
200 {
201 foreach (SceneObjectPart part in m_UnchangedEntity.Children.Values)
202 if (part.LocalId == localID)
203 return true;
204 return false;
205 }
206
207 public override void Hide(IClientAPI client)
208 {
209 base.Hide(client);
210 foreach (MetaEntity group in m_AuraEntities.Values)
211 group.Hide(client);
212 foreach (MetaEntity group in m_BeamEntities.Values)
213 group.Hide(client);
214 }
215
216 public override void HideFromAll()
217 {
218 base.HideFromAll();
219 foreach (MetaEntity group in m_AuraEntities.Values)
220 group.HideFromAll();
221 foreach (MetaEntity group in m_BeamEntities.Values)
222 group.HideFromAll();
223 }
224
225 /// <summary>
226 /// Returns true if there was a change between meta entity and the entity group, false otherwise.
227 /// If true is returned, it is assumed the metaentity's appearance has changed to reflect the difference (though clients haven't been updated).
228 /// </summary>
229 public bool MarkWithDifferences(SceneObjectGroup sceneEntityGroup)
230 {
231 SceneObjectPart sceneEntityPart;
232 SceneObjectPart metaEntityPart;
233 Diff differences;
234 bool changed = false;
235
236 // Use "UnchangedEntity" to do comparisons because its text, transparency, and other attributes will be just as the user
237 // had originally saved.
238 // m_Entity will NOT necessarily be the same entity as the user had saved.
239 foreach (SceneObjectPart UnchangedPart in m_UnchangedEntity.Children.Values)
240 {
241 //This is the part that we use to show changes.
242 metaEntityPart = m_Entity.GetLinkNumPart(UnchangedPart.LinkNum);
243 if (sceneEntityGroup.Children.ContainsKey(UnchangedPart.UUID))
244 {
245 sceneEntityPart = sceneEntityGroup.Children[UnchangedPart.UUID];
246 differences = Difference.FindDifferences(UnchangedPart, sceneEntityPart);
247 if (differences != Diff.NONE)
248 metaEntityPart.Text = "CHANGE: " + differences.ToString();
249 if (differences != 0)
250 {
251 // Root Part that has been modified
252 if ((differences&Diff.POSITION) > 0)
253 {
254 // If the position of any part has changed, make sure the RootPart of the
255 // meta entity is pointing with a beam particle system
256 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
257 {
258 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
259 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
260 }
261 BeamMetaEntity beamGroup = new BeamMetaEntity(m_Entity.Scene,
262 m_UnchangedEntity.RootPart.GetWorldPosition(),
263 MetaEntity.TRANSLUCENT,
264 sceneEntityPart,
265 new Vector3(0,0,254)
266 );
267 m_BeamEntities.Add(m_UnchangedEntity.RootPart.UUID, beamGroup);
268 }
269
270 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
271 {
272 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
273 m_AuraEntities.Remove(UnchangedPart.UUID);
274 }
275 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
276 UnchangedPart.GetWorldPosition(),
277 MetaEntity.TRANSLUCENT,
278 new Vector3(0,0,254),
279 UnchangedPart.Scale
280 );
281 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
282 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
283
284 DiffersFromSceneGroup = true;
285 }
286 else // no differences between scene part and meta part
287 {
288 if (m_BeamEntities.ContainsKey(m_UnchangedEntity.RootPart.UUID))
289 {
290 m_BeamEntities[m_UnchangedEntity.RootPart.UUID].HideFromAll();
291 m_BeamEntities.Remove(m_UnchangedEntity.RootPart.UUID);
292 }
293 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
294 {
295 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
296 m_AuraEntities.Remove(UnchangedPart.UUID);
297 }
298 SetPartTransparency(metaEntityPart, MetaEntity.NONE);
299 }
300 }
301 else //The entity currently in the scene is missing parts from the metaentity saved, so mark parts red as deleted.
302 {
303 if (m_AuraEntities.ContainsKey(UnchangedPart.UUID))
304 {
305 m_AuraEntities[UnchangedPart.UUID].HideFromAll();
306 m_AuraEntities.Remove(UnchangedPart.UUID);
307 }
308 AuraMetaEntity auraGroup = new AuraMetaEntity(m_Entity.Scene,
309 UnchangedPart.GetWorldPosition(),
310 MetaEntity.TRANSLUCENT,
311 new Vector3(254,0,0),
312 UnchangedPart.Scale
313 );
314 m_AuraEntities.Add(UnchangedPart.UUID, auraGroup);
315 SetPartTransparency(metaEntityPart, MetaEntity.TRANSLUCENT);
316
317 DiffersFromSceneGroup = true;
318 }
319 }
320 return changed;
321 }
322
323 public void SendFullAuraUpdate(IClientAPI client)
324 {
325 if (DiffersFromSceneGroup)
326 {
327 foreach (AuraMetaEntity group in m_AuraEntities.Values)
328 group.SendFullUpdate(client);
329 }
330 }
331
332 public void SendFullAuraUpdateToAll()
333 {
334 if (DiffersFromSceneGroup)
335 {
336 foreach (AuraMetaEntity group in m_AuraEntities.Values)
337 group.SendFullUpdateToAll();
338 }
339 }
340
341 public void SendFullBeamUpdate(IClientAPI client)
342 {
343 if (DiffersFromSceneGroup)
344 {
345 foreach (BeamMetaEntity group in m_BeamEntities.Values)
346 group.SendFullUpdate(client);
347 }
348 }
349
350 public void SendFullBeamUpdateToAll()
351 {
352 if (DiffersFromSceneGroup)
353 {
354 foreach (BeamMetaEntity group in m_BeamEntities.Values)
355 group.SendFullUpdateToAll();
356 }
357 }
358
359 public void SendFullDiffUpdate(IClientAPI client)
360 {
361 FindDifferences();
362 if (DiffersFromSceneGroup)
363 {
364 SendFullUpdate(client);
365 SendFullAuraUpdate(client);
366 SendFullBeamUpdate(client);
367 }
368 }
369
370 public void SendFullDiffUpdateToAll()
371 {
372 FindDifferences();
373 if (DiffersFromSceneGroup)
374 {
375 SendFullUpdateToAll();
376 SendFullAuraUpdateToAll();
377 SendFullBeamUpdateToAll();
378 }
379 }
380
381 #endregion Public Methods
382 }
383}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs
new file mode 100644
index 0000000..21bc8b2
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs
@@ -0,0 +1,163 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// ContentManagementModule.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Threading;
38
39using OpenMetaverse;
40
41using Nini.Config;
42
43using OpenSim;
44using OpenSim.Framework;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.Physics.Manager;
48
49using log4net;
50
51namespace OpenSim.Region.OptionalModules.ContentManagement
52{
53 public class ContentManagementModule : IRegionModule
54 {
55 #region Static Fields
56
57 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
58
59 #endregion Static Fields
60
61 #region Fields
62
63 bool initialised = false;
64 CMController m_control = null;
65 bool m_enabled = false;
66 CMModel m_model = null;
67 bool m_posted = false;
68 CMView m_view = null;
69
70 #endregion Fields
71
72 #region Public Properties
73
74 public bool IsSharedModule
75 {
76 get { return true; }
77 }
78
79 public string Name
80 {
81 get { return "ContentManagementModule"; }
82 }
83
84 #endregion Public Properties
85
86 #region Public Methods
87
88 public void Close()
89 {
90 }
91
92 public void Initialise(Scene scene, IConfigSource source)
93 {
94 string databaseDir = "./";
95 string database = "FileSystemDatabase";
96 int channel = 345;
97 try
98 {
99 if (source.Configs["CMS"] == null)
100 return;
101
102 m_enabled = source.Configs["CMS"].GetBoolean("enabled", false);
103 databaseDir = source.Configs["CMS"].GetString("directory", databaseDir);
104 database = source.Configs["CMS"].GetString("database", database);
105 channel = source.Configs["CMS"].GetInt("channel", channel);
106
107 if (database != "FileSystemDatabase" && database != "GitDatabase")
108 {
109 m_log.ErrorFormat("[Content Management]: The Database attribute must be defined as either FileSystemDatabase or GitDatabase");
110 m_enabled = false;
111 }
112 }
113 catch (Exception e)
114 {
115 m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e);
116 m_enabled = false;
117 }
118
119 if (!m_enabled)
120 {
121 m_log.Info("[Content Management]: Content Management System is not Enabled.");
122 return;
123 }
124
125 lock (this)
126 {
127 if (!initialised) //only init once
128 {
129 m_view = new CMView();
130 m_model = new CMModel();
131 m_control = new CMController(m_model, m_view, scene, channel);
132 m_model.Initialise(database);
133 m_view.Initialise(m_model);
134
135 initialised = true;
136 m_model.InitialiseDatabase(scene, databaseDir);
137 }
138 else
139 {
140 m_model.InitialiseDatabase(scene, databaseDir);
141 m_control.RegisterNewRegion(scene);
142 }
143 }
144 }
145
146 public void PostInitialise()
147 {
148 if (! m_enabled)
149 return;
150
151 lock (this)
152 {
153 if (!m_posted) //only post once
154 {
155 m_model.PostInitialise();
156 m_posted = true;
157 }
158 }
159 }
160
161 #endregion Public Methods
162 }
163}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs
new file mode 100644
index 0000000..6a50906
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/FileSystemDatabase.cs
@@ -0,0 +1,317 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// FileSystemDatabase.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Diagnostics;
38using System.IO;
39using Slash = System.IO.Path;
40using System.Reflection;
41using System.Xml;
42
43using OpenMetaverse;
44
45using Nini.Config;
46
47using OpenSim.Framework;
48using OpenSim.Region.Framework.Interfaces;
49using OpenSim.Region.Framework.Scenes;
50using OpenSim.Region.CoreModules.World.Serialiser;
51using OpenSim.Region.CoreModules.World.Terrain;
52using OpenSim.Region.Physics.Manager;
53
54using log4net;
55
56namespace OpenSim.Region.OptionalModules.ContentManagement
57{
58 public class FileSystemDatabase : IContentDatabase
59 {
60 #region Static Fields
61
62 public static float TimeToDownload = 0;
63 public static float TimeToSave = 0;
64 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
65
66 #endregion Static Fields
67
68 #region Fields
69
70 private string m_repodir = null;
71 private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
72 private Dictionary<UUID, IRegionSerialiserModule> m_serialiser = new Dictionary<UUID, IRegionSerialiserModule>();
73
74 #endregion Fields
75
76 #region Constructors
77
78 public FileSystemDatabase()
79 {
80 }
81
82 #endregion Constructors
83
84 #region Private Methods
85
86 // called by postinitialise
87 private void CreateDirectory()
88 {
89 string scenedir;
90 if (!Directory.Exists(m_repodir))
91 Directory.CreateDirectory(m_repodir);
92
93 foreach (UUID region in m_scenes.Keys)
94 {
95 scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar;
96 if (!Directory.Exists(scenedir))
97 Directory.CreateDirectory(scenedir);
98 }
99 }
100
101 // called by postinitialise
102 private void SetupSerialiser()
103 {
104 if (m_serialiser.Count == 0)
105 {
106 foreach (UUID region in m_scenes.Keys)
107 {
108 m_serialiser.Add(region, m_scenes[region].RequestModuleInterface<IRegionSerialiserModule>());
109 }
110 }
111 }
112
113 #endregion Private Methods
114
115 #region Public Methods
116
117 public int GetMostRecentRevision(UUID regionid)
118 {
119 return NumOfRegionRev(regionid);
120 }
121
122 public string GetRegionObjectHeightMap(UUID regionid)
123 {
124 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
125 Slash.DirectorySeparatorChar + "heightmap.r32";
126 FileStream fs = new FileStream( filename, FileMode.Open);
127 StreamReader sr = new StreamReader(fs);
128 String result = sr.ReadToEnd();
129 sr.Close();
130 fs.Close();
131 return result;
132 }
133
134 public string GetRegionObjectHeightMap(UUID regionid, int revision)
135 {
136 String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
137 Slash.DirectorySeparatorChar + "heightmap.r32";
138 FileStream fs = new FileStream( filename, FileMode.Open);
139 StreamReader sr = new StreamReader(fs);
140 String result = sr.ReadToEnd();
141 sr.Close();
142 fs.Close();
143 return result;
144 }
145
146 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
147 {
148 System.Collections.ArrayList objectList = new System.Collections.ArrayList();
149 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
150 + revision + Slash.DirectorySeparatorChar + "objects.xml";
151 XmlDocument doc = new XmlDocument();
152 XmlNode rootNode;
153 //int primCount = 0;
154 //SceneObjectGroup obj = null;
155
156 if (File.Exists(filename))
157 {
158 XmlTextReader reader = new XmlTextReader(filename);
159 reader.WhitespaceHandling = WhitespaceHandling.None;
160 doc.Load(reader);
161 reader.Close();
162 rootNode = doc.FirstChild;
163 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
164 {
165 objectList.Add(aPrimNode.OuterXml);
166 }
167 return objectList;
168 }
169 return null;
170 }
171
172 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
173 {
174 int revision = NumOfRegionRev(regionid);
175 m_log.Info("[FSDB]: found revisions:" + revision);
176 System.Collections.ArrayList xmlList = new System.Collections.ArrayList();
177 string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
178 + revision + Slash.DirectorySeparatorChar + "objects.xml";
179 XmlDocument doc = new XmlDocument();
180 XmlNode rootNode;
181
182 m_log.Info("[FSDB]: Checking if " + filename + " exists.");
183 if (File.Exists(filename))
184 {
185 Stopwatch x = new Stopwatch();
186 x.Start();
187
188 XmlTextReader reader = new XmlTextReader(filename);
189 reader.WhitespaceHandling = WhitespaceHandling.None;
190 doc.Load(reader);
191 reader.Close();
192 rootNode = doc.FirstChild;
193
194 foreach (XmlNode aPrimNode in rootNode.ChildNodes)
195 {
196 xmlList.Add(aPrimNode.OuterXml);
197 }
198
199 x.Stop();
200 TimeToDownload += x.ElapsedMilliseconds;
201 m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload);
202
203 return xmlList;
204 }
205 return null;
206 }
207
208 public void Initialise(Scene scene, string dir)
209 {
210 lock (this)
211 {
212 if (m_repodir == null)
213 m_repodir = dir;
214 }
215 lock (m_scenes)
216 m_scenes.Add(scene.RegionInfo.RegionID, scene);
217 }
218
219 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID regionid)
220 {
221 SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>();
222
223 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
224 string[] directories = Directory.GetDirectories(scenedir);
225
226 FileStream fs = null;
227 StreamReader sr = null;
228 String logMessage = "";
229 String logLocation = "";
230 foreach (string revisionDir in directories)
231 {
232 try
233 {
234 logLocation = revisionDir + Slash.DirectorySeparatorChar + "log";
235 fs = new FileStream( logLocation, FileMode.Open);
236 sr = new StreamReader(fs);
237 logMessage = sr.ReadToEnd();
238 sr.Close();
239 fs.Close();
240 revisionDict.Add(revisionDir, logMessage);
241 }
242 catch (Exception)
243 {
244 }
245 }
246
247 return revisionDict;
248 }
249
250 public int NumOfRegionRev(UUID regionid)
251 {
252 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
253 m_log.Info("[FSDB]: Reading scene dir: " + scenedir);
254 string[] directories = Directory.GetDirectories(scenedir);
255 return directories.Length;
256 }
257
258 // Run once and only once.
259 public void PostInitialise()
260 {
261 SetupSerialiser();
262
263 m_log.Info("[FSDB]: Creating repository in " + m_repodir + ".");
264 CreateDirectory();
265 }
266
267 public void SaveRegion(UUID regionid, string regionName, string logMessage)
268 {
269 m_log.Info("[FSDB]: ...............................");
270 string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
271
272 m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir);
273 if (!Directory.Exists(scenedir))
274 Directory.CreateDirectory(scenedir);
275
276 int newRevisionNum = GetMostRecentRevision(regionid)+1;
277 string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar;
278
279 m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir);
280 if (!Directory.Exists(revisiondir))
281 Directory.CreateDirectory(revisiondir);
282
283 try {
284 Stopwatch x = new Stopwatch();
285 x.Start();
286 if (m_scenes.ContainsKey(regionid))
287 {
288 m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir);
289 }
290 x.Stop();
291 TimeToSave += x.ElapsedMilliseconds;
292 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds);
293 m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave);
294 }
295 catch (Exception e)
296 {
297 m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e);
298 return;
299 }
300
301 try {
302 // Finish by writing log message.
303 FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite);
304 StreamWriter sw = new StreamWriter(file);
305 sw.Write(logMessage);
306 sw.Close();
307 }
308 catch (Exception e)
309 {
310 m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e);
311 return;
312 }
313 }
314
315 #endregion Public Methods
316 }
317}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs
new file mode 100644
index 0000000..d24747c
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/GitDatabase.cs
@@ -0,0 +1,167 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// GitDatabase.cs
31//
32//
33//
34
35#endregion Header
36
37using System;
38using System.Collections.Generic;
39using System.IO;
40using Slash = System.IO.Path;
41using System.Reflection;
42using System.Xml;
43
44using OpenMetaverse;
45
46using Nini.Config;
47
48using OpenSim.Framework;
49using OpenSim.Region.Framework.Interfaces;
50using OpenSim.Region.Framework.Scenes;
51using OpenSim.Region.CoreModules.World.Serialiser;
52using OpenSim.Region.CoreModules.World.Terrain;
53using OpenSim.Region.Physics.Manager;
54
55using log4net;
56
57namespace OpenSim.Region.OptionalModules.ContentManagement
58{
59 /// <summary>
60 /// Just a stub :-(
61 /// </summary>
62 public class GitDatabase : IContentDatabase
63 {
64 #region Constructors
65
66 public GitDatabase()
67 {
68 }
69
70 #endregion Constructors
71
72 #region Public Methods
73
74 public SceneObjectGroup GetMostRecentObjectRevision(UUID id)
75 {
76 return null;
77 }
78
79 public int GetMostRecentRevision(UUID regionid)
80 {
81 return 0;
82 }
83
84 public SceneObjectGroup GetObjectRevision(UUID id, int revision)
85 {
86 return null;
87 }
88
89 public System.Collections.ArrayList GetObjectsFromRegion(UUID regionid, int revision)
90 {
91 return null;
92 }
93
94 public string GetRegionObjectHeightMap(UUID regionid)
95 {
96 return null;
97 }
98
99 public string GetRegionObjectHeightMap(UUID regionid, int revision)
100 {
101 return null;
102 }
103
104 public string GetRegionObjectXML(UUID regionid)
105 {
106 return null;
107 }
108
109 public string GetRegionObjectXML(UUID regionid, int revision)
110 {
111 return null;
112 }
113
114 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
115 {
116 return null;
117 }
118
119 public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
120 {
121 return null;
122 }
123
124 public bool InRepository(UUID id)
125 {
126 return false;
127 }
128
129 public void Initialise(Scene scene, String dir)
130 {
131 }
132
133 public System.Collections.Generic.SortedDictionary<string, string> ListOfObjectRevisions(UUID id)
134 {
135 return null;
136 }
137
138 public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id)
139 {
140 return null;
141 }
142
143 public int NumOfObjectRev(UUID id)
144 {
145 return 0;
146 }
147
148 public int NumOfRegionRev(UUID regionid)
149 {
150 return 0;
151 }
152
153 public void PostInitialise()
154 {
155 }
156
157 public void SaveObject(SceneObjectGroup entity)
158 {
159 }
160
161 public void SaveRegion(UUID regionid, string regionName, string logMessage)
162 {
163 }
164
165 #endregion Public Methods
166 }
167}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs
new file mode 100644
index 0000000..7a25fa5
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/IContentDatabase.cs
@@ -0,0 +1,94 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// IContentDatabase.cs
31// User: bongiojp
32//
33//
34//
35
36#endregion Header
37
38using System;
39using OpenMetaverse;
40using OpenSim.Region.Framework.Scenes;
41using Nini.Config;
42
43namespace OpenSim.Region.OptionalModules.ContentManagement
44{
45 public interface IContentDatabase
46 {
47 #region Methods
48
49 /// <summary>
50 /// Returns the most recent revision number of a region.
51 /// </summary>
52 int GetMostRecentRevision(UUID regionid);
53
54 string GetRegionObjectHeightMap(UUID regionid);
55
56 string GetRegionObjectHeightMap(UUID regionid, int revision);
57
58 /// <summary>
59 /// Retrieves the xml that describes each individual object from the last revision or specific revision of the given region.
60 /// </summary>
61 System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid);
62
63 System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision);
64
65 /// <summary>
66 /// Similar to the IRegionModule function. This is the function to be called before attempting to interface with the database.
67 /// Initialise should be called one for each region to be contained in the database. The directory should be the full path
68 /// to the repository and will only be defined once, regardless of how many times the method is called.
69 /// </summary>
70 void Initialise(Scene scene, String dir);
71
72 /// <summary>
73 /// Returns a list of the revision numbers and corresponding log messages for a given region.
74 /// </summary>
75 System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID id);
76
77 /// <summary>
78 /// Returns the total number of revisions saved for a specific region.
79 /// </summary>
80 int NumOfRegionRev(UUID regionid);
81
82 /// <summary>
83 /// Should be called once after Initialise has been called.
84 /// </summary>
85 void PostInitialise();
86
87 /// <summary>
88 /// Saves the Region terrain map and objects within the region as xml to the database.
89 /// </summary>
90 void SaveRegion(UUID regionid, string regionName, string logMessage);
91
92 #endregion Methods
93 }
94}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
new file mode 100644
index 0000000..63c74e1
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs
@@ -0,0 +1,274 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// MetaEntity.cs
31// User: bongiojp
32//
33// TODO:
34// Create a physics manager to the meta object if there isn't one or the object knows of no scene but the user wants physics enabled.
35
36#endregion Header
37
38using System;
39using System.Collections.Generic;
40using System.Drawing;
41
42using OpenMetaverse;
43
44using Nini.Config;
45
46using OpenSim.Framework;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Physics.Manager;
50
51using log4net;
52
53namespace OpenSim.Region.OptionalModules.ContentManagement
54{
55 public class MetaEntity
56 {
57 #region Constants
58
59 public const float INVISIBLE = .95f;
60
61 // Settings for transparency of metaentity
62 public const float NONE = 0f;
63 public const float TRANSLUCENT = .5f;
64
65 #endregion Constants
66
67 #region Static Fields
68
69 protected static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
70
71 #endregion Static Fields
72
73 #region Fields
74
75 protected SceneObjectGroup m_Entity = null; // The scene object group that represents this meta entity.
76 protected uint m_metaLocalid;
77
78 #endregion Fields
79
80 #region Constructors
81
82 public MetaEntity()
83 {
84 }
85
86 /// <summary>
87 /// Makes a new meta entity by copying the given scene object group.
88 /// The physics boolean is just a stub right now.
89 /// </summary>
90 public MetaEntity(SceneObjectGroup orig, bool physics)
91 {
92 m_Entity = orig.Copy(orig.RootPart.OwnerID, orig.RootPart.GroupID, false);
93 Initialize(physics);
94 }
95
96 /// <summary>
97 /// Takes an XML description of a scene object group and converts it to a meta entity.
98 /// </summary>
99 public MetaEntity(string objectXML, Scene scene, bool physics)
100 {
101 m_Entity = new SceneObjectGroup(objectXML);
102 m_Entity.SetScene(scene);
103 Initialize(physics);
104 }
105
106 #endregion Constructors
107
108 #region Public Properties
109
110 public Dictionary<UUID, SceneObjectPart> Children
111 {
112 get { return m_Entity.Children; }
113 set { m_Entity.Children = value; }
114 }
115
116 public uint LocalId
117 {
118 get { return m_Entity.LocalId; }
119 set { m_Entity.LocalId = value; }
120 }
121
122 public SceneObjectGroup ObjectGroup
123 {
124 get { return m_Entity; }
125 }
126
127 public int PrimCount
128 {
129 get { return m_Entity.PrimCount; }
130 }
131
132 public SceneObjectPart RootPart
133 {
134 get { return m_Entity.RootPart; }
135 }
136
137 public Scene Scene
138 {
139 get { return m_Entity.Scene; }
140 }
141
142 public UUID UUID
143 {
144 get { return m_Entity.UUID; }
145 set { m_Entity.UUID = value; }
146 }
147
148 #endregion Public Properties
149
150 #region Protected Methods
151
152 // The metaentity objectgroup must have unique localids as well as unique uuids.
153 // localids are used by the client to refer to parts.
154 // uuids are sent to the client and back to the server to identify parts on the server side.
155 /// <summary>
156 /// Changes localids and uuids of m_Entity.
157 /// </summary>
158 protected void Initialize(bool physics)
159 {
160 //make new uuids
161 Dictionary<UUID, SceneObjectPart> parts = new Dictionary<UUID, SceneObjectPart>();
162 foreach (SceneObjectPart part in m_Entity.Children.Values)
163 {
164 part.ResetIDs(part.LinkNum);
165 parts.Add(part.UUID, part);
166 }
167
168 //finalize
169 m_Entity.RootPart.PhysActor = null;
170 m_Entity.Children = parts;
171 }
172
173 #endregion Protected Methods
174
175 #region Public Methods
176
177 /// <summary>
178 /// Hides the metaentity from a single client.
179 /// </summary>
180 public virtual void Hide(IClientAPI client)
181 {
182 //This deletes the group without removing from any databases.
183 //This is important because we are not IN any database.
184 //m_Entity.FakeDeleteGroup();
185 foreach (SceneObjectPart part in m_Entity.Children.Values)
186 client.SendKillObject(m_Entity.RegionHandle, part.LocalId);
187 }
188
189 /// <summary>
190 /// Sends a kill object message to all clients, effectively "hiding" the metaentity even though it's still on the server.
191 /// </summary>
192 public virtual void HideFromAll()
193 {
194 foreach (SceneObjectPart part in m_Entity.Children.Values)
195 m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller)
196 { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); }
197 );
198 }
199
200 public void SendFullUpdate(IClientAPI client)
201 {
202 // Not sure what clientFlags should be but 0 seems to work
203 SendFullUpdate(client, 0);
204 }
205
206 public void SendFullUpdate(IClientAPI client, uint clientFlags)
207 {
208 m_Entity.SendFullUpdateToClient(client);
209 }
210
211 public void SendFullUpdateToAll()
212 {
213 m_Entity.Scene.ClientManager.ForEachClient(delegate(IClientAPI controller)
214 { m_Entity.SendFullUpdateToClient(controller); }
215 );
216 }
217
218 /// <summary>
219 /// Makes a single SceneObjectPart see through.
220 /// </summary>
221 /// <param name="part">
222 /// A <see cref="SceneObjectPart"/>
223 /// The part to make see through
224 /// </param>
225 /// <param name="transparencyAmount">
226 /// A <see cref="System.Single"/>
227 /// The degree of transparency to imbue the part with, 0f being solid and .95f being invisible.
228 /// </param>
229 public static void SetPartTransparency(SceneObjectPart part, float transparencyAmount)
230 {
231 Primitive.TextureEntry tex = null;
232 Color4 texcolor;
233 try
234 {
235 tex = part.Shape.Textures;
236 texcolor = new Color4();
237 }
238 catch(Exception)
239 {
240 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing textures of scene object: " + e);
241 return;
242 }
243
244 for (uint i = 0; i < tex.FaceTextures.Length; i++)
245 {
246 try {
247 if (tex.FaceTextures[i] != null)
248 {
249 texcolor = tex.FaceTextures[i].RGBA;
250 texcolor.A = transparencyAmount;
251 tex.FaceTextures[i].RGBA = texcolor;
252 }
253 }
254 catch (Exception)
255 {
256 //m_log.ErrorFormat("[Content Management]: Exception thrown while accessing different face textures of object: " + e);
257 continue;
258 }
259 }
260 try {
261 texcolor = tex.DefaultTexture.RGBA;
262 texcolor.A = transparencyAmount;
263 tex.DefaultTexture.RGBA = texcolor;
264 part.Shape.TextureEntry = tex.ToBytes();
265 }
266 catch (Exception)
267 {
268 //m_log.Info("[Content Management]: Exception thrown while accessing default face texture of object: " + e);
269 }
270 }
271
272 #endregion Public Methods
273 }
274}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
new file mode 100644
index 0000000..22f09fd
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/PointMetaEntity.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// PointMetaEntity.cs created with MonoDevelop
31// User: bongiojp at 3:03 PMĀ 8/6/2008
32//
33// To change standard headers go to Edit->Preferences->Coding->Standard Headers
34//
35
36#endregion Header
37
38using System;
39using System.Collections.Generic;
40using System.Drawing;
41
42using OpenMetaverse;
43
44using Nini.Config;
45
46using OpenSim.Framework;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Physics.Manager;
50
51using log4net;
52
53namespace OpenSim.Region.OptionalModules.ContentManagement
54{
55 public class PointMetaEntity : MetaEntity
56 {
57 #region Constructors
58
59 public PointMetaEntity(Scene scene, Vector3 groupPos, float transparency)
60 : base()
61 {
62 CreatePointEntity(scene, UUID.Random(), groupPos);
63 SetPartTransparency(m_Entity.RootPart, transparency);
64 }
65
66 public PointMetaEntity(Scene scene, UUID uuid, Vector3 groupPos, float transparency)
67 : base()
68 {
69 CreatePointEntity(scene, uuid, groupPos);
70 SetPartTransparency(m_Entity.RootPart, transparency);
71 }
72
73 #endregion Constructors
74
75 #region Private Methods
76
77 private void CreatePointEntity(Scene scene, UUID uuid, Vector3 groupPos)
78 {
79 SceneObjectGroup x = new SceneObjectGroup();
80 SceneObjectPart y = new SceneObjectPart();
81
82 //Initialize part
83 y.Name = "Very Small Point";
84 y.RegionHandle = scene.RegionInfo.RegionHandle;
85 y.CreationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
86 y.OwnerID = UUID.Zero;
87 y.CreatorID = UUID.Zero;
88 y.LastOwnerID = UUID.Zero;
89 y.UUID = uuid;
90
91 y.Shape = PrimitiveBaseShape.CreateBox();
92 y.Scale = new Vector3(0.01f,0.01f,0.01f);
93 y.LastOwnerID = UUID.Zero;
94 y.GroupPosition = groupPos;
95 y.OffsetPosition = new Vector3(0, 0, 0);
96 y.RotationOffset = new Quaternion(0,0,0,0);
97 y.Velocity = new Vector3(0, 0, 0);
98 y.RotationalVelocity = new Vector3(0, 0, 0);
99 y.AngularVelocity = new Vector3(0, 0, 0);
100 y.Acceleration = new Vector3(0, 0, 0);
101
102 y.Flags = 0;
103 y.TrimPermissions();
104
105 //Initialize group and add part as root part
106 x.SetScene(scene);
107 x.SetRootPart(y);
108 x.RegionHandle = scene.RegionInfo.RegionHandle;
109 x.SetScene(scene);
110
111 m_Entity = x;
112 }
113
114 #endregion Private Methods
115 }
116}
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/README b/OpenSim/Region/OptionalModules/ContentManagementSystem/README
new file mode 100644
index 0000000..1a69fef
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/README
@@ -0,0 +1,52 @@
1This module is meant to be built alone and not added to the Opensim code base. References are made to required dlls through a
2reference file, ContentManagement.mdp. Originally, for development, this project was contained in the Opensim/Region/Modules/
3directory.
4
5To compile: nant
6To use: Copy ContentManagement.dll into the bin directory of your Opensim build. You should find many other dlls in the same directory.
7
8
9--------------------------------------------------------------------------------------------------------------------
10To build the libgit.so file:
11
12#Download GIT git repository
13$ git clone git://git2.kernel.org/pub/OpenSim/Region/Environment/Modules/ContentManagementSystem/scm/git/git.git
14$ cd git
15
16#Compile GIT
17#Note that we are adding two extra flags to pass to gcc while compiling (-c and -fPIC)
18$ autoconf
19$ ./configure
20$ CFLAGS="-g -O2 -Wall -c -fPIC" make
21
22#Copy necessary object files (and some not so necessary) to their own directory for shared object file creation
23$ mkdir ../libgit-objects
24$ cp builtin*.o ../libgit-objects
25$ cp xdiff/*.o ../libgit-objects
26$ cp libgit.a ../libgit-objects
27
28#Remove the main symbol from any object files (like git.o)
29$ cd ../libgit-objects
30$ strip -N main *.o
31
32#Uncompress the plumbing objects from archive created by git
33$ ar x libgit.a
34
35#Create shared object file from all objects (including the zlib library)
36$ ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o
37
38
39#You can also just copy the following commands into a file and run as a script inside the git directory
40
41make clean
42autoconf
43./configure
44CFLAGS="-g -O2 -Wall -c -fPIC" make
45mkdir libgit-objects
46cp builtin*.o libgit-objects
47cp xdiff/*.o libgit-objects
48cp libgit.a libgit-objects
49cd libgit-objects
50strip -N main *.o
51ar x libgit.a
52ld -shared -soname libgit.so.1 -o libgit.so.1.5.6.3 -lc -lz *.o \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
new file mode 100644
index 0000000..8957e8f
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/SceneObjectGroupDiff.cs
@@ -0,0 +1,218 @@
1ļ»æ/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#region Header
29
30// SceneObjectGroupDiff.cs
31// User: bongiojp
32
33#endregion Header
34
35using System;
36using System.Collections.Generic;
37using System.Diagnostics;
38using System.Drawing;
39
40using OpenMetaverse;
41
42using Nini.Config;
43
44using OpenSim.Framework;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.Physics.Manager;
48
49using log4net;
50
51namespace OpenSim.Region.OptionalModules.ContentManagement
52{
53 #region Enumerations
54
55 [Flags]
56 public enum Diff
57 {
58 NONE = 0,
59 FACECOLOR = 1,
60 SHAPE = 1<<1,
61 MATERIAL = 1<<2,
62 TEXTURE = 1<<3,
63 SCALE = 1<<4,
64 POSITION = 1<<5,
65 OFFSETPOSITION = 1<<6,
66 ROTATIONOFFSET = 1<<7,
67 ROTATIONALVELOCITY = 1<<8,
68 ACCELERATION = 1<<9,
69 ANGULARVELOCITY = 1<<10,
70 VELOCITY = 1<<11,
71 OBJECTOWNER = 1<<12,
72 PERMISSIONS = 1<<13,
73 DESCRIPTION = 1<<14,
74 NAME = 1<<15,
75 SCRIPT = 1<<16,
76 CLICKACTION = 1<<17,
77 PARTICLESYSTEM = 1<<18,
78 GLOW = 1<<19,
79 SALEPRICE = 1<<20,
80 SITNAME = 1<<21,
81 SITTARGETORIENTATION = 1<<22,
82 SITTARGETPOSITION = 1<<23,
83 TEXT = 1<<24,
84 TOUCHNAME = 1<<25
85 }
86
87 #endregion Enumerations
88
89 public static class Difference
90 {
91 #region Static Fields
92
93 static float TimeToDiff = 0;
94// private static readonly ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
95
96 #endregion Static Fields
97
98 #region Private Methods
99
100 private static bool AreQuaternionsEquivalent(Quaternion first, Quaternion second)
101 {
102 Vector3 firstVector = llRot2Euler(first);
103 Vector3 secondVector = llRot2Euler(second);
104 return AreVectorsEquivalent(firstVector, secondVector);
105 }
106
107 private static bool AreVectorsEquivalent(Vector3 first, Vector3 second)
108 {
109 if (TruncateSignificant(first.X, 2) == TruncateSignificant(second.X, 2)
110 && TruncateSignificant(first.Y, 2) == TruncateSignificant(second.Y, 2)
111 && TruncateSignificant(first.Z, 2) == TruncateSignificant(second.Z, 2)
112 )
113 return true;
114 else
115 return false;
116 }
117
118 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
119 private static double NormalizeAngle(double angle)
120 {
121 angle = angle % (Math.PI * 2);
122 if (angle < 0) angle = angle + Math.PI * 2;
123 return angle;
124 }
125
126 private static int TruncateSignificant(float num, int digits)
127 {
128 return (int) Math.Ceiling((Math.Truncate(num * 10 * digits)/10*digits));
129 // return (int) ((num * (10*digits))/10*digits);
130 }
131
132 // Taken from Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
133 // Also changed the original function from LSL_Types to LL types
134 private static Vector3 llRot2Euler(Quaternion r)
135 {
136 Quaternion t = new Quaternion(r.X * r.X, r.Y * r.Y, r.Z * r.Z, r.W * r.W);
137 double m = (t.X + t.Y + t.Z + t.W);
138 if (m == 0) return new Vector3();
139 double n = 2 * (r.Y * r.W + r.X * r.Z);
140 double p = m * m - n * n;
141 if (p > 0)
142 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))),
143 (float)NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))),
144 (float)NormalizeAngle(Math.Atan2(2.0 * (r.Z * r.W - r.X * r.Y), (t.X - t.Y - t.Z + t.W))));
145 else if (n > 0)
146 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)));
147 else
148 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)));
149 }
150
151 #endregion Private Methods
152
153 #region Public Methods
154
155 /// <summary>
156 /// Compares the attributes (Vectors, Quaternions, Strings, etc.) between two scene object parts
157 /// and returns a Diff bitmask which details what the differences are.
158 /// </summary>
159 public static Diff FindDifferences(SceneObjectPart first, SceneObjectPart second)
160 {
161 Stopwatch x = new Stopwatch();
162 x.Start();
163
164 Diff result = 0;
165
166 // VECTOR COMPARISONS
167 if (!AreVectorsEquivalent(first.Acceleration, second.Acceleration))
168 result |= Diff.ACCELERATION;
169 if (!AreVectorsEquivalent(first.AbsolutePosition, second.AbsolutePosition))
170 result |= Diff.POSITION;
171 if (!AreVectorsEquivalent(first.AngularVelocity, second.AngularVelocity))
172 result |= Diff.ANGULARVELOCITY;
173 if (!AreVectorsEquivalent(first.OffsetPosition, second.OffsetPosition))
174 result |= Diff.OFFSETPOSITION;
175 if (!AreVectorsEquivalent(first.RotationalVelocity, second.RotationalVelocity))
176 result |= Diff.ROTATIONALVELOCITY;
177 if (!AreVectorsEquivalent(first.Scale, second.Scale))
178 result |= Diff.SCALE;
179 if (!AreVectorsEquivalent(first.Velocity, second.Velocity))
180 result |= Diff.VELOCITY;
181
182
183 // QUATERNION COMPARISONS
184 if (!AreQuaternionsEquivalent(first.RotationOffset, second.RotationOffset))
185 result |= Diff.ROTATIONOFFSET;
186
187
188 // MISC COMPARISONS (UUID, Byte)
189 if (first.ClickAction != second.ClickAction)
190 result |= Diff.CLICKACTION;
191 if (first.ObjectOwner != second.ObjectOwner)
192 result |= Diff.OBJECTOWNER;
193
194
195 // STRING COMPARISONS
196 if (first.Description != second.Description)
197 result |= Diff.DESCRIPTION;
198 if (first.Material != second.Material)
199 result |= Diff.MATERIAL;
200 if (first.Name != second.Name)
201 result |= Diff.NAME;
202 if (first.SitName != second.SitName)
203 result |= Diff.SITNAME;
204 if (first.Text != second.Text)
205 result |= Diff.TEXT;
206 if (first.TouchName != second.TouchName)
207 result |= Diff.TOUCHNAME;
208
209 x.Stop();
210 TimeToDiff += x.ElapsedMilliseconds;
211 //m_log.Info("[DIFFERENCES] Time spent diffing objects so far" + TimeToDiff);
212
213 return result;
214 }
215
216 #endregion Public Methods
217 }
218}