aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs')
-rw-r--r--OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs362
1 files changed, 362 insertions, 0 deletions
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}