mirror of
https://github.com/opensim/opensim.git
synced 2026-05-25 11:15:42 +08:00
OpenSim.Region.Environment into a "framework" part and a modules only
part. This first changeset refactors OpenSim.Region.Environment.Scenes,
OpenSim.Region.Environment.Interfaces, and OpenSim.Region.Interfaces
into OpenSim.Region.Framework.{Interfaces,Scenes} leaving only region
modules in OpenSim.Region.Environment.
The next step will be to move region modules up from
OpenSim.Region.Environment.Modules to OpenSim.Region.CoreModules and
then sort out which modules are really core modules and which should
move out to forge.
I've been very careful to NOT BREAK anything. i hope i've
succeeded. as this is the work of a whole week i hope i managed to
keep track with the applied patches of the last week --- could any of
you that did check in stuff have a look at whether it survived? thx!
318 lines
12 KiB
C#
318 lines
12 KiB
C#
/*
|
|
* Copyright (c) Contributors, http://opensimulator.org/
|
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the OpenSim Project nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#region Header
|
|
|
|
// FileSystemDatabase.cs
|
|
// User: bongiojp
|
|
|
|
#endregion Header
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using Slash = System.IO.Path;
|
|
using System.Reflection;
|
|
using System.Xml;
|
|
|
|
using OpenMetaverse;
|
|
|
|
using Nini.Config;
|
|
|
|
using OpenSim.Framework;
|
|
using OpenSim.Region.Framework.Interfaces;
|
|
using OpenSim.Region.Framework.Scenes;
|
|
using OpenSim.Region.Environment.Modules.World.Serialiser;
|
|
using OpenSim.Region.Environment.Modules.World.Terrain;
|
|
using OpenSim.Region.Physics.Manager;
|
|
|
|
using log4net;
|
|
|
|
namespace OpenSim.Region.Environment.Modules.ContentManagement
|
|
{
|
|
public class FileSystemDatabase : IContentDatabase
|
|
{
|
|
#region Static Fields
|
|
|
|
public static float TimeToDownload = 0;
|
|
public static float TimeToSave = 0;
|
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
#endregion Static Fields
|
|
|
|
#region Fields
|
|
|
|
private string m_repodir = null;
|
|
private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>();
|
|
private Dictionary<UUID, IRegionSerialiserModule> m_serialiser = new Dictionary<UUID, IRegionSerialiserModule>();
|
|
|
|
#endregion Fields
|
|
|
|
#region Constructors
|
|
|
|
public FileSystemDatabase()
|
|
{
|
|
}
|
|
|
|
#endregion Constructors
|
|
|
|
#region Private Methods
|
|
|
|
// called by postinitialise
|
|
private void CreateDirectory()
|
|
{
|
|
string scenedir;
|
|
if (!Directory.Exists(m_repodir))
|
|
Directory.CreateDirectory(m_repodir);
|
|
|
|
foreach (UUID region in m_scenes.Keys)
|
|
{
|
|
scenedir = m_repodir + Slash.DirectorySeparatorChar + region + Slash.DirectorySeparatorChar;
|
|
if (!Directory.Exists(scenedir))
|
|
Directory.CreateDirectory(scenedir);
|
|
}
|
|
}
|
|
|
|
// called by postinitialise
|
|
private void SetupSerialiser()
|
|
{
|
|
if (m_serialiser.Count == 0)
|
|
{
|
|
foreach (UUID region in m_scenes.Keys)
|
|
{
|
|
m_serialiser.Add(region, m_scenes[region].RequestModuleInterface<IRegionSerialiserModule>());
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
|
|
#region Public Methods
|
|
|
|
public int GetMostRecentRevision(UUID regionid)
|
|
{
|
|
return NumOfRegionRev(regionid);
|
|
}
|
|
|
|
public string GetRegionObjectHeightMap(UUID regionid)
|
|
{
|
|
String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
|
|
Slash.DirectorySeparatorChar + "heightmap.r32";
|
|
FileStream fs = new FileStream( filename, FileMode.Open);
|
|
StreamReader sr = new StreamReader(fs);
|
|
String result = sr.ReadToEnd();
|
|
sr.Close();
|
|
fs.Close();
|
|
return result;
|
|
}
|
|
|
|
public string GetRegionObjectHeightMap(UUID regionid, int revision)
|
|
{
|
|
String filename = m_repodir + Slash.DirectorySeparatorChar + regionid +
|
|
Slash.DirectorySeparatorChar + "heightmap.r32";
|
|
FileStream fs = new FileStream( filename, FileMode.Open);
|
|
StreamReader sr = new StreamReader(fs);
|
|
String result = sr.ReadToEnd();
|
|
sr.Close();
|
|
fs.Close();
|
|
return result;
|
|
}
|
|
|
|
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid, int revision)
|
|
{
|
|
System.Collections.ArrayList objectList = new System.Collections.ArrayList();
|
|
string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
|
|
+ revision + Slash.DirectorySeparatorChar + "objects.xml";
|
|
XmlDocument doc = new XmlDocument();
|
|
XmlNode rootNode;
|
|
//int primCount = 0;
|
|
//SceneObjectGroup obj = null;
|
|
|
|
if (File.Exists(filename))
|
|
{
|
|
XmlTextReader reader = new XmlTextReader(filename);
|
|
reader.WhitespaceHandling = WhitespaceHandling.None;
|
|
doc.Load(reader);
|
|
reader.Close();
|
|
rootNode = doc.FirstChild;
|
|
foreach (XmlNode aPrimNode in rootNode.ChildNodes)
|
|
{
|
|
objectList.Add(aPrimNode.OuterXml);
|
|
}
|
|
return objectList;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public System.Collections.ArrayList GetRegionObjectXMLList(UUID regionid)
|
|
{
|
|
int revision = NumOfRegionRev(regionid);
|
|
m_log.Info("[FSDB]: found revisions:" + revision);
|
|
System.Collections.ArrayList xmlList = new System.Collections.ArrayList();
|
|
string filename = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar +
|
|
+ revision + Slash.DirectorySeparatorChar + "objects.xml";
|
|
XmlDocument doc = new XmlDocument();
|
|
XmlNode rootNode;
|
|
|
|
m_log.Info("[FSDB]: Checking if " + filename + " exists.");
|
|
if (File.Exists(filename))
|
|
{
|
|
Stopwatch x = new Stopwatch();
|
|
x.Start();
|
|
|
|
XmlTextReader reader = new XmlTextReader(filename);
|
|
reader.WhitespaceHandling = WhitespaceHandling.None;
|
|
doc.Load(reader);
|
|
reader.Close();
|
|
rootNode = doc.FirstChild;
|
|
|
|
foreach (XmlNode aPrimNode in rootNode.ChildNodes)
|
|
{
|
|
xmlList.Add(aPrimNode.OuterXml);
|
|
}
|
|
|
|
x.Stop();
|
|
TimeToDownload += x.ElapsedMilliseconds;
|
|
m_log.Info("[FileSystemDatabase] Time spent retrieving xml files so far: " + TimeToDownload);
|
|
|
|
return xmlList;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void Initialise(Scene scene, string dir)
|
|
{
|
|
lock (this)
|
|
{
|
|
if (m_repodir == null)
|
|
m_repodir = dir;
|
|
}
|
|
lock (m_scenes)
|
|
m_scenes.Add(scene.RegionInfo.RegionID, scene);
|
|
}
|
|
|
|
public System.Collections.Generic.SortedDictionary<string, string> ListOfRegionRevisions(UUID regionid)
|
|
{
|
|
SortedDictionary<string, string> revisionDict = new SortedDictionary<string,string>();
|
|
|
|
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
string[] directories = Directory.GetDirectories(scenedir);
|
|
|
|
FileStream fs = null;
|
|
StreamReader sr = null;
|
|
String logMessage = "";
|
|
String logLocation = "";
|
|
foreach (string revisionDir in directories)
|
|
{
|
|
try
|
|
{
|
|
logLocation = revisionDir + Slash.DirectorySeparatorChar + "log";
|
|
fs = new FileStream( logLocation, FileMode.Open);
|
|
sr = new StreamReader(fs);
|
|
logMessage = sr.ReadToEnd();
|
|
sr.Close();
|
|
fs.Close();
|
|
revisionDict.Add(revisionDir, logMessage);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
}
|
|
|
|
return revisionDict;
|
|
}
|
|
|
|
public int NumOfRegionRev(UUID regionid)
|
|
{
|
|
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
m_log.Info("[FSDB]: Reading scene dir: " + scenedir);
|
|
string[] directories = Directory.GetDirectories(scenedir);
|
|
return directories.Length;
|
|
}
|
|
|
|
// Run once and only once.
|
|
public void PostInitialise()
|
|
{
|
|
SetupSerialiser();
|
|
|
|
m_log.Info("[FSDB]: Creating repository in " + m_repodir + ".");
|
|
CreateDirectory();
|
|
}
|
|
|
|
public void SaveRegion(UUID regionid, string regionName, string logMessage)
|
|
{
|
|
m_log.Info("[FSDB]: ...............................");
|
|
string scenedir = m_repodir + Slash.DirectorySeparatorChar + regionid + Slash.DirectorySeparatorChar;
|
|
|
|
m_log.Info("[FSDB]: checking if scene directory exists: " + scenedir);
|
|
if (!Directory.Exists(scenedir))
|
|
Directory.CreateDirectory(scenedir);
|
|
|
|
int newRevisionNum = GetMostRecentRevision(regionid)+1;
|
|
string revisiondir = scenedir + newRevisionNum + Slash.DirectorySeparatorChar;
|
|
|
|
m_log.Info("[FSDB]: checking if revision directory exists: " + revisiondir);
|
|
if (!Directory.Exists(revisiondir))
|
|
Directory.CreateDirectory(revisiondir);
|
|
|
|
try {
|
|
Stopwatch x = new Stopwatch();
|
|
x.Start();
|
|
if (m_scenes.ContainsKey(regionid))
|
|
{
|
|
m_serialiser[regionid].SerialiseRegion(m_scenes[regionid], revisiondir);
|
|
}
|
|
x.Stop();
|
|
TimeToSave += x.ElapsedMilliseconds;
|
|
m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk for " + regionName + ": " + x.ElapsedMilliseconds);
|
|
m_log.Info("[FileSystemDatabase] Time spent serialising regions to files on disk so far: " + TimeToSave);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[FSDB]: Serialisation of region failed: " + e);
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Finish by writing log message.
|
|
FileStream file = new FileStream(revisiondir + "log", FileMode.Create, FileAccess.ReadWrite);
|
|
StreamWriter sw = new StreamWriter(file);
|
|
sw.Write(logMessage);
|
|
sw.Close();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[FSDB]: Failed trying to save log file " + e);
|
|
return;
|
|
}
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
}
|