aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs309
1 files changed, 309 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs
new file mode 100644
index 0000000..d3b3b77
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/ContentManagementSystem/CMModel.cs
@@ -0,0 +1,309 @@
1// CMModel.cs
2// User: bongiojp
3//
4//
5
6using System;
7using System.Collections.Generic;
8using System.Collections;
9using libsecondlife;
10using OpenSim;
11using OpenSim.Framework;
12using OpenSim.Region.Environment.Interfaces;
13using OpenSim.Region.Environment.Scenes;
14using log4net;
15using OpenSim.Region.Physics.Manager;
16using Axiom.Math;
17using System.Diagnostics;
18
19namespace OpenSim.Region.Environment.Modules.ContentManagement
20{
21
22 public class CMModel
23 {
24 static float TimeToUpdate = 0;
25 static float TimeToConvertXml = 0;
26
27 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
28
29 IContentDatabase m_database = null;
30
31 /// <value>
32 /// The class that contains all auras and metaentities used in the CMS.
33 /// </value>
34 CMEntityCollection m_MetaEntityCollection = new CMEntityCollection();
35
36 public CMEntityCollection MetaEntityCollection
37 {
38 get { return m_MetaEntityCollection; }
39 }
40
41 public CMModel()
42 {
43 }
44
45 public void Initialise(string database)
46 {
47 if (database == "FileSystemDatabase")
48 m_database = new FileSystemDatabase();
49 else if (database == "GitDatabase")
50 m_database = new GitDatabase();
51 }
52
53 public void InitialiseDatabase(Scene scene, string dir)
54 {
55 m_database.Initialise(scene, dir);
56 }
57
58 /// <summary>
59 /// Should be called just once to finish initializing the database.
60 /// </summary>
61 public void PostInitialise()
62 {
63 m_database.PostInitialise();
64 }
65
66 public ContentManagementEntity FindMetaEntityAffectedByUndo(LLUUID uuid)
67 {
68 ContentManagementEntity ent = GetMetaGroupByPrim(uuid);
69 return ent;
70 }
71
72 /// <summary>
73 /// Removes the green aura when an a new scene object group is deleted.
74 /// </summary>
75 public void RemoveOrUpdateDeletedEntity(SceneObjectGroup group)
76 {
77 // Deal with new parts not revisioned that have been deleted.
78 foreach(SceneObjectPart part in group.Children.Values)
79 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
80 m_MetaEntityCollection.RemoveNewlyCreatedEntityAura(part.UUID);
81 }
82
83 /// <summary>
84 /// Uses the database to serialize all current scene objects into xml and save into a database with an accompanying log message.
85 /// </summary>
86 public void CommitRegion(Scene scene, String logMessage)
87 {
88 m_log.Debug("[CONTENT MANAG] saving " + scene.RegionInfo.RegionName + " with log message: " + logMessage + " length of message: " + logMessage.Length);
89 m_database.SaveRegion(scene.RegionInfo.RegionID, scene.RegionInfo.RegionName, logMessage);
90 m_log.Debug("[CONTENT MANAG] the region name we are dealing with heeeeeeeere: " + scene.RegionInfo.RegionName );
91 }
92
93 /// <summary>
94 /// Retrieves the latest revision of a region in xml form,
95 /// converts it to scene object groups and scene presences,
96 /// swaps the current scene's entity list with the revision's list.
97 /// Note: Since deleted objects while
98 /// </summary>
99 public void RollbackRegion(Scene scene)
100 {
101 System.Collections.ArrayList xmllist = null;
102 SceneObjectGroup temp = null;
103 System.Collections.Hashtable deleteListUUIDs = new Hashtable();
104 Dictionary<LLUUID, EntityBase> SearchList = new Dictionary<LLUUID,EntityBase>();
105 Dictionary<LLUUID, EntityBase> ReplacementList = new Dictionary<LLUUID,EntityBase>();
106 int revision = m_database.GetMostRecentRevision(scene.RegionInfo.RegionID);
107 EntityBase[] searchArray;
108
109 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID, revision);
110 if (xmllist == null)
111 {
112 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") does not have given revision number (" + revision + ").");
113 return;
114 }
115
116 m_log.Info("[CMMODEL]: Region (" + scene.RegionInfo.RegionID + ") revision number (" + revision + ").");
117 m_log.Info("[CMMODEL]: Scene Objects = " + xmllist.Count);
118 m_log.Info("[CMMODEL]: Converting scene entities list to specified revision.");
119
120 m_log.ErrorFormat("[CMMODEL]: 1");
121
122 foreach (string xml in xmllist)
123 {
124 try{
125 temp = new SceneObjectGroup(xml);
126 temp.SetScene(scene);
127 foreach(SceneObjectPart part in temp.Children.Values)
128 part.RegionHandle = scene.RegionInfo.RegionHandle;
129 ReplacementList.Add(temp.UUID, (EntityBase)temp);
130 }
131 catch(Exception e)
132 {
133 m_log.Info("[CMMODEL]: Error while creating replacement list for rollback: " + e);
134 }
135 }
136
137 //If in scene but not in revision and not a client, remove them
138 while (true)
139 {
140 try
141 {
142 foreach(EntityBase entity in scene.GetEntities())
143 {
144 if (entity == null)
145 continue;
146
147 if (entity is ScenePresence)
148 {
149 ReplacementList.Add(entity.UUID, entity);
150 continue;
151 }
152 else //if (!ReplacementList.ContainsKey(entity.UUID))
153 deleteListUUIDs.Add(entity.UUID, 0);
154 }
155 }
156 catch(Exception e)
157 {
158 m_log.ErrorFormat("[CMMODEL]: " + e);
159 deleteListUUIDs.Clear();
160 ReplacementList.Clear();
161 continue;
162 }
163 break;
164 }
165
166 foreach(LLUUID uuid in deleteListUUIDs.Keys)
167 {
168 try
169 {
170 // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles.
171 ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup((SceneObjectGroup)scene.Entities[uuid]);
172 scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor);
173 scene.SendKillObject(scene.Entities[uuid].LocalId);
174 scene.m_innerScene.DeleteSceneObject(uuid, false);
175 ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroup();
176 }
177 catch(Exception e)
178 {
179 m_log.ErrorFormat("[CMMODEL]: Error while removing objects from scene: " + e);
180 }
181 }
182
183 lock (scene)
184 {
185 scene.Entities = ReplacementList;
186 }
187
188 foreach(EntityBase ent in ReplacementList.Values)
189 {
190 try
191 {
192 if (!(ent is SceneObjectGroup))
193 continue;
194
195 if ((((SceneObjectGroup)ent).RootPart.GetEffectiveObjectFlags() & (uint) LLObject.ObjectFlags.Phantom) == 0)
196 ((SceneObjectGroup)ent).ApplyPhysics(true);
197 ((SceneObjectGroup)ent).AttachToBackup();
198 ((SceneObjectGroup)ent).HasGroupChanged = true; // If not true, then attaching to backup does nothing because no change is detected.
199 ((SceneObjectGroup)ent).ScheduleGroupForFullUpdate();
200 }
201 catch(Exception e)
202 {
203 m_log.ErrorFormat("[CMMODEL]: Error while attaching new scene entities to backup and scheduling for a full update: " + e);
204 }
205 }
206 m_log.Info("[CMMODEL]: Scheduling a backup of new scene object groups to backup.");
207 scene.Backup();
208 }
209
210 /// <summary>
211 /// Detects if a scene object group from the scene list has moved or changed scale. The green aura
212 /// that surrounds the object is then moved or scaled with the group.
213 /// </summary>
214 public System.Collections.ArrayList UpdateNormalEntityEffects(SceneObjectGroup group)
215 {
216 System.Collections.ArrayList auraList = new System.Collections.ArrayList();
217 if (group == null)
218 return null;
219 foreach(SceneObjectPart part in group.Children.Values)
220 {
221 if (m_MetaEntityCollection.Auras.ContainsKey(part.UUID))
222 {
223 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).SetAura(new LLVector3(0,254,0), part.Scale);
224 ((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]).RootPart.GroupPosition = part.GetWorldPosition();
225 auraList.Add((AuraMetaEntity)m_MetaEntityCollection.Auras[part.UUID]);
226 }
227 }
228 return auraList;
229 }
230
231 public void DeleteAllMetaObjects()
232 {
233 m_MetaEntityCollection.ClearAll();
234 }
235
236 /// <summary>
237 /// Downloads the latest revision of the given scene and converts the xml file to CMEntities. After this method, the view can find the differences
238 /// and display the differences to clients.
239 /// </summary>
240 public void UpdateCMEntities(Scene scene)
241 {
242 Stopwatch x = new Stopwatch();
243 x.Start();
244
245 System.Collections.ArrayList xmllist = null;
246 m_log.Debug("[CONTENT MANAGEMENT] Retrieving object xml files for region: " + scene.RegionInfo.RegionID);
247 xmllist = m_database.GetRegionObjectXMLList(scene.RegionInfo.RegionID);
248 m_log.Info("[FSDB]: got list");
249 if (xmllist == null)
250 return;
251
252 Stopwatch y = new Stopwatch();
253 y.Start();
254 foreach (string xml in xmllist)
255 m_MetaEntityCollection.CreateNewEntity(xml, scene);
256 y.Stop();
257 TimeToConvertXml += y.ElapsedMilliseconds;
258 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities for " + scene.RegionInfo.RegionName + ": " + y.ElapsedMilliseconds);
259 m_log.Info("[FileSystemDatabase] Time spent converting xml to metaentities so far: " + TimeToConvertXml);
260
261 m_log.Info("[FSDB]: checking for new scene object parts missing green auras and create the auras");
262 CheckForNewEntitiesMissingAuras(scene);
263
264 x.Stop();
265 TimeToUpdate += x.ElapsedMilliseconds;
266 m_log.Info("[FileSystemDatabase] Time spent Updating entity list for " + scene.RegionInfo.RegionName + ": " + x.ElapsedMilliseconds);
267 m_log.Info("[FileSystemDatabase] Time spent Updating so far: " + TimeToUpdate);
268
269 }
270
271 /// <summary>
272 /// 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
273 /// it is a new part that must have a green aura (for diff mode).
274 /// Returns list of ContentManagementEntities
275 /// </summary>
276 public ArrayList CheckForNewEntitiesMissingAuras(Scene scene)
277 {
278 ArrayList missingList = null;
279 ArrayList newList = new ArrayList();
280
281 m_log.Debug("[CONTENT MANAGEMENT] Checking for new scene object parts in scene: " + scene.RegionInfo.RegionName);
282
283 //Check if the current scene has groups not included in the current list of MetaEntities
284 //If so, then the current scene's parts that are new should be marked green.
285 missingList = m_MetaEntityCollection.CheckForMissingEntities(scene.GetEntities());
286
287 foreach(Object missingPart in missingList)
288 {
289 if (m_MetaEntityCollection.Auras.ContainsKey(((SceneObjectPart)missingPart).UUID))
290 continue;
291 newList.Add(m_MetaEntityCollection.CreateAuraForNewlyCreatedEntity((SceneObjectPart)missingPart));
292 }
293 m_log.Info("Number of missing objects found: " + newList.Count);
294 return newList;
295 }
296
297//-------------------------------- HELPERS --------------------------------------------------------------------//
298
299 public ContentManagementEntity GetMetaGroupByPrim(LLUUID uuid)
300 {
301 foreach (Object ent in m_MetaEntityCollection.Entities.Values)
302 {
303 if (((ContentManagementEntity)ent).HasChildPrim(uuid))
304 return (ContentManagementEntity)ent;
305 }
306 return null;
307 }
308 }
309} \ No newline at end of file