Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
27c34b69bf
|
@ -90,7 +90,7 @@ namespace OpenSim.Framework.Communications
|
|||
private byte[] _readbuf;
|
||||
|
||||
/// <summary>
|
||||
/// MemoryStream representing the resultiong resource
|
||||
/// MemoryStream representing the resulting resource
|
||||
/// </summary>
|
||||
private Stream _resource;
|
||||
|
||||
|
@ -352,42 +352,46 @@ namespace OpenSim.Framework.Communications
|
|||
m_log.DebugFormat("[LOGHTTP]: HTTP OUT {0} REST {1} to {2}", reqnum, _request.Method, _request.RequestUri);
|
||||
|
||||
// IAsyncResult responseAsyncResult = _request.BeginGetResponse(new AsyncCallback(ResponseIsReadyDelegate), _request);
|
||||
|
||||
try
|
||||
{
|
||||
_response = (HttpWebResponse) _request.GetResponse();
|
||||
using (_response = (HttpWebResponse) _request.GetResponse())
|
||||
{
|
||||
using (Stream src = _response.GetResponseStream())
|
||||
{
|
||||
int length = src.Read(_readbuf, 0, BufferSize);
|
||||
while (length > 0)
|
||||
{
|
||||
_resource.Write(_readbuf, 0, length);
|
||||
length = src.Read(_readbuf, 0, BufferSize);
|
||||
}
|
||||
|
||||
// TODO! Implement timeout, without killing the server
|
||||
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
|
||||
//ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
|
||||
|
||||
// _allDone.WaitOne();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (WebException e)
|
||||
{
|
||||
HttpWebResponse errorResponse = e.Response as HttpWebResponse;
|
||||
if (null != errorResponse && HttpStatusCode.NotFound == errorResponse.StatusCode)
|
||||
using (HttpWebResponse errorResponse = e.Response as HttpWebResponse)
|
||||
{
|
||||
// This is often benign. E.g., requesting a missing asset will return 404.
|
||||
m_log.DebugFormat("[REST CLIENT] Resource not found (404): {0}", _request.Address.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error(string.Format("[REST CLIENT] Error fetching resource from server: {0} ", _request.Address.ToString()), e);
|
||||
if (null != errorResponse && HttpStatusCode.NotFound == errorResponse.StatusCode)
|
||||
{
|
||||
// This is often benign. E.g., requesting a missing asset will return 404.
|
||||
m_log.DebugFormat("[REST CLIENT] Resource not found (404): {0}", _request.Address.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error(string.Format("[REST CLIENT] Error fetching resource from server: {0} ", _request.Address.ToString()), e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Stream src = _response.GetResponseStream();
|
||||
int length = src.Read(_readbuf, 0, BufferSize);
|
||||
while (length > 0)
|
||||
{
|
||||
_resource.Write(_readbuf, 0, length);
|
||||
length = src.Read(_readbuf, 0, BufferSize);
|
||||
}
|
||||
|
||||
|
||||
// TODO! Implement timeout, without killing the server
|
||||
// this line implements the timeout, if there is a timeout, the callback fires and the request becomes aborted
|
||||
//ThreadPool.RegisterWaitForSingleObject(responseAsyncResult.AsyncWaitHandle, new WaitOrTimerCallback(TimeoutCallback), _request, DefaultTimeout, true);
|
||||
|
||||
// _allDone.WaitOne();
|
||||
if (_response != null)
|
||||
_response.Close();
|
||||
if (_asyncException != null)
|
||||
throw _asyncException;
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ namespace OpenSim.Framework
|
|||
{
|
||||
public interface ISceneObject
|
||||
{
|
||||
string Name { get; }
|
||||
|
||||
UUID UUID { get; }
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -256,20 +256,7 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
// If the file is already cached, don't cache it, just touch it so access time is updated
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
// We don't really want to know about sharing
|
||||
// violations here. If the file is locked, then
|
||||
// the other thread has updated the time for us.
|
||||
try
|
||||
{
|
||||
lock (m_CurrentlyWriting)
|
||||
{
|
||||
if (!m_CurrentlyWriting.Contains(filename))
|
||||
File.SetLastAccessTime(filename, DateTime.Now);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
UpdateFileLastAccessTime(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -328,6 +315,24 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the cached file with the current time.
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename.</param>
|
||||
/// <returns><c>true</c>, if the update was successful, false otherwise.</returns>
|
||||
private bool UpdateFileLastAccessTime(string filename)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.SetLastAccessTime(filename, DateTime.Now);
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to get an asset from the in-memory cache.
|
||||
/// </summary>
|
||||
|
@ -771,8 +776,8 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
{
|
||||
UuidGatherer gatherer = new UuidGatherer(m_AssetService);
|
||||
|
||||
HashSet<UUID> uniqueUuids = new HashSet<UUID>();
|
||||
Dictionary<UUID, sbyte> assets = new Dictionary<UUID, sbyte>();
|
||||
Dictionary<UUID, sbyte> assetIdsToCheck = new Dictionary<UUID, sbyte>();
|
||||
Dictionary<UUID, bool> assetsFound = new Dictionary<UUID, bool>();
|
||||
|
||||
foreach (Scene s in m_Scenes)
|
||||
{
|
||||
|
@ -780,34 +785,40 @@ namespace OpenSim.Region.CoreModules.Asset
|
|||
|
||||
s.ForEachSOG(delegate(SceneObjectGroup e)
|
||||
{
|
||||
gatherer.GatherAssetUuids(e, assets);
|
||||
gatherer.GatherAssetUuids(e, assetIdsToCheck);
|
||||
|
||||
foreach (UUID assetID in assets.Keys)
|
||||
foreach (UUID assetID in assetIdsToCheck.Keys)
|
||||
{
|
||||
uniqueUuids.Add(assetID);
|
||||
|
||||
string filename = GetFileName(assetID.ToString());
|
||||
|
||||
if (File.Exists(filename))
|
||||
if (!assetsFound.ContainsKey(assetID))
|
||||
{
|
||||
File.SetLastAccessTime(filename, DateTime.Now);
|
||||
string filename = GetFileName(assetID.ToString());
|
||||
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
UpdateFileLastAccessTime(filename);
|
||||
}
|
||||
else if (storeUncached)
|
||||
{
|
||||
AssetBase cachedAsset = m_AssetService.Get(assetID.ToString());
|
||||
if (cachedAsset == null && assetIdsToCheck[assetID] != (sbyte)AssetType.Unknown)
|
||||
assetsFound[assetID] = false;
|
||||
else
|
||||
assetsFound[assetID] = true;
|
||||
}
|
||||
}
|
||||
else if (storeUncached)
|
||||
else if (!assetsFound[assetID])
|
||||
{
|
||||
AssetBase cachedAsset = m_AssetService.Get(assetID.ToString());
|
||||
if (cachedAsset == null && assets[assetID] != (sbyte)AssetType.Unknown)
|
||||
m_log.DebugFormat(
|
||||
m_log.DebugFormat(
|
||||
"[FLOTSAM ASSET CACHE]: Could not find asset {0}, type {1} referenced by object {2} at {3} in scene {4} when pre-caching all scene assets",
|
||||
assetID, assets[assetID], e.Name, e.AbsolutePosition, s.Name);
|
||||
assetID, assetIdsToCheck[assetID], e.Name, e.AbsolutePosition, s.Name);
|
||||
}
|
||||
}
|
||||
|
||||
assets.Clear();
|
||||
assetIdsToCheck.Clear();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return uniqueUuids.Count;
|
||||
return assetsFound.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -255,6 +255,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
|
||||
public void CopyAttachments(AgentData ad, IScenePresence sp)
|
||||
{
|
||||
// m_log.DebugFormat("[ATTACHMENTS MODULE]: Copying attachment data into {0} in {1}", sp.Name, m_scene.Name);
|
||||
|
||||
if (ad.AttachmentObjects != null && ad.AttachmentObjects.Count > 0)
|
||||
{
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
|
@ -265,6 +267,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
{
|
||||
((SceneObjectGroup)so).LocalId = 0;
|
||||
((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: Copying script state with {0} bytes for object {1} for {2} in {3}",
|
||||
// ad.AttachmentObjectStates[i].Length, so.Name, sp.Name, m_scene.Name);
|
||||
|
||||
so.SetState(ad.AttachmentObjectStates[i++], m_scene);
|
||||
m_scene.IncomingCreateObject(Vector3.Zero, so);
|
||||
}
|
||||
|
@ -334,11 +341,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
if (!Enabled)
|
||||
return;
|
||||
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name);
|
||||
|
||||
List<SceneObjectGroup> attachments = sp.GetAttachments();
|
||||
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat(
|
||||
"[ATTACHMENTS MODULE]: Saving for {0} attachments for {1} in {2}",
|
||||
attachments.Count, sp.Name, m_scene.Name);
|
||||
|
||||
if (attachments.Count <= 0)
|
||||
return;
|
||||
|
||||
|
@ -352,6 +361,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
// This must be done outside the sp.AttachmentSyncLock so that there is no risk of a deadlock from
|
||||
// scripts performing attachment operations at the same time. Getting object states stops the scripts.
|
||||
scriptStates[so] = PrepareScriptInstanceForSave(so, false);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ATTACHMENTS MODULE]: For object {0} for {1} in {2} got saved state {3}",
|
||||
// so.Name, sp.Name, m_scene.Name, scriptStates[so]);
|
||||
}
|
||||
|
||||
lock (sp.AttachmentsSyncLock)
|
||||
|
@ -819,8 +832,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
|
|||
{
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat(
|
||||
"[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}",
|
||||
so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos);
|
||||
"[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} at pt {2} pos {3} {4} in {5}",
|
||||
so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos, m_scene.Name);
|
||||
|
||||
// Remove from database and parcel prim count
|
||||
m_scene.DeleteFromStorage(so.UUID);
|
||||
|
|
|
@ -103,48 +103,51 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
|
|||
return null;
|
||||
|
||||
int size = 0;
|
||||
RestClient rc = new RestClient(m_URL);
|
||||
List<WearableCacheItem> ret = new List<WearableCacheItem>();
|
||||
rc.AddResourcePath("bakes");
|
||||
rc.AddResourcePath(id.ToString());
|
||||
|
||||
rc.RequestMethod = "GET";
|
||||
|
||||
try
|
||||
using (RestClient rc = new RestClient(m_URL))
|
||||
{
|
||||
Stream s = rc.Request(m_Auth);
|
||||
XmlTextReader sr = new XmlTextReader(s);
|
||||
List<WearableCacheItem> ret = new List<WearableCacheItem>();
|
||||
rc.AddResourcePath("bakes");
|
||||
rc.AddResourcePath(id.ToString());
|
||||
|
||||
sr.ReadStartElement("BakedAppearance");
|
||||
while (sr.LocalName == "BakedTexture")
|
||||
rc.RequestMethod = "GET";
|
||||
|
||||
try
|
||||
{
|
||||
string sTextureIndex = sr.GetAttribute("TextureIndex");
|
||||
int lTextureIndex = Convert.ToInt32(sTextureIndex);
|
||||
string sCacheId = sr.GetAttribute("CacheId");
|
||||
UUID lCacheId = UUID.Zero;
|
||||
if (!(UUID.TryParse(sCacheId, out lCacheId)))
|
||||
Stream s = rc.Request(m_Auth);
|
||||
|
||||
using (XmlTextReader sr = new XmlTextReader(s))
|
||||
{
|
||||
// ?? Nothing here
|
||||
sr.ReadStartElement("BakedAppearance");
|
||||
while (sr.LocalName == "BakedTexture")
|
||||
{
|
||||
string sTextureIndex = sr.GetAttribute("TextureIndex");
|
||||
int lTextureIndex = Convert.ToInt32(sTextureIndex);
|
||||
string sCacheId = sr.GetAttribute("CacheId");
|
||||
UUID lCacheId = UUID.Zero;
|
||||
if (!(UUID.TryParse(sCacheId, out lCacheId)))
|
||||
{
|
||||
// ?? Nothing here
|
||||
}
|
||||
|
||||
++size;
|
||||
|
||||
sr.ReadStartElement("BakedTexture");
|
||||
AssetBase a = (AssetBase)m_serializer.Deserialize(sr);
|
||||
ret.Add(new WearableCacheItem() { CacheId = lCacheId, TextureIndex = (uint)lTextureIndex, TextureAsset = a, TextureID = a.FullID });
|
||||
|
||||
sr.ReadEndElement();
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[XBakes]: read {0} textures for user {1}", ret.Count, id);
|
||||
}
|
||||
|
||||
++size;
|
||||
|
||||
sr.ReadStartElement("BakedTexture");
|
||||
AssetBase a = (AssetBase)m_serializer.Deserialize(sr);
|
||||
ret.Add(new WearableCacheItem() { CacheId = lCacheId, TextureIndex = (uint)lTextureIndex, TextureAsset = a, TextureID = a.FullID });
|
||||
|
||||
sr.ReadEndElement();
|
||||
return ret.ToArray();
|
||||
}
|
||||
catch (XmlException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
m_log.DebugFormat("[XBakes]: read {0} textures for user {1}", ret.Count, id);
|
||||
sr.Close();
|
||||
s.Close();
|
||||
|
||||
|
||||
return ret.ToArray();
|
||||
}
|
||||
catch (XmlException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,27 +156,32 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
|
|||
if (m_URL == String.Empty)
|
||||
return;
|
||||
|
||||
MemoryStream bakeStream = new MemoryStream();
|
||||
XmlTextWriter bakeWriter = new XmlTextWriter(bakeStream, null);
|
||||
MemoryStream reqStream;
|
||||
|
||||
bakeWriter.WriteStartElement(String.Empty, "BakedAppearance", String.Empty);
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
using (MemoryStream bakeStream = new MemoryStream())
|
||||
using (XmlTextWriter bakeWriter = new XmlTextWriter(bakeStream, null))
|
||||
{
|
||||
if (data[i] != null)
|
||||
bakeWriter.WriteStartElement(String.Empty, "BakedAppearance", String.Empty);
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
bakeWriter.WriteStartElement(String.Empty, "BakedTexture", String.Empty);
|
||||
bakeWriter.WriteAttributeString(String.Empty, "TextureIndex", String.Empty, data[i].TextureIndex.ToString());
|
||||
bakeWriter.WriteAttributeString(String.Empty, "CacheId", String.Empty, data[i].CacheId.ToString());
|
||||
if (data[i].TextureAsset != null)
|
||||
m_serializer.Serialize(bakeWriter, data[i].TextureAsset);
|
||||
if (data[i] != null)
|
||||
{
|
||||
bakeWriter.WriteStartElement(String.Empty, "BakedTexture", String.Empty);
|
||||
bakeWriter.WriteAttributeString(String.Empty, "TextureIndex", String.Empty, data[i].TextureIndex.ToString());
|
||||
bakeWriter.WriteAttributeString(String.Empty, "CacheId", String.Empty, data[i].CacheId.ToString());
|
||||
if (data[i].TextureAsset != null)
|
||||
m_serializer.Serialize(bakeWriter, data[i].TextureAsset);
|
||||
|
||||
bakeWriter.WriteEndElement();
|
||||
bakeWriter.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bakeWriter.WriteEndElement();
|
||||
bakeWriter.Flush();
|
||||
bakeWriter.WriteEndElement();
|
||||
bakeWriter.Flush();
|
||||
|
||||
reqStream = new MemoryStream(bakeStream.ToArray());
|
||||
}
|
||||
|
||||
RestClient rc = new RestClient(m_URL);
|
||||
rc.AddResourcePath("bakes");
|
||||
|
@ -181,7 +189,6 @@ namespace OpenSim.Region.CoreModules.Avatar.BakedTextures
|
|||
|
||||
rc.RequestMethod = "POST";
|
||||
|
||||
MemoryStream reqStream = new MemoryStream(bakeStream.ToArray());
|
||||
Util.FireAndForget(
|
||||
delegate
|
||||
{
|
||||
|
|
|
@ -604,8 +604,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
// "[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset service {2}",
|
||||
// so.Name, so.AttachedAvatar, url);
|
||||
|
||||
IteratingHGUuidGatherer uuidGatherer = new IteratingHGUuidGatherer(Scene.AssetService, url);
|
||||
uuidGatherer.RecordAssetUuids(so);
|
||||
IDictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
|
||||
IteratingHGUuidGatherer uuidGatherer
|
||||
= new IteratingHGUuidGatherer(Scene.AssetService, url, ids);
|
||||
uuidGatherer.AddForInspection(so);
|
||||
|
||||
while (!uuidGatherer.Complete)
|
||||
{
|
||||
|
@ -632,8 +634,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
}
|
||||
|
||||
IDictionary<UUID, sbyte> ids = uuidGatherer.GetGatheredUuids();
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[HG ENTITY TRANSFER]: Fetching {0} assets for attachment {1} for HG user {2} with asset service {3}",
|
||||
// ids.Count, so.Name, so.OwnerID, url);
|
||||
|
|
|
@ -680,6 +680,21 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
|||
"Show the bindings between user UUIDs and user names",
|
||||
String.Empty,
|
||||
HandleShowUsers);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||
"reset user cache",
|
||||
"reset user cache",
|
||||
"reset user cache to allow changed settings to be applied",
|
||||
String.Empty,
|
||||
HandleResetUserCache);
|
||||
}
|
||||
|
||||
private void HandleResetUserCache(string module, string[] cmd)
|
||||
{
|
||||
lock(m_UserCache)
|
||||
{
|
||||
m_UserCache.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleShowUser(string module, string[] cmd)
|
||||
|
|
|
@ -595,6 +595,9 @@ namespace OpenSim.Region.CoreModules.World.Media.Moap
|
|||
/// <returns>true if the url matches an entry on the whitelist, false otherwise</returns>
|
||||
protected bool CheckUrlAgainstWhitelist(string rawUrl, string[] whitelist)
|
||||
{
|
||||
if (whitelist == null)
|
||||
return false;
|
||||
|
||||
Uri url = new Uri(rawUrl);
|
||||
|
||||
foreach (string origWlUrl in whitelist)
|
||||
|
|
|
@ -122,6 +122,17 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <summary>
|
||||
/// Check if the caller has permission to manipulate the given NPC.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A caller has permission if
|
||||
/// * An NPC exists with the given npcID.
|
||||
/// * The caller UUID given is UUID.Zero.
|
||||
/// * The avatar is unowned (owner is UUID.Zero).
|
||||
/// * The avatar is owned and the owner and callerID match.
|
||||
/// * The avatar is owned and the callerID matches its agentID.
|
||||
/// </remarks>
|
||||
/// <param name="av"></param>
|
||||
/// <param name="callerID"></param>
|
||||
/// <returns>true if they do, false if they don't.</returns>
|
||||
/// <param name="npcID"></param>
|
||||
/// <param name="callerID"></param>
|
||||
/// <returns>
|
||||
|
|
|
@ -823,7 +823,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_sceneGridService = sceneGridService;
|
||||
m_SimulationDataService = simDataService;
|
||||
m_EstateDataService = estateDataService;
|
||||
m_regionHandle = RegionInfo.RegionHandle;
|
||||
|
||||
m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
|
||||
m_asyncSceneObjectDeleter.Enabled = true;
|
||||
|
@ -2042,11 +2041,11 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
GridRegion region = new GridRegion(RegionInfo);
|
||||
string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
|
||||
m_log.DebugFormat("{0} RegisterRegionWithGrid. name={1},id={2},loc=<{3},{4}>,size=<{5},{6}>",
|
||||
LogHeader, m_regionName,
|
||||
RegionInfo.RegionID,
|
||||
RegionInfo.RegionLocX, RegionInfo.RegionLocY,
|
||||
RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
|
||||
// m_log.DebugFormat("[SCENE]: RegisterRegionWithGrid. name={0},id={1},loc=<{2},{3}>,size=<{4},{5}>",
|
||||
// m_regionName,
|
||||
// RegionInfo.RegionID,
|
||||
// RegionInfo.RegionLocX, RegionInfo.RegionLocY,
|
||||
// RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
|
||||
|
||||
if (error != String.Empty)
|
||||
throw new Exception(error);
|
||||
|
|
|
@ -145,10 +145,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
get { return 1.0f; }
|
||||
}
|
||||
|
||||
protected ulong m_regionHandle;
|
||||
protected string m_regionName;
|
||||
protected RegionInfo m_regInfo;
|
||||
|
||||
public ITerrainChannel Heightmap;
|
||||
|
||||
/// <value>
|
||||
|
|
|
@ -1228,45 +1228,27 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
m_scene.SwapRootAgentCount(false);
|
||||
|
||||
// The initial login scene presence is already root when it gets here
|
||||
// and it has already rezzed the attachments and started their scripts.
|
||||
// We do the following only for non-login agents, because their scripts
|
||||
// haven't started yet.
|
||||
if (PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags))
|
||||
if (Scene.AttachmentsModule != null)
|
||||
{
|
||||
// Viewers which have a current outfit folder will actually rez their own attachments. However,
|
||||
// viewers without (e.g. v1 viewers) will not, so we still need to make this call.
|
||||
if (Scene.AttachmentsModule != null)
|
||||
// The initial login scene presence is already root when it gets here
|
||||
// and it has already rezzed the attachments and started their scripts.
|
||||
// We do the following only for non-login agents, because their scripts
|
||||
// haven't started yet.
|
||||
if (PresenceType == PresenceType.Npc || IsRealLogin(m_teleportFlags))
|
||||
{
|
||||
// Viewers which have a current outfit folder will actually rez their own attachments. However,
|
||||
// viewers without (e.g. v1 viewers) will not, so we still need to make this call.
|
||||
WorkManager.RunJob(
|
||||
"RezAttachments",
|
||||
o => Scene.AttachmentsModule.RezAttachments(this),
|
||||
null,
|
||||
string.Format("Rez attachments for {0} in {1}", Name, Scene.Name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
|
||||
// and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
|
||||
// be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
|
||||
// not transporting the required data.
|
||||
//
|
||||
// We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
|
||||
// the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
|
||||
// which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
|
||||
//
|
||||
// FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
|
||||
// But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
|
||||
// is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
|
||||
// script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
|
||||
List<SceneObjectGroup> attachments = GetAttachments();
|
||||
|
||||
if (attachments.Count > 0)
|
||||
else
|
||||
{
|
||||
WorkManager.RunJob(
|
||||
"StartAttachmentScripts",
|
||||
o => RestartAttachmentScripts(attachments),
|
||||
o => RestartAttachmentScripts(),
|
||||
null,
|
||||
string.Format("Start attachment scripts for {0} in {1}", Name, Scene.Name),
|
||||
true);
|
||||
|
@ -1292,10 +1274,25 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return true;
|
||||
}
|
||||
|
||||
private void RestartAttachmentScripts(List<SceneObjectGroup> attachments)
|
||||
private void RestartAttachmentScripts()
|
||||
{
|
||||
// We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT
|
||||
// and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently
|
||||
// be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are
|
||||
// not transporting the required data.
|
||||
//
|
||||
// We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of
|
||||
// the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here
|
||||
// which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status.
|
||||
//
|
||||
// FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts().
|
||||
// But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing
|
||||
// is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the
|
||||
// script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine.
|
||||
List<SceneObjectGroup> attachments = GetAttachments();
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name);
|
||||
"[SCENE PRESENCE]: Restarting scripts in {0} attachments for {1} in {2}", attachments.Count, Name, Scene.Name);
|
||||
|
||||
// Resume scripts
|
||||
foreach (SceneObjectGroup sog in attachments)
|
||||
|
|
|
@ -648,6 +648,15 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gather uuids for a given entity.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This does a deep inspection of the entity to retrieve all the assets it uses (whether as textures, as scripts
|
||||
/// contained in inventory, as scripts contained in objects contained in another object's inventory, etc. Assets
|
||||
/// are only retrieved when they are necessary to carry out the inspection (i.e. a serialized object needs to be
|
||||
/// retrieved to work out which assets it references).
|
||||
/// </remarks>
|
||||
public class IteratingUuidGatherer
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
@ -678,21 +687,31 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
protected Queue<UUID> m_assetUuidsToInspect;
|
||||
|
||||
public IteratingUuidGatherer(IAssetService assetService)
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenSim.Region.Framework.Scenes.UuidGatherer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="assetService">
|
||||
/// Asset service.
|
||||
/// </param>
|
||||
/// <param name="collector">
|
||||
/// Gathered UUIDs will be collected in this dictinaory.
|
||||
/// It can be pre-populated if you want to stop the gatherer from analyzing assets that have already been fetched and inspected.
|
||||
/// </param>
|
||||
public IteratingUuidGatherer(IAssetService assetService, IDictionary<UUID, sbyte> collector)
|
||||
{
|
||||
m_assetService = assetService;
|
||||
m_gatheredAssetUuids = new Dictionary<UUID, sbyte>();
|
||||
m_gatheredAssetUuids = collector;
|
||||
|
||||
// FIXME: Not efficient for searching, can improve.
|
||||
m_assetUuidsToInspect = new Queue<UUID>();
|
||||
}
|
||||
|
||||
public IDictionary<UUID, sbyte> GetGatheredUuids()
|
||||
{
|
||||
return new Dictionary<UUID, sbyte>(m_gatheredAssetUuids);
|
||||
}
|
||||
|
||||
public bool AddAssetUuidToInspect(UUID uuid)
|
||||
/// <summary>
|
||||
/// Adds the asset uuid for inspection during the gathering process.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if for inspection was added, <c>false</c> otherwise.</returns>
|
||||
/// <param name="uuid">UUID.</param>
|
||||
public bool AddForInspection(UUID uuid)
|
||||
{
|
||||
if (m_assetUuidsToInspect.Contains(uuid))
|
||||
return false;
|
||||
|
@ -702,6 +721,107 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gather all the asset uuids associated with a given object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This includes both those directly associated with
|
||||
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
|
||||
/// within this object).
|
||||
/// </remarks>
|
||||
/// <param name="sceneObject">The scene object for which to gather assets</param>
|
||||
public void AddForInspection(SceneObjectGroup sceneObject)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
|
||||
|
||||
SceneObjectPart[] parts = sceneObject.Parts;
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
SceneObjectPart part = parts[i];
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
|
||||
|
||||
try
|
||||
{
|
||||
Primitive.TextureEntry textureEntry = part.Shape.Textures;
|
||||
if (textureEntry != null)
|
||||
{
|
||||
// Get the prim's default texture. This will be used for faces which don't have their own texture
|
||||
if (textureEntry.DefaultTexture != null)
|
||||
RecordTextureEntryAssetUuids(textureEntry.DefaultTexture);
|
||||
|
||||
if (textureEntry.FaceTextures != null)
|
||||
{
|
||||
// Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture)
|
||||
foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
|
||||
{
|
||||
if (texture != null)
|
||||
RecordTextureEntryAssetUuids(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the prim is a sculpt then preserve this information too
|
||||
if (part.Shape.SculptTexture != UUID.Zero)
|
||||
m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
|
||||
|
||||
if (part.Shape.ProjectionTextureUUID != UUID.Zero)
|
||||
m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
|
||||
|
||||
if (part.CollisionSound != UUID.Zero)
|
||||
m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
|
||||
|
||||
if (part.ParticleSystem.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
|
||||
if (ps.Texture != UUID.Zero)
|
||||
m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
|
||||
part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
|
||||
|
||||
// Now analyze this prim's inventory items to preserve all the uuids that they reference
|
||||
foreach (TaskInventoryItem tii in taskDictionary.Values)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
|
||||
// tii.Name, tii.Type, part.Name, part.UUID);
|
||||
|
||||
if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID))
|
||||
AddForInspection(tii.AssetID, (sbyte)tii.Type);
|
||||
}
|
||||
|
||||
// FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
|
||||
// to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
|
||||
// inventory transfer. There needs to be a way for a module to register a method without assuming a
|
||||
// Scene.EventManager is present.
|
||||
// part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
|
||||
|
||||
|
||||
// still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
|
||||
RecordMaterialsUuids(part);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
|
||||
m_log.DebugFormat(
|
||||
"[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
|
||||
part.Shape.TextureEntry.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gathers the next set of assets returned by the next uuid to get from the asset service.
|
||||
/// </summary>
|
||||
|
@ -790,7 +910,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
private void RecordAssetUuids(UUID assetUuid, sbyte assetType)
|
||||
private void AddForInspection(UUID assetUuid, sbyte assetType)
|
||||
{
|
||||
// Here, we want to collect uuids which require further asset fetches but mark the others as gathered
|
||||
try
|
||||
|
@ -799,27 +919,27 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType)
|
||||
{
|
||||
AddAssetUuidToInspect(assetUuid);
|
||||
AddForInspection(assetUuid);
|
||||
}
|
||||
else if ((sbyte)AssetType.Gesture == assetType)
|
||||
{
|
||||
AddAssetUuidToInspect(assetUuid);
|
||||
AddForInspection(assetUuid);
|
||||
}
|
||||
else if ((sbyte)AssetType.Notecard == assetType)
|
||||
{
|
||||
AddAssetUuidToInspect(assetUuid);
|
||||
AddForInspection(assetUuid);
|
||||
}
|
||||
else if ((sbyte)AssetType.LSLText == assetType)
|
||||
{
|
||||
AddAssetUuidToInspect(assetUuid);
|
||||
AddForInspection(assetUuid);
|
||||
}
|
||||
else if ((sbyte)OpenSimAssetType.Material == assetType)
|
||||
{
|
||||
AddAssetUuidToInspect(assetUuid);
|
||||
AddForInspection(assetUuid);
|
||||
}
|
||||
else if ((sbyte)AssetType.Object == assetType)
|
||||
{
|
||||
AddAssetUuidToInspect(assetUuid);
|
||||
AddForInspection(assetUuid);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
|
@ -831,107 +951,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gather all the asset uuids associated with a given object.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This includes both those directly associated with
|
||||
/// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained
|
||||
/// within this object).
|
||||
/// </remarks>
|
||||
/// <param name="sceneObject">The scene object for which to gather assets</param>
|
||||
public void RecordAssetUuids(SceneObjectGroup sceneObject)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ASSET GATHERER]: Getting assets for object {0}, {1}", sceneObject.Name, sceneObject.UUID);
|
||||
|
||||
SceneObjectPart[] parts = sceneObject.Parts;
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
SceneObjectPart part = parts[i];
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Getting part {0}, {1} for object {2}", part.Name, part.UUID, sceneObject.UUID);
|
||||
|
||||
try
|
||||
{
|
||||
Primitive.TextureEntry textureEntry = part.Shape.Textures;
|
||||
if (textureEntry != null)
|
||||
{
|
||||
// Get the prim's default texture. This will be used for faces which don't have their own texture
|
||||
if (textureEntry.DefaultTexture != null)
|
||||
RecordTextureEntryAssetUuids(textureEntry.DefaultTexture);
|
||||
|
||||
if (textureEntry.FaceTextures != null)
|
||||
{
|
||||
// Loop through the rest of the texture faces (a non-null face means the face is different from DefaultTexture)
|
||||
foreach (Primitive.TextureEntryFace texture in textureEntry.FaceTextures)
|
||||
{
|
||||
if (texture != null)
|
||||
RecordTextureEntryAssetUuids(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the prim is a sculpt then preserve this information too
|
||||
if (part.Shape.SculptTexture != UUID.Zero)
|
||||
m_gatheredAssetUuids[part.Shape.SculptTexture] = (sbyte)AssetType.Texture;
|
||||
|
||||
if (part.Shape.ProjectionTextureUUID != UUID.Zero)
|
||||
m_gatheredAssetUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
|
||||
|
||||
if (part.CollisionSound != UUID.Zero)
|
||||
m_gatheredAssetUuids[part.CollisionSound] = (sbyte)AssetType.Sound;
|
||||
|
||||
if (part.ParticleSystem.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
Primitive.ParticleSystem ps = new Primitive.ParticleSystem(part.ParticleSystem, 0);
|
||||
if (ps.Texture != UUID.Zero)
|
||||
m_gatheredAssetUuids[ps.Texture] = (sbyte)AssetType.Texture;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[UUID GATHERER]: Could not check particle system for part {0} {1} in object {2} {3} since it is corrupt. Continuing.",
|
||||
part.Name, part.UUID, sceneObject.Name, sceneObject.UUID);
|
||||
}
|
||||
}
|
||||
|
||||
TaskInventoryDictionary taskDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
|
||||
|
||||
// Now analyze this prim's inventory items to preserve all the uuids that they reference
|
||||
foreach (TaskInventoryItem tii in taskDictionary.Values)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[ARCHIVER]: Analysing item {0} asset type {1} in {2} {3}",
|
||||
// tii.Name, tii.Type, part.Name, part.UUID);
|
||||
|
||||
if (!m_gatheredAssetUuids.ContainsKey(tii.AssetID))
|
||||
RecordAssetUuids(tii.AssetID, (sbyte)tii.Type);
|
||||
}
|
||||
|
||||
// FIXME: We need to make gathering modular but we cannot yet, since gatherers are not guaranteed
|
||||
// to be called with scene objects that are in a scene (e.g. in the case of hg asset mapping and
|
||||
// inventory transfer. There needs to be a way for a module to register a method without assuming a
|
||||
// Scene.EventManager is present.
|
||||
// part.ParentGroup.Scene.EventManager.TriggerGatherUuids(part, assetUuids);
|
||||
|
||||
|
||||
// still needed to retrieve textures used as materials for any parts containing legacy materials stored in DynAttrs
|
||||
RecordMaterialsUuids(part);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat("[UUID GATHERER]: Failed to get part - {0}", e);
|
||||
m_log.DebugFormat(
|
||||
"[UUID GATHERER]: Texture entry length for prim was {0} (min is 46)",
|
||||
part.Shape.TextureEntry.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Collect all the asset uuids found in one face of a Texture Entry.
|
||||
/// </summary>
|
||||
|
@ -940,7 +959,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_gatheredAssetUuids[texture.TextureID] = (sbyte)AssetType.Texture;
|
||||
|
||||
if (texture.MaterialID != UUID.Zero)
|
||||
AddAssetUuidToInspect(texture.MaterialID);
|
||||
AddForInspection(texture.MaterialID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -948,7 +967,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// stored in legacy format in part.DynAttrs
|
||||
/// </summary>
|
||||
/// <param name="part"></param>
|
||||
public void RecordMaterialsUuids(SceneObjectPart part)
|
||||
private void RecordMaterialsUuids(SceneObjectPart part)
|
||||
{
|
||||
// scan thru the dynAttrs map of this part for any textures used as materials
|
||||
OSD osdMaterials = null;
|
||||
|
@ -1039,7 +1058,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
UUID uuid = new UUID(uuidMatch.Value);
|
||||
// m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid);
|
||||
|
||||
AddAssetUuidToInspect(uuid);
|
||||
AddForInspection(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1074,14 +1093,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa))
|
||||
{
|
||||
foreach (SceneObjectGroup sog in coa.Objects)
|
||||
RecordAssetUuids(sog);
|
||||
AddForInspection(sog);
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml);
|
||||
|
||||
if (null != sog)
|
||||
RecordAssetUuids(sog);
|
||||
AddForInspection(sog);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1147,8 +1166,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
protected string m_assetServerURL;
|
||||
|
||||
public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL)
|
||||
: base(assetService)
|
||||
public IteratingHGUuidGatherer(IAssetService assetService, string assetServerURL, IDictionary<UUID, sbyte> collector)
|
||||
: base(assetService, collector)
|
||||
{
|
||||
m_assetServerURL = assetServerURL;
|
||||
if (!m_assetServerURL.EndsWith("/") && !m_assetServerURL.EndsWith("="))
|
||||
|
|
|
@ -441,13 +441,20 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
|||
/// <summary>
|
||||
/// Check if the caller has permission to manipulate the given NPC.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A caller has permission if
|
||||
/// * The caller UUID given is UUID.Zero.
|
||||
/// * The avatar is unowned (owner is UUID.Zero).
|
||||
/// * The avatar is owned and the owner and callerID match.
|
||||
/// * The avatar is owned and the callerID matches its agentID.
|
||||
/// </remarks>
|
||||
/// <param name="av"></param>
|
||||
/// <param name="callerID"></param>
|
||||
/// <returns>true if they do, false if they don't.</returns>
|
||||
private bool CheckPermissions(NPCAvatar av, UUID callerID)
|
||||
{
|
||||
return callerID == UUID.Zero || av.OwnerID == UUID.Zero ||
|
||||
av.OwnerID == callerID;
|
||||
av.OwnerID == callerID || av.AgentId == callerID;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
|
|||
void SetVars(Dictionary<string, object> vars);
|
||||
DetectParams GetDetectParams(int idx);
|
||||
UUID GetDetectID(int idx);
|
||||
void SaveState(string assembly);
|
||||
void SaveState();
|
||||
void DestroyScriptInstance();
|
||||
|
||||
IScriptApi GetApi(string name);
|
||||
|
|
|
@ -663,9 +663,8 @@ namespace SecondLife
|
|||
|
||||
try
|
||||
{
|
||||
FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read);
|
||||
fs.Read(data, 0, data.Length);
|
||||
fs.Close();
|
||||
using (FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read))
|
||||
fs.Read(data, 0, data.Length);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
@ -680,9 +679,8 @@ namespace SecondLife
|
|||
|
||||
Byte[] buf = Encoding.ASCII.GetBytes(filetext);
|
||||
|
||||
FileStream sfs = File.Create(assembly + ".text");
|
||||
sfs.Write(buf, 0, buf.Length);
|
||||
sfs.Close();
|
||||
using (FileStream sfs = File.Create(assembly + ".text"))
|
||||
sfs.Write(buf, 0, buf.Length);
|
||||
|
||||
return assembly;
|
||||
}
|
||||
|
@ -775,7 +773,6 @@ namespace SecondLife
|
|||
return message;
|
||||
}
|
||||
|
||||
|
||||
private static void WriteMapFile(string filename, Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap)
|
||||
{
|
||||
string mapstring = String.Empty;
|
||||
|
@ -787,39 +784,41 @@ namespace SecondLife
|
|||
}
|
||||
|
||||
Byte[] mapbytes = Encoding.ASCII.GetBytes(mapstring);
|
||||
FileStream mfs = File.Create(filename);
|
||||
mfs.Write(mapbytes, 0, mapbytes.Length);
|
||||
mfs.Close();
|
||||
}
|
||||
|
||||
using (FileStream mfs = File.Create(filename))
|
||||
mfs.Write(mapbytes, 0, mapbytes.Length);
|
||||
}
|
||||
|
||||
private static Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> ReadMapFile(string filename)
|
||||
{
|
||||
Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap;
|
||||
try
|
||||
{
|
||||
StreamReader r = File.OpenText(filename);
|
||||
linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
|
||||
|
||||
string line;
|
||||
while ((line = r.ReadLine()) != null)
|
||||
using (StreamReader r = File.OpenText(filename))
|
||||
{
|
||||
String[] parts = line.Split(new Char[] { ',' });
|
||||
int kk = System.Convert.ToInt32(parts[0]);
|
||||
int kv = System.Convert.ToInt32(parts[1]);
|
||||
int vk = System.Convert.ToInt32(parts[2]);
|
||||
int vv = System.Convert.ToInt32(parts[3]);
|
||||
linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
|
||||
|
||||
KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv);
|
||||
KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv);
|
||||
string line;
|
||||
while ((line = r.ReadLine()) != null)
|
||||
{
|
||||
String[] parts = line.Split(new Char[] { ',' });
|
||||
int kk = System.Convert.ToInt32(parts[0]);
|
||||
int kv = System.Convert.ToInt32(parts[1]);
|
||||
int vk = System.Convert.ToInt32(parts[2]);
|
||||
int vv = System.Convert.ToInt32(parts[3]);
|
||||
|
||||
linemap[k] = v;
|
||||
KeyValuePair<int, int> k = new KeyValuePair<int, int>(kk, kv);
|
||||
KeyValuePair<int, int> v = new KeyValuePair<int, int>(vk, vv);
|
||||
|
||||
linemap[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
linemap = new Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>();
|
||||
}
|
||||
|
||||
return linemap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,7 +71,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
private bool m_TimerQueued;
|
||||
private DateTime m_EventStart;
|
||||
private bool m_InEvent;
|
||||
private string m_Assembly;
|
||||
private string m_assemblyPath;
|
||||
private string m_dataPath;
|
||||
private string m_CurrentEvent = String.Empty;
|
||||
private bool m_InSelfDelete;
|
||||
private int m_MaxScriptQueue;
|
||||
|
@ -244,12 +245,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
/// </summary>
|
||||
/// <param name='dom'></param>
|
||||
/// <param name='assembly'></param>
|
||||
/// <param name='dataPath'>
|
||||
/// Path for all script associated data (state, etc.). In a multi-region set up
|
||||
/// with all scripts loading into the same AppDomain this may not be the same place as the DLL itself.
|
||||
/// </param>
|
||||
/// <param name='stateSource'></param>
|
||||
/// <returns>false if load failed, true if suceeded</returns>
|
||||
public bool Load(AppDomain dom, Assembly scriptAssembly, StateSource stateSource)
|
||||
public bool Load(AppDomain dom, Assembly scriptAssembly, string dataPath, StateSource stateSource)
|
||||
{
|
||||
//m_Assembly = scriptAssembly.CodeBase;
|
||||
m_Assembly = scriptAssembly.Location;
|
||||
m_assemblyPath = scriptAssembly.Location;
|
||||
m_dataPath = dataPath;
|
||||
m_stateSource = stateSource;
|
||||
|
||||
try
|
||||
|
@ -270,14 +275,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
constructorParams = null;
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCRIP
|
||||
// scriptType.FullName, m_Assembly, Engine.World.Name);
|
||||
|
||||
if (dom != System.AppDomain.CurrentDomain)
|
||||
m_Script
|
||||
= (IScript)dom.CreateInstanceAndUnwrap(
|
||||
Path.GetFileNameWithoutExtension(m_Assembly),
|
||||
Path.GetFileNameWithoutExtension(m_assemblyPath),
|
||||
scriptType.FullName,
|
||||
false,
|
||||
BindingFlags.Default,
|
||||
|
@ -305,7 +306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
{
|
||||
m_log.ErrorFormat(
|
||||
"[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}",
|
||||
ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, m_Assembly, e.Message, e.StackTrace);
|
||||
ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, scriptAssembly.Location, e.Message, e.StackTrace);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -340,10 +341,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
|
||||
m_SaveState = true;
|
||||
|
||||
string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly), ItemID.ToString() + ".state");
|
||||
string savedState = Path.Combine(m_dataPath, ItemID.ToString() + ".state");
|
||||
|
||||
if (File.Exists(savedState))
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[SCRIPT INSTANCE]: Found state for script {0} for {1} ({2}) at {3} in {4}",
|
||||
// ItemID, savedState, Part.Name, Part.ParentGroup.Name, Part.ParentGroup.Scene.Name);
|
||||
|
||||
string xml = String.Empty;
|
||||
|
||||
try
|
||||
|
@ -385,12 +390,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
m_startedFromSavedState = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.",
|
||||
ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// m_log.WarnFormat(
|
||||
// "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.",
|
||||
// ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState);
|
||||
// }
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -401,11 +406,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
}
|
||||
// else
|
||||
// {
|
||||
// ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID);
|
||||
|
||||
// if (presence != null && (!postOnRez))
|
||||
// presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCRIPT INSTANCE]: Did not find state for script {0} for {1} ({2}) at {3} in {4}",
|
||||
// ItemID, savedState, Part.Name, Part.ParentGroup.Name, Part.ParentGroup.Scene.Name);
|
||||
// }
|
||||
|
||||
return true;
|
||||
|
@ -498,8 +501,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
|
||||
public void RemoveState()
|
||||
{
|
||||
string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly),
|
||||
ItemID.ToString() + ".state");
|
||||
string savedState = Path.Combine(m_dataPath, ItemID.ToString() + ".state");
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[SCRIPT INSTANCE]: Deleting state {0} for script {1} (id {2}) in part {3} (id {4}) in object {5} in {6}.",
|
||||
// savedState, ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -822,8 +828,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
if (Engine.World.PipeEventsForScript(LocalID) ||
|
||||
data.EventName == "control") // Don't freeze avies!
|
||||
{
|
||||
// m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
|
||||
// PrimName, ScriptName, data.EventName, State);
|
||||
// m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
|
||||
// PrimName, ScriptName, data.EventName, State);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -849,7 +855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
// This will be the very first event we deliver
|
||||
// (state_entry) in default state
|
||||
//
|
||||
SaveState(m_Assembly);
|
||||
SaveState();
|
||||
|
||||
m_SaveState = false;
|
||||
}
|
||||
|
@ -1043,7 +1049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
return m_DetectParams[idx].Key;
|
||||
}
|
||||
|
||||
public void SaveState(string assembly)
|
||||
public void SaveState()
|
||||
{
|
||||
// If we're currently in an event, just tell it to save upon return
|
||||
//
|
||||
|
@ -1065,10 +1071,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
{
|
||||
try
|
||||
{
|
||||
FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), ItemID.ToString() + ".state"));
|
||||
Byte[] buf = Util.UTF8NoBomEncoding.GetBytes(xml);
|
||||
fs.Write(buf, 0, buf.Length);
|
||||
fs.Close();
|
||||
using (FileStream fs = File.Create(Path.Combine(m_dataPath, ItemID.ToString() + ".state")))
|
||||
{
|
||||
Byte[] buf = Util.UTF8NoBomEncoding.GetBytes(xml);
|
||||
fs.Write(buf, 0, buf.Length);
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
|
@ -1148,7 +1155,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
|
||||
public string GetAssemblyName()
|
||||
{
|
||||
return m_Assembly;
|
||||
return m_assemblyPath;
|
||||
}
|
||||
|
||||
public string GetXMLState()
|
||||
|
|
|
@ -40,10 +40,10 @@ using OpenSim.Tests.Common;
|
|||
namespace OpenSim.Region.ScriptEngine.XEngine.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// XEngine tests.
|
||||
/// Basic XEngine tests.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class XEngineTest : OpenSimTestCase
|
||||
public class XEngineBasicTests : OpenSimTestCase
|
||||
{
|
||||
private TestScene m_scene;
|
||||
private XEngine m_xEngine;
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Framework.EntityTransfer;
|
||||
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.ScriptEngine.Shared;
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
namespace OpenSim.Region.ScriptEngine.XEngine.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// XEngine tests connected with crossing scripts between regions.
|
||||
/// </summary>
|
||||
[TestFixture]
|
||||
public class XEngineCrossingTests : OpenSimTestCase
|
||||
{
|
||||
[TestFixtureSetUp]
|
||||
public void FixtureInit()
|
||||
{
|
||||
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
|
||||
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
|
||||
}
|
||||
|
||||
[TestFixtureTearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
|
||||
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
|
||||
// tests really shouldn't).
|
||||
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test script state preservation when a script crosses between regions on the same simulator.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestScriptCrossOnSameSimulator()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
UUID userId = TestHelpers.ParseTail(0x1);
|
||||
int sceneObjectIdTail = 0x2;
|
||||
|
||||
EntityTransferModule etmA = new EntityTransferModule();
|
||||
EntityTransferModule etmB = new EntityTransferModule();
|
||||
LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
|
||||
XEngine xEngineA = new XEngine();
|
||||
XEngine xEngineB = new XEngine();
|
||||
xEngineA.DebugLevel = 1;
|
||||
xEngineB.DebugLevel = 1;
|
||||
|
||||
IConfigSource configSource = new IniConfigSource();
|
||||
|
||||
IConfig startupConfig = configSource.AddConfig("Startup");
|
||||
startupConfig.Set("DefaultScriptEngine", "XEngine");
|
||||
|
||||
IConfig xEngineConfig = configSource.AddConfig("XEngine");
|
||||
xEngineConfig.Set("Enabled", "true");
|
||||
xEngineConfig.Set("StartDelay", "0");
|
||||
|
||||
// These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call
|
||||
// to AssemblyResolver.OnAssemblyResolve fails.
|
||||
xEngineConfig.Set("AppDomainLoading", "false");
|
||||
|
||||
IConfig modulesConfig = configSource.AddConfig("Modules");
|
||||
modulesConfig.Set("EntityTransferModule", etmA.Name);
|
||||
modulesConfig.Set("SimulationServices", lscm.Name);
|
||||
|
||||
SceneHelpers sh = new SceneHelpers();
|
||||
TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000, configSource);
|
||||
TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999, configSource);
|
||||
|
||||
SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, configSource, lscm);
|
||||
SceneHelpers.SetupSceneModules(sceneA, configSource, etmA, xEngineA);
|
||||
SceneHelpers.SetupSceneModules(sceneB, configSource, etmB, xEngineB);
|
||||
sceneA.StartScripts();
|
||||
sceneB.StartScripts();
|
||||
|
||||
SceneObjectGroup soSceneA = SceneHelpers.AddSceneObject(sceneA, 1, userId, "so1-", sceneObjectIdTail);
|
||||
soSceneA.AbsolutePosition = new Vector3(128, 10, 20);
|
||||
|
||||
// CREATE SCRIPT TODO
|
||||
InventoryItemBase scriptItemSceneA = new InventoryItemBase();
|
||||
// itemTemplate.ID = itemId;
|
||||
scriptItemSceneA.Name = "script1";
|
||||
scriptItemSceneA.Folder = soSceneA.UUID;
|
||||
scriptItemSceneA.InvType = (int)InventoryType.LSL;
|
||||
|
||||
AutoResetEvent chatEvent = new AutoResetEvent(false);
|
||||
OSChatMessage messageReceived = null;
|
||||
sceneA.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEvent.Set(); };
|
||||
|
||||
sceneA.RezNewScript(userId, scriptItemSceneA,
|
||||
@"integer c = 0;
|
||||
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
llSay(0, ""Script running"");
|
||||
}
|
||||
|
||||
changed(integer change)
|
||||
{
|
||||
llSay(0, ""Changed"");
|
||||
}
|
||||
|
||||
touch_start(integer n)
|
||||
{
|
||||
c = c + 1;
|
||||
llSay(0, (string)c);
|
||||
}
|
||||
}");
|
||||
|
||||
chatEvent.WaitOne(60000);
|
||||
|
||||
Assert.That(messageReceived, Is.Not.Null, "No chat message received.");
|
||||
Assert.That(messageReceived.Message, Is.EqualTo("Script running"));
|
||||
|
||||
{
|
||||
// XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead.
|
||||
DetectParams[] det = new DetectParams[1];
|
||||
det[0] = new DetectParams();
|
||||
det[0].Key = userId;
|
||||
det[0].Populate(sceneA);
|
||||
|
||||
EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det);
|
||||
|
||||
xEngineA.PostObjectEvent(soSceneA.LocalId, ep);
|
||||
chatEvent.WaitOne(60000);
|
||||
|
||||
Assert.That(messageReceived.Message, Is.EqualTo("1"));
|
||||
}
|
||||
|
||||
sceneB.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEvent.Set(); };
|
||||
|
||||
// Cross with a negative value
|
||||
soSceneA.AbsolutePosition = new Vector3(128, -10, 20);
|
||||
|
||||
chatEvent.WaitOne(60000);
|
||||
Assert.That(messageReceived.Message, Is.EqualTo("Changed"));
|
||||
|
||||
// TEST sending event to moved prim and output
|
||||
{
|
||||
SceneObjectGroup soSceneB = sceneB.GetSceneObjectGroup(soSceneA.Name);
|
||||
TaskInventoryItem scriptItemSceneB = soSceneB.RootPart.Inventory.GetInventoryItem(scriptItemSceneA.Name);
|
||||
|
||||
// XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead.
|
||||
DetectParams[] det = new DetectParams[1];
|
||||
det[0] = new DetectParams();
|
||||
det[0].Key = userId;
|
||||
det[0].Populate(sceneB);
|
||||
|
||||
EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det);
|
||||
|
||||
xEngineB.PostObjectEvent(soSceneB.LocalId, ep);
|
||||
chatEvent.WaitOne(60000);
|
||||
|
||||
Assert.That(messageReceived.Message, Is.EqualTo("2"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,7 +70,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
/// <remarks>
|
||||
/// If DebugLevel >= 1, then we log every time that a script is started.
|
||||
/// </remarks>
|
||||
// public int DebugLevel { get; set; }
|
||||
public int DebugLevel { get; set; }
|
||||
|
||||
private SmartThreadPool m_ThreadPool;
|
||||
private int m_MaxScriptQueue;
|
||||
|
@ -101,7 +101,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
private bool m_InitialStartup = true;
|
||||
private int m_ScriptFailCount; // Number of script fails since compile queue was last empty
|
||||
private string m_ScriptErrorMessage;
|
||||
private Dictionary<string, string> m_uniqueScripts = new Dictionary<string, string>();
|
||||
private bool m_AppDomainLoading;
|
||||
private Dictionary<UUID,ArrayList> m_ScriptErrors =
|
||||
new Dictionary<UUID,ArrayList>();
|
||||
|
@ -403,12 +402,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
+ "Level >= 2, log event invocations.\n",
|
||||
HandleDebugScriptLogCommand);
|
||||
|
||||
// MainConsole.Instance.Commands.AddCommand(
|
||||
// "Debug", false, "debug xengine", "debug xengine [<level>]",
|
||||
// "Turn on detailed xengine debugging.",
|
||||
// "If level <= 0, then no extra logging is done.\n"
|
||||
// + "If level >= 1, then we log every time that a script is started.",
|
||||
// HandleDebugLevelCommand);
|
||||
MainConsole.Instance.Commands.AddCommand(
|
||||
"Debug", false, "debug xengine log", "debug xengine log [<level>]",
|
||||
"Turn on detailed xengine debugging.",
|
||||
"If level <= 0, then no extra logging is done.\n"
|
||||
+ "If level >= 1, then we log every time that a script is started.",
|
||||
HandleDebugLevelCommand);
|
||||
}
|
||||
|
||||
private void HandleDebugScriptLogCommand(string module, string[] args)
|
||||
|
@ -451,26 +450,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
/// </summary>
|
||||
/// <param name="module"></param>
|
||||
/// <param name="args"></param>
|
||||
// private void HandleDebugLevelCommand(string module, string[] args)
|
||||
// {
|
||||
// if (args.Length == 3)
|
||||
// {
|
||||
// int newDebug;
|
||||
// if (int.TryParse(args[2], out newDebug))
|
||||
// {
|
||||
// DebugLevel = newDebug;
|
||||
// MainConsole.Instance.OutputFormat("Debug level set to {0}", newDebug);
|
||||
// }
|
||||
// }
|
||||
// else if (args.Length == 2)
|
||||
// {
|
||||
// MainConsole.Instance.OutputFormat("Current debug level is {0}", DebugLevel);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// MainConsole.Instance.Output("Usage: debug xengine 0..1");
|
||||
// }
|
||||
// }
|
||||
private void HandleDebugLevelCommand(string module, string[] args)
|
||||
{
|
||||
if (args.Length <= 4)
|
||||
{
|
||||
int newDebug;
|
||||
if (ConsoleUtil.TryParseConsoleNaturalInt(MainConsole.Instance, args[3], out newDebug))
|
||||
{
|
||||
DebugLevel = newDebug;
|
||||
MainConsole.Instance.OutputFormat("Debug level set to {0} in XEngine for region {1}", newDebug, m_Scene.Name);
|
||||
}
|
||||
}
|
||||
else if (args.Length == 3)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("Current debug level is {0}", DebugLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: debug xengine log <level>");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse the raw item id into a script instance from the command params if it's present.
|
||||
|
@ -570,7 +569,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
}
|
||||
|
||||
sb.AppendFormat("Scripts loaded : {0}\n", scriptsLoaded);
|
||||
sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count);
|
||||
sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count);
|
||||
sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads);
|
||||
sb.AppendFormat("Min threads : {0}\n", m_ThreadPool.MinThreads);
|
||||
|
@ -716,22 +714,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
{
|
||||
// Force a final state save
|
||||
//
|
||||
if (m_Assemblies.ContainsKey(instance.AssetID))
|
||||
try
|
||||
{
|
||||
string assembly = m_Assemblies[instance.AssetID];
|
||||
|
||||
try
|
||||
{
|
||||
instance.SaveState(assembly);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
|
||||
instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
|
||||
, e);
|
||||
}
|
||||
instance.SaveState();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
|
||||
instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
|
||||
, e);
|
||||
}
|
||||
|
||||
// Clear the event queue and abort the instance thread
|
||||
|
@ -840,18 +833,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
|
||||
foreach (IScriptInstance i in instances)
|
||||
{
|
||||
string assembly = String.Empty;
|
||||
|
||||
lock (m_Scripts)
|
||||
{
|
||||
if (!m_Assemblies.ContainsKey(i.AssetID))
|
||||
continue;
|
||||
assembly = m_Assemblies[i.AssetID];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
i.SaveState(assembly);
|
||||
i.SaveState();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -1001,12 +985,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
if (engine != ScriptEngineName)
|
||||
return;
|
||||
|
||||
// If we've seen this exact script text before, use that reference instead
|
||||
if (m_uniqueScripts.ContainsKey(script))
|
||||
script = m_uniqueScripts[script];
|
||||
else
|
||||
m_uniqueScripts[script] = script;
|
||||
|
||||
Object[] parms = new Object[]{localID, itemID, script, startParam, postOnRez, (StateSource)stateSource};
|
||||
|
||||
if (stateSource == (int)StateSource.ScriptedRez)
|
||||
|
@ -1020,11 +998,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
}
|
||||
else
|
||||
{
|
||||
m_CompileQueue.Enqueue(parms);
|
||||
lock (m_CompileDict)
|
||||
{
|
||||
m_CompileDict[itemID] = 0;
|
||||
}
|
||||
|
||||
// This must occur after the m_CompileDict so that an existing compile thread cannot hit the check
|
||||
// in DoOnRezScript() before m_CompileDict has been updated.
|
||||
m_CompileQueue.Enqueue(parms);
|
||||
|
||||
// m_log.DebugFormat("[XEngine]: Added script {0} to compile queue", itemID);
|
||||
|
||||
|
@ -1100,7 +1079,15 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
// due to a race condition
|
||||
//
|
||||
lock (m_CompileQueue)
|
||||
{
|
||||
m_CurrentCompile = null;
|
||||
|
||||
// This is to avoid a situation where the m_CompileQueue while loop above could complete but
|
||||
// OnRezScript() place a new script on the queue and check m_CurrentCompile = null before we hit
|
||||
// this section.
|
||||
if (m_CompileQueue.Count > 0)
|
||||
m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -1148,10 +1135,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
return false;
|
||||
}
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
|
||||
part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
|
||||
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
if (DebugLevel > 0)
|
||||
m_log.DebugFormat(
|
||||
"[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
|
||||
part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
|
||||
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
|
||||
|
||||
UUID assetID = item.AssetID;
|
||||
|
||||
|
@ -1171,6 +1159,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
{
|
||||
m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assemblyPath, out linemap);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[XENGINE]: Found assembly path {0} onrez {1} in {2}",
|
||||
// assemblyPath, item.ItemID, World.Name);
|
||||
|
||||
if (!m_AddingAssemblies.ContainsKey(assemblyPath)) {
|
||||
m_AddingAssemblies[assemblyPath] = 1;
|
||||
} else {
|
||||
|
@ -1348,14 +1340,24 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
// simulator session if the script halt strategy has been changed. Instead, we'll continue with
|
||||
// the existing DLL and the new one will be used in the next simulator session.
|
||||
if (recompile)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[XEngine]: Recompiling script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5} to switch it to {6} termination. Will be active on next restart.",
|
||||
part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
|
||||
part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.Name,
|
||||
m_coopTermination ? "co-op" : "abort");
|
||||
|
||||
m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, true, out assemblyPath, out linemap);
|
||||
}
|
||||
|
||||
instance = new ScriptInstance(this, part,
|
||||
item,
|
||||
startParam, postOnRez,
|
||||
m_MaxScriptQueue);
|
||||
|
||||
if (!instance.Load(m_AppDomains[appDomain], scriptAssembly, stateSource))
|
||||
if (!instance.Load(
|
||||
m_AppDomains[appDomain], scriptAssembly,
|
||||
Path.Combine(ScriptEnginePath, World.RegionInfo.RegionID.ToString()), stateSource))
|
||||
return false;
|
||||
|
||||
// if (DebugLevel >= 1)
|
||||
|
@ -1586,7 +1588,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
|
||||
IScriptInstance instance = (ScriptInstance) parms;
|
||||
|
||||
//m_log.DebugFormat("[XEngine]: Processing event for {0}", instance);
|
||||
// m_log.DebugFormat("[XEngine]: Processing event for {0}", instance);
|
||||
|
||||
return instance.EventProcessor();
|
||||
}
|
||||
|
@ -2155,7 +2157,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
catch (IOException ex)
|
||||
{
|
||||
// if there already exists a file at that location, it may be locked.
|
||||
m_log.ErrorFormat("[XEngine]: Linemap file {0} already exists! {1}", mappath, ex.Message);
|
||||
m_log.Error(
|
||||
string.Format("[XEngine]: Linemap file {0} could not be written. Exception ", mappath), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2181,6 +2184,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
|||
m_log.ErrorFormat("[XEngine]: Error whilst writing state file {0}, {1}", statepath, ex.Message);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[XEngine]: Wrote state for script item with ID {0} at {1} in {2}", itemID, statepath, m_Scene.Name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -107,11 +107,9 @@ namespace OpenSim.Server.Handlers.BakedTextures
|
|||
File.Delete(diskFile);
|
||||
|
||||
byte[] data = utf8encoding.GetBytes(sdata);
|
||||
FileStream fs = File.Create(diskFile);
|
||||
|
||||
fs.Write(data, 0, data.Length);
|
||||
|
||||
fs.Close();
|
||||
using (FileStream fs = File.Create(diskFile))
|
||||
fs.Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
private void HandleDeleteBakes(string module, string[] args)
|
||||
|
|
|
@ -317,8 +317,10 @@ namespace OpenSim.Services.GridService
|
|||
m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
|
||||
}
|
||||
|
||||
m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3} with flags {4}",
|
||||
regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY,
|
||||
m_log.DebugFormat
|
||||
("[GRID SERVICE]: Region {0} ({1}, {2}x{3}) registered at {4},{5} with flags {6}",
|
||||
regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionSizeX, regionInfos.RegionSizeY,
|
||||
regionInfos.RegionCoordX, regionInfos.RegionCoordY,
|
||||
(OpenSim.Framework.RegionFlags)flags);
|
||||
|
||||
return String.Empty;
|
||||
|
|
|
@ -98,7 +98,12 @@ namespace OpenSim.Services.UserAccountService
|
|||
MainConsole.Instance.Commands.AddCommand("Users", false,
|
||||
"reset user password",
|
||||
"reset user password [<first> [<last> [<password>]]]",
|
||||
"Reset a user password", HandleResetUserPassword);
|
||||
"Reset a user password", HandleResetUserPassword);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("Users", false,
|
||||
"reset user email",
|
||||
"reset user email [<first> [<last> [<email>]]]",
|
||||
"Reset a user email address", HandleResetUserEmail);
|
||||
|
||||
MainConsole.Instance.Commands.AddCommand("Users", false,
|
||||
"set user level",
|
||||
|
@ -420,6 +425,43 @@ namespace OpenSim.Services.UserAccountService
|
|||
MainConsole.Instance.OutputFormat("Password reset for user {0} {1}", firstName, lastName);
|
||||
}
|
||||
|
||||
protected void HandleResetUserEmail(string module, string[] cmdparams)
|
||||
{
|
||||
string firstName;
|
||||
string lastName;
|
||||
string newEmail;
|
||||
|
||||
if (cmdparams.Length < 4)
|
||||
firstName = MainConsole.Instance.CmdPrompt("First name");
|
||||
else firstName = cmdparams[3];
|
||||
|
||||
if (cmdparams.Length < 5)
|
||||
lastName = MainConsole.Instance.CmdPrompt("Last name");
|
||||
else lastName = cmdparams[4];
|
||||
|
||||
if (cmdparams.Length < 6)
|
||||
newEmail = MainConsole.Instance.PasswdPrompt("New Email");
|
||||
else newEmail = cmdparams[5];
|
||||
|
||||
UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
|
||||
if (account == null)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName);
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
|
||||
account.Email = newEmail;
|
||||
|
||||
success = StoreUserAccount(account);
|
||||
if (!success)
|
||||
MainConsole.Instance.OutputFormat("Unable to set Email for account {0} {1}.", firstName, lastName);
|
||||
else
|
||||
MainConsole.Instance.OutputFormat("User Email set for user {0} {1} to {2}", firstName, lastName, account.Email);
|
||||
}
|
||||
|
||||
|
||||
protected void HandleSetUserLevel(string module, string[] cmdparams)
|
||||
{
|
||||
string firstName;
|
||||
|
|
Binary file not shown.
|
@ -57,11 +57,6 @@
|
|||
<appender-ref ref="LogFileAppender" />
|
||||
</root>
|
||||
|
||||
<!-- Independently control logging level for XEngine -->
|
||||
<logger name="OpenSim.Region.ScriptEngine.XEngine">
|
||||
<level value="INFO"/>
|
||||
</logger>
|
||||
|
||||
<!-- Independently control logging level for per region module loading -->
|
||||
<logger name="OpenSim.ApplicationPlugins.RegionModulesController.RegionModulesControllerPlugin">
|
||||
<level value="INFO"/>
|
||||
|
|
|
@ -208,6 +208,10 @@
|
|||
[InventoryService]
|
||||
LocalServiceModule = "OpenSim.Services.InventoryService.dll:XInventoryService"
|
||||
|
||||
; Will calls to purge folders (empty trash) and immediately delete/update items or folders (not move to trash first) succeed?
|
||||
; If this is set to false then some other arrangement must be made to perform these operations if necessary.
|
||||
AllowDelete = true
|
||||
|
||||
|
||||
; * This is the new style grid service.
|
||||
; * "Realm" is the table that is used for user lookup.
|
||||
|
|
|
@ -179,6 +179,10 @@
|
|||
[InventoryService]
|
||||
LocalServiceModule = "OpenSim.Services.InventoryService.dll:XInventoryService"
|
||||
|
||||
; Will calls to purge folders (empty trash) and immediately delete/update items or folders (not move to trash first) succeed?
|
||||
; If this is set to false then some other arrangement must be made to perform these operations if necessary.
|
||||
AllowDelete = true
|
||||
|
||||
|
||||
; * This is the new style grid service.
|
||||
; * "Realm" is the table that is used for user lookup.
|
||||
|
|
|
@ -2926,7 +2926,6 @@
|
|||
<Reference name="Nini" path="../../../bin/"/>
|
||||
|
||||
<Reference name="OpenSim.Data.MySQL"/>
|
||||
<Reference name="OpenSim.Data.MSSQL"/>
|
||||
<Reference name="OpenSim.Data.SQLite"/>
|
||||
|
||||
<Reference name="MySql.Data" path="../../../bin/"/>
|
||||
|
|
Loading…
Reference in New Issue