Merge branch 'master' into careminster-presence-refactor

avinationmerge
root 2011-07-05 04:01:59 +01:00
commit 47cf9c8fe0
26 changed files with 766 additions and 315 deletions

View File

@ -2304,6 +2304,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
/// <description>UUID of the region</description></item>
/// <item><term>region_name</term>
/// <description>region name</description></item>
/// <item><term>merge</term>
/// <description>true if oar should be merged</description></item>
/// <item><term>skip-assets</term>
/// <description>true if assets should be skiped</description></item>
/// </list>
///
/// <code>region_uuid</code> takes precedence over
@ -2363,9 +2367,21 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
else throw new Exception("neither region_name nor region_uuid given");
bool mergeOar = false;
bool skipAssets = false;
if ((string)requestData["merge"] == "true")
{
mergeOar = true;
}
if ((string)requestData["skip-assets"] == "true")
{
skipAssets = true;
}
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
if (archiver != null)
archiver.DearchiveRegion(filename);
archiver.DearchiveRegion(filename, mergeOar, skipAssets, Guid.Empty);
else
throw new Exception("Archiver module not present for scene");
@ -2405,6 +2421,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController
/// <description>UUID of the region</description></item>
/// <item><term>region_name</term>
/// <description>region name</description></item>
/// <item><term>profile</term>
/// <description>profile url</description></item>
/// <item><term>noassets</term>
/// <description>true if no assets should be saved</description></item>
/// </list>
///
/// <code>region_uuid</code> takes precedence over
@ -2462,12 +2482,29 @@ namespace OpenSim.ApplicationPlugins.RemoteController
}
else throw new Exception("neither region_name nor region_uuid given");
Dictionary<string, object> options = new Dictionary<string, object>();
//if (requestData.Contains("version"))
//{
// options["version"] = (string)requestData["version"];
//}
if (requestData.Contains("profile"))
{
options["profile"] = (string)requestData["profile"];
}
if (requestData["noassets"] == "true")
{
options["noassets"] = (string)requestData["noassets"] ;
}
IRegionArchiverModule archiver = scene.RequestModuleInterface<IRegionArchiverModule>();
if (archiver != null)
{
scene.EventManager.OnOarFileSaved += RemoteAdminOarSaveCompleted;
archiver.ArchiveRegion(filename, new Dictionary<string, object>());
archiver.ArchiveRegion(filename, options);
lock (m_saveOarLock) Monitor.Wait(m_saveOarLock,5000);
scene.EventManager.OnOarFileSaved -= RemoteAdminOarSaveCompleted;
}

View File

@ -281,6 +281,7 @@ namespace OpenSim.Framework
return m_id;
}
set
{
UUID uuid = UUID.Zero;

View File

@ -741,7 +741,7 @@ namespace OpenSim.Framework
bool IsActive { get; set; }
/// <value>
/// Determines whether the client is logging out or not.
/// Determines whether the client is or has been removed from a given scene
/// </value>
bool IsLoggingOut { get; set; }

View File

@ -31,6 +31,7 @@ using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Timers;
using log4net;
@ -124,7 +125,6 @@ namespace OpenSim.Framework.Servers
m_logFileAppender = appender;
}
}
}
/// <summary>
@ -443,45 +443,68 @@ namespace OpenSim.Framework.Servers
{
string buildVersion = string.Empty;
// Add commit hash and date information if available
// The commit hash and date are stored in a file bin/.version
// This file can automatically created by a post
// commit script in the opensim git master repository or
// by issuing the follwoing command from the top level
// directory of the opensim repository
// git log -n 1 --pretty="format:%h: %ci" >bin/.version
// For the full git commit hash use %H instead of %h
//
// The subversion information is deprecated and will be removed at a later date
// Add subversion revision information if available
// Try file "svn_revision" in the current directory first, then the .svn info.
// This allows to make the revision available in simulators not running from the source tree.
// FIXME: Making an assumption about the directory we're currently in - we do this all over the place
// elsewhere as well
string gitDir = "../.git/";
string gitRefPointerPath = gitDir + "HEAD";
string svnRevisionFileName = "svn_revision";
string svnFileName = ".svn/entries";
string gitCommitFileName = ".version";
string manualVersionFileName = ".version";
string inputLine;
int strcmp;
if (File.Exists(gitCommitFileName))
if (File.Exists(manualVersionFileName))
{
StreamReader CommitFile = File.OpenText(gitCommitFileName);
buildVersion = CommitFile.ReadLine();
CommitFile.Close();
using (StreamReader CommitFile = File.OpenText(manualVersionFileName))
buildVersion = CommitFile.ReadLine();
m_version += buildVersion ?? "";
}
else if (File.Exists(gitRefPointerPath))
{
// m_log.DebugFormat("[OPENSIM]: Found {0}", gitRefPointerPath);
// Remove the else logic when subversion mirror is no longer used
string rawPointer = "";
using (StreamReader pointerFile = File.OpenText(gitRefPointerPath))
rawPointer = pointerFile.ReadLine();
// m_log.DebugFormat("[OPENSIM]: rawPointer [{0}]", rawPointer);
Match m = Regex.Match(rawPointer, "^ref: (.+)$");
if (m.Success)
{
// m_log.DebugFormat("[OPENSIM]: Matched [{0}]", m.Groups[1].Value);
string gitRef = m.Groups[1].Value;
string gitRefPath = gitDir + gitRef;
if (File.Exists(gitRefPath))
{
// m_log.DebugFormat("[OPENSIM]: Found gitRefPath [{0}]", gitRefPath);
using (StreamReader refFile = File.OpenText(gitRefPath))
{
string gitHash = refFile.ReadLine();
m_version += gitHash.Substring(0, 7);
}
}
}
}
else
{
// Remove the else logic when subversion mirror is no longer used
if (File.Exists(svnRevisionFileName))
{
StreamReader RevisionFile = File.OpenText(svnRevisionFileName);
buildVersion = RevisionFile.ReadLine();
buildVersion.Trim();
RevisionFile.Close();
}
if (string.IsNullOrEmpty(buildVersion) && File.Exists(svnFileName))

View File

@ -328,7 +328,7 @@ namespace OpenSim
config.Set("meshing", "Meshmerizer");
config.Set("physical_prim", true);
config.Set("see_into_this_sim_from_neighbor", true);
config.Set("serverside_object_permissions", false);
config.Set("serverside_object_permissions", true);
config.Set("storage_plugin", "OpenSim.Data.SQLite.dll");
config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3");
config.Set("storage_prim_inventories", true);

View File

@ -86,6 +86,8 @@ namespace Flotsam.RegionModules.AssetCache
private List<string> m_CurrentlyWriting = new List<string>();
#endif
private bool m_FileCacheEnabled = true;
private ExpiringCache<string, AssetBase> m_MemoryCache;
private bool m_MemoryCacheEnabled = false;
@ -146,6 +148,7 @@ namespace Flotsam.RegionModules.AssetCache
}
else
{
m_FileCacheEnabled = assetConfig.GetBoolean("FileCacheEnabled", m_FileCacheEnabled);
m_CacheDirectory = assetConfig.GetString("CacheDirectory", m_DefaultCacheDirectory);
m_MemoryCacheEnabled = assetConfig.GetBoolean("MemoryCacheEnabled", m_MemoryCacheEnabled);
@ -173,7 +176,7 @@ namespace Flotsam.RegionModules.AssetCache
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Cache Directory {0}", m_CacheDirectory);
if ((m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
if (m_FileCacheEnabled && (m_FileExpiration > TimeSpan.Zero) && (m_FileExpirationCleanupTimer > TimeSpan.Zero))
{
m_CacheCleanTimer = new System.Timers.Timer(m_FileExpirationCleanupTimer.TotalMilliseconds);
m_CacheCleanTimer.AutoReset = true;
@ -226,7 +229,6 @@ namespace Flotsam.RegionModules.AssetCache
if (m_AssetService == null)
{
m_AssetService = scene.RequestModuleInterface<IAssetService>();
}
}
}
@ -250,18 +252,15 @@ namespace Flotsam.RegionModules.AssetCache
private void UpdateMemoryCache(string key, AssetBase asset)
{
if (m_MemoryCacheEnabled)
m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
m_MemoryCache.AddOrUpdate(key, asset, m_MemoryExpiration);
}
public void Cache(AssetBase asset)
private void UpdateFileCache(string key, AssetBase asset)
{
// TODO: Spawn this off to some seperate thread to do the actual writing
if (asset != null)
{
UpdateMemoryCache(asset.ID, asset);
string filename = GetFileName(asset.ID);
string filename = GetFileName(key);
try
{
@ -319,78 +318,118 @@ namespace Flotsam.RegionModules.AssetCache
}
}
public void Cache(AssetBase asset)
{
// TODO: Spawn this off to some seperate thread to do the actual writing
if (asset != null)
{
//m_log.DebugFormat("[FLOTSAM ASSET CACHE]: Caching asset with id {0}", asset.ID);
if (m_MemoryCacheEnabled)
UpdateMemoryCache(asset.ID, asset);
if (m_FileCacheEnabled)
UpdateFileCache(asset.ID, asset);
}
}
/// <summary>
/// Try to get an asset from the in-memory cache.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private AssetBase GetFromMemoryCache(string id)
{
AssetBase asset = null;
if (m_MemoryCache.TryGetValue(id, out asset))
m_MemoryHits++;
return asset;
}
/// <summary>
/// Try to get an asset from the file cache.
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
private AssetBase GetFromFileCache(string id)
{
AssetBase asset = null;
string filename = GetFileName(id);
if (File.Exists(filename))
{
FileStream stream = null;
try
{
stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryFormatter bformatter = new BinaryFormatter();
asset = (AssetBase)bformatter.Deserialize(stream);
UpdateMemoryCache(id, asset);
m_DiskHits++;
}
catch (System.Runtime.Serialization.SerializationException e)
{
LogException(e);
// If there was a problem deserializing the asset, the asset may
// either be corrupted OR was serialized under an old format
// {different version of AssetBase} -- we should attempt to
// delete it and re-cache
File.Delete(filename);
}
catch (Exception e)
{
LogException(e);
}
finally
{
if (stream != null)
stream.Close();
}
}
#if WAIT_ON_INPROGRESS_REQUESTS
// Check if we're already downloading this asset. If so, try to wait for it to
// download.
if (m_WaitOnInprogressTimeout > 0)
{
m_RequestsForInprogress++;
ManualResetEvent waitEvent;
if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent))
{
waitEvent.WaitOne(m_WaitOnInprogressTimeout);
return Get(id);
}
}
#else
// Track how often we have the problem that an asset is requested while
// it is still being downloaded by a previous request.
if (m_CurrentlyWriting.Contains(filename))
{
m_RequestsForInprogress++;
}
#endif
return asset;
}
public AssetBase Get(string id)
{
m_Requests++;
AssetBase asset = null;
if (m_MemoryCacheEnabled && m_MemoryCache.TryGetValue(id, out asset))
{
m_MemoryHits++;
}
else
{
string filename = GetFileName(id);
if (File.Exists(filename))
{
FileStream stream = null;
try
{
stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryFormatter bformatter = new BinaryFormatter();
asset = (AssetBase)bformatter.Deserialize(stream);
UpdateMemoryCache(id, asset);
m_DiskHits++;
}
catch (System.Runtime.Serialization.SerializationException e)
{
LogException(e);
// If there was a problem deserializing the asset, the asset may
// either be corrupted OR was serialized under an old format
// {different version of AssetBase} -- we should attempt to
// delete it and re-cache
File.Delete(filename);
}
catch (Exception e)
{
LogException(e);
}
finally
{
if (stream != null)
stream.Close();
}
}
#if WAIT_ON_INPROGRESS_REQUESTS
// Check if we're already downloading this asset. If so, try to wait for it to
// download.
if (m_WaitOnInprogressTimeout > 0)
{
m_RequestsForInprogress++;
ManualResetEvent waitEvent;
if (m_CurrentlyWriting.TryGetValue(filename, out waitEvent))
{
waitEvent.WaitOne(m_WaitOnInprogressTimeout);
return Get(id);
}
}
#else
// Track how often we have the problem that an asset is requested while
// it is still being downloaded by a previous request.
if (m_CurrentlyWriting.Contains(filename))
{
m_RequestsForInprogress++;
}
#endif
}
if (m_MemoryCacheEnabled)
asset = GetFromMemoryCache(id);
else if (m_FileCacheEnabled)
asset = GetFromFileCache(id);
if (((m_LogLevel >= 1)) && (m_HitRateDisplay != 0) && (m_Requests % m_HitRateDisplay == 0))
{
@ -424,10 +463,13 @@ namespace Flotsam.RegionModules.AssetCache
try
{
string filename = GetFileName(id);
if (File.Exists(filename))
if (m_FileCacheEnabled)
{
File.Delete(filename);
string filename = GetFileName(id);
if (File.Exists(filename))
{
File.Delete(filename);
}
}
if (m_MemoryCacheEnabled)
@ -442,11 +484,14 @@ namespace Flotsam.RegionModules.AssetCache
public void Clear()
{
if (m_LogLevel >= 2)
m_log.Debug("[FLOTSAM ASSET CACHE]: Clearing Cache.");
m_log.Debug("[FLOTSAM ASSET CACHE]: Clearing caches.");
foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
if (m_FileCacheEnabled)
{
Directory.Delete(dir);
foreach (string dir in Directory.GetDirectories(m_CacheDirectory))
{
Directory.Delete(dir);
}
}
if (m_MemoryCacheEnabled)
@ -481,9 +526,9 @@ namespace Flotsam.RegionModules.AssetCache
/// removes empty tier directories.
/// </summary>
/// <param name="dir"></param>
/// <param name="purgeLine"></param>
private void CleanExpiredFiles(string dir, DateTime purgeLine)
{
foreach (string file in Directory.GetFiles(dir))
{
if (File.GetLastAccessTime(file) < purgeLine)
@ -721,18 +766,28 @@ namespace Flotsam.RegionModules.AssetCache
switch (cmd)
{
case "status":
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Memory Cache : {0} assets", m_MemoryCache.Count);
if (m_MemoryCacheEnabled)
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Memory Cache : {0} assets", m_MemoryCache.Count);
else
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Memory cache disabled");
int fileCount = GetFileCacheCount(m_CacheDirectory);
m_log.InfoFormat("[FLOTSAM ASSET CACHE] File Cache : {0} assets", fileCount);
foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac"))
if (m_FileCacheEnabled)
{
m_log.Info("[FLOTSAM ASSET CACHE] Deep Scans were performed on the following regions:");
int fileCount = GetFileCacheCount(m_CacheDirectory);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File Cache : {0} assets", fileCount);
string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac","");
DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s);
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Region: {0}, {1}", RegionID, RegionDeepScanTMStamp.ToString("MM/dd/yyyy hh:mm:ss"));
foreach (string s in Directory.GetFiles(m_CacheDirectory, "*.fac"))
{
m_log.Info("[FLOTSAM ASSET CACHE]: Deep Scans were performed on the following regions:");
string RegionID = s.Remove(0,s.IndexOf("_")).Replace(".fac","");
DateTime RegionDeepScanTMStamp = File.GetLastWriteTime(s);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Region: {0}, {1}", RegionID, RegionDeepScanTMStamp.ToString("MM/dd/yyyy hh:mm:ss"));
}
}
else
{
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File cache disabled");
}
break;
@ -740,7 +795,7 @@ namespace Flotsam.RegionModules.AssetCache
case "clear":
if (cmdparams.Length < 2)
{
m_log.Warn("[FLOTSAM ASSET CACHE] Usage is fcache clear [file] [memory]");
m_log.Warn("[FLOTSAM ASSET CACHE]: Usage is fcache clear [file] [memory]");
break;
}
@ -761,36 +816,48 @@ namespace Flotsam.RegionModules.AssetCache
if (clearMemory)
{
m_MemoryCache.Clear();
m_log.Info("[FLOTSAM ASSET CACHE] Memory cache cleared.");
if (m_MemoryCacheEnabled)
{
m_MemoryCache.Clear();
m_log.Info("[FLOTSAM ASSET CACHE]: Memory cache cleared.");
}
else
{
m_log.Info("[FLOTSAM ASSET CACHE]: Memory cache not enabled.");
}
}
if (clearFile)
{
ClearFileCache();
m_log.Info("[FLOTSAM ASSET CACHE] File cache cleared.");
if (m_FileCacheEnabled)
{
ClearFileCache();
m_log.Info("[FLOTSAM ASSET CACHE]: File cache cleared.");
}
else
{
m_log.Info("[FLOTSAM ASSET CACHE]: File cache not enabled.");
}
}
break;
case "assets":
m_log.Info("[FLOTSAM ASSET CACHE] Caching all assets, in all scenes.");
m_log.Info("[FLOTSAM ASSET CACHE]: Caching all assets, in all scenes.");
Util.FireAndForget(delegate {
int assetsCached = CacheScenes();
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Completed Scene Caching, {0} assets found.", assetsCached);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Completed Scene Caching, {0} assets found.", assetsCached);
});
break;
case "expire":
if (cmdparams.Length < 3)
{
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Invalid parameters for Expire, please specify a valid date & time", cmd);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Invalid parameters for Expire, please specify a valid date & time", cmd);
break;
}
@ -808,26 +875,28 @@ namespace Flotsam.RegionModules.AssetCache
if (!DateTime.TryParse(s_expirationDate, out expirationDate))
{
m_log.InfoFormat("[FLOTSAM ASSET CACHE] {0} is not a valid date & time", cmd);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: {0} is not a valid date & time", cmd);
break;
}
CleanExpiredFiles(m_CacheDirectory, expirationDate);
if (m_FileCacheEnabled)
CleanExpiredFiles(m_CacheDirectory, expirationDate);
else
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: File cache not active, not clearing.");
break;
default:
m_log.InfoFormat("[FLOTSAM ASSET CACHE] Unknown command {0}", cmd);
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: Unknown command {0}", cmd);
break;
}
}
else if (cmdparams.Length == 1)
{
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache status - Display cache status");
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache clearmem - Remove all assets cached in memory");
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache clearfile - Remove all assets cached on disk");
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache cachescenes - Attempt a deep cache of all assets in all scenes");
m_log.InfoFormat("[FLOTSAM ASSET CACHE] flotsamcache <datetime> - Purge assets older then the specified date & time");
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache status - Display cache status");
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache clearmem - Remove all assets cached in memory");
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache clearfile - Remove all assets cached on disk");
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache cachescenes - Attempt a deep cache of all assets in all scenes");
m_log.InfoFormat("[FLOTSAM ASSET CACHE]: fcache <datetime> - Purge assets older then the specified date & time");
}
}

View File

@ -0,0 +1,127 @@
/*
* 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.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using log4net.Config;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenMetaverse.Assets;
using Flotsam.RegionModules.AssetCache;
using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Scenes.Serialization;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.CoreModules.Asset.Tests
{
/// <summary>
/// At the moment we're only test the in-memory part of the FlotsamAssetCache. This is a considerable weakness.
/// </summary>
[TestFixture]
public class FlotsamAssetCacheTests
{
protected TestScene m_scene;
protected FlotsamAssetCache m_cache;
[SetUp]
public void SetUp()
{
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
config.Configs["Modules"].Set("AssetCaching", "FlotsamAssetCache");
config.AddConfig("AssetCache");
config.Configs["AssetCache"].Set("FileCacheEnabled", "false");
config.Configs["AssetCache"].Set("MemoryCacheEnabled", "true");
m_cache = new FlotsamAssetCache();
m_scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(m_scene, config, m_cache);
}
[Test]
public void TestCacheAsset()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
AssetBase asset = AssetHelpers.CreateAsset();
asset.ID = TestHelper.ParseTail(0x1).ToString();
// Check we don't get anything before the asset is put in the cache
AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString());
Assert.That(retrievedAsset, Is.Null);
m_cache.Store(asset);
// Check that asset is now in cache
retrievedAsset = m_cache.Get(asset.ID.ToString());
Assert.That(retrievedAsset, Is.Not.Null);
Assert.That(retrievedAsset.ID, Is.EqualTo(asset.ID));
}
[Test]
public void TestExpireAsset()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
AssetBase asset = AssetHelpers.CreateAsset();
asset.ID = TestHelper.ParseTail(0x2).ToString();
m_cache.Store(asset);
m_cache.Expire(asset.ID);
AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString());
Assert.That(retrievedAsset, Is.Null);
}
[Test]
public void TestClearCache()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
AssetBase asset = AssetHelpers.CreateAsset();
asset.ID = TestHelper.ParseTail(0x2).ToString();
m_cache.Store(asset);
m_cache.Clear();
AssetBase retrievedAsset = m_cache.Get(asset.ID.ToString());
Assert.That(retrievedAsset, Is.Null);
}
}
}

View File

@ -449,7 +449,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool IsBannedFromLand(UUID avatar)
{
if (m_scene.Permissions.IsAdministrator(avatar))
if (m_scene.Permissions.CanEditParcelProperties(avatar, this, 0))
return false;
if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar))
@ -463,7 +463,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (e.AgentID == avatar && e.Flags == AccessList.Ban)
return true;
return false;
}) != -1 && LandData.OwnerID != avatar)
}) != -1)
{
return true;
}
@ -473,7 +473,7 @@ namespace OpenSim.Region.CoreModules.World.Land
public bool IsRestrictedFromLand(UUID avatar)
{
if (m_scene.Permissions.IsAdministrator(avatar))
if (m_scene.Permissions.CanEditParcelProperties(avatar, this, 0))
return false;
if (m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar))
@ -487,7 +487,7 @@ namespace OpenSim.Region.CoreModules.World.Land
if (e.AgentID == avatar && e.Flags == AccessList.Access)
return true;
return false;
}) == -1 && LandData.OwnerID != avatar)
}) == -1)
{
if (!HasGroupAccess(avatar))
{

View File

@ -134,7 +134,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return;
m_allowGridGods = myConfig.GetBoolean("allow_grid_gods", false);
m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", false);
m_bypassPermissions = !myConfig.GetBoolean("serverside_object_permissions", true);
m_propagatePermissions = myConfig.GetBoolean("propagate_permissions", true);
m_RegionOwnerIsGod = myConfig.GetBoolean("region_owner_is_god", true);
m_RegionManagerIsGod = myConfig.GetBoolean("region_manager_is_god", false);

View File

@ -28,7 +28,7 @@
using OpenMetaverse;
using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.CoreModules.Avatar.NPC
namespace OpenSim.Region.Framework.Interfaces
{
public interface INPCModule
{

View File

@ -0,0 +1,156 @@
/*
* 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.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
namespace OpenSim.Region.Framework.Scenes
{
class FetchHolder
{
public IClientAPI Client { get; private set; }
public UUID ItemID { get; private set; }
public FetchHolder(IClientAPI client, UUID itemID)
{
Client = client;
ItemID = itemID;
}
}
/// <summary>
/// Send FetchInventoryReply information to clients asynchronously on a single thread rather than asynchronously via
/// multiple threads.
/// </summary>
/// <remarks>
/// If the main root inventory is right-clicked on a version 1 viewer for a user with a large inventory, a very
/// very large number of FetchInventory requests are sent to the simulator. Each is handled on a separate thread
/// by the IClientAPI, but the sheer number of requests overwhelms the number of threads available and ends up
/// freezing the inbound packet handling.
///
/// This class makes the first FetchInventory packet thread process the queue. If new requests come
/// in while it is processing, then the subsequent threads just add the requests and leave it to the original
/// thread to process them.
///
/// This might slow down outbound packets but these are limited by the IClientAPI outbound queues
/// anyway.
///
/// It might be possible to ignore FetchInventory requests altogether, particularly as they are redundant wrt to
/// FetchInventoryDescendents requests, but this would require more investigation.
/// </remarks>
public class AsyncInventorySender
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected Scene m_scene;
/// <summary>
/// Queues fetch requests
/// </summary>
Queue<FetchHolder> m_fetchHolder = new Queue<FetchHolder>();
/// <summary>
/// Signal whether a queue is currently being processed or not.
/// </summary>
protected volatile bool m_processing;
public AsyncInventorySender(Scene scene)
{
m_processing = false;
m_scene = scene;
}
/// <summary>
/// Handle a fetch inventory request from the client
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="ownerID"></param>
public void HandleFetchInventory(IClientAPI remoteClient, UUID itemID, UUID ownerID)
{
lock (m_fetchHolder)
{
// m_log.DebugFormat(
// "[ASYNC INVENTORY SENDER]: Putting request from {0} for {1} on queue", remoteClient.Name, itemID);
m_fetchHolder.Enqueue(new FetchHolder(remoteClient, itemID));
}
if (!m_processing)
{
m_processing = true;
ProcessQueue();
}
}
/// <summary>
/// Process the queue of fetches
/// </summary>
protected void ProcessQueue()
{
FetchHolder fh = null;
while (true)
{
lock (m_fetchHolder)
{
// m_log.DebugFormat("[ASYNC INVENTORY SENDER]: {0} items left to process", m_fetchHolder.Count);
if (m_fetchHolder.Count == 0)
{
m_processing = false;
return;
}
else
{
fh = m_fetchHolder.Dequeue();
}
}
if (fh.Client.IsLoggingOut)
continue;
// m_log.DebugFormat(
// "[ASYNC INVENTORY SENDER]: Handling request from {0} for {1} on queue", fh.Client.Name, fh.ItemID);
InventoryItemBase item = new InventoryItemBase(fh.ItemID, fh.Client.AgentId);
item = m_scene.InventoryService.GetItem(item);
if (item != null)
fh.Client.SendInventoryItemDetails(item.Owner, item);
// TODO: Possibly log any failure
}
}
}
}

View File

@ -51,6 +51,11 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
protected AsyncSceneObjectGroupDeleter m_asyncSceneObjectDeleter;
/// <summary>
/// Allows inventory details to be sent to clients asynchronously
/// </summary>
protected AsyncInventorySender m_asyncInventorySender;
/// <summary>
/// Start all the scripts in the scene which should be started.
/// </summary>

View File

@ -462,31 +462,6 @@ namespace OpenSim.Region.Framework.Scenes
);
}
/// <summary>
/// Handle a fetch inventory request from the client
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="ownerID"></param>
public void HandleFetchInventory(IClientAPI remoteClient, UUID itemID, UUID ownerID)
{
if (LibraryService != null && LibraryService.LibraryRootFolder != null && ownerID == LibraryService.LibraryRootFolder.Owner)
{
//m_log.Debug("request info for library item");
return;
}
InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
item = InventoryService.GetItem(item);
if (item != null)
{
remoteClient.SendInventoryItemDetails(ownerID, item);
}
// else shouldn't we send an alert message?
}
/// <summary>
/// Tell the client about the various child items and folders contained in the requested folder.
/// </summary>

View File

@ -604,6 +604,8 @@ namespace OpenSim.Region.Framework.Scenes
m_asyncSceneObjectDeleter = new AsyncSceneObjectGroupDeleter(this);
m_asyncSceneObjectDeleter.Enabled = true;
m_asyncInventorySender = new AsyncInventorySender(this);
#region Region Settings
// Load region settings
@ -2866,14 +2868,13 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void SubscribeToClientInventoryEvents(IClientAPI client)
{
client.OnLinkInventoryItem += HandleLinkInventoryItem;
client.OnCreateNewInventoryFolder += HandleCreateInventoryFolder;
client.OnUpdateInventoryFolder += HandleUpdateInventoryFolder;
client.OnMoveInventoryFolder += HandleMoveInventoryFolder; // 2; //!!
client.OnFetchInventoryDescendents += HandleFetchInventoryDescendents;
client.OnPurgeInventoryDescendents += HandlePurgeInventoryDescendents; // 2; //!!
client.OnFetchInventory += HandleFetchInventory;
client.OnFetchInventory += m_asyncInventorySender.HandleFetchInventory;
client.OnUpdateInventoryItem += UpdateInventoryItemAsset;
client.OnCopyInventoryItem += CopyInventoryItem;
client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy;
@ -2993,13 +2994,12 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
{
client.OnCreateNewInventoryFolder -= HandleCreateInventoryFolder;
client.OnUpdateInventoryFolder -= HandleUpdateInventoryFolder;
client.OnMoveInventoryFolder -= HandleMoveInventoryFolder; // 2; //!!
client.OnFetchInventoryDescendents -= HandleFetchInventoryDescendents;
client.OnPurgeInventoryDescendents -= HandlePurgeInventoryDescendents; // 2; //!!
client.OnFetchInventory -= HandleFetchInventory;
client.OnFetchInventory -= m_asyncInventorySender.HandleFetchInventory;
client.OnUpdateInventoryItem -= UpdateInventoryItemAsset;
client.OnCopyInventoryItem -= CopyInventoryItem;
client.OnMoveInventoryItem -= MoveInventoryItem;

View File

@ -34,7 +34,6 @@ using Nini.Config;
using OpenMetaverse;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.CoreModules.Avatar.NPC;
using OpenSim.Framework;
using Timer=System.Timers.Timer;
using OpenSim.Services.Interfaces;
@ -47,31 +46,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC
// private const bool m_enabled = false;
private Mutex m_createMutex;
private Timer m_timer;
private Dictionary<UUID,NPCAvatar> m_avatars = new Dictionary<UUID, NPCAvatar>();
private Dictionary<UUID,AvatarAppearance> m_appearanceCache = new Dictionary<UUID, AvatarAppearance>();
// Timer vars.
private bool p_inUse = false;
private readonly object p_lock = new object();
// Private Temporary Variables.
private string p_firstname;
private string p_lastname;
private Vector3 p_position;
private Scene p_scene;
private UUID p_cloneAppearanceFrom;
private UUID p_returnUuid;
public void Initialise(Scene scene, IConfigSource source)
{
m_createMutex = new Mutex(false);
m_timer = new Timer(500);
m_timer.Elapsed += m_timer_Elapsed;
m_timer.Start();
scene.RegisterModuleInterface<INPCModule>(this);
}
@ -90,35 +69,53 @@ namespace OpenSim.Region.OptionalModules.World.NPC
return new AvatarAppearance();
}
public UUID CreateNPC(string firstname, string lastname,Vector3 position, Scene scene, UUID cloneAppearanceFrom)
public UUID CreateNPC(string firstname, string lastname, Vector3 position, Scene scene, UUID cloneAppearanceFrom)
{
NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, scene);
npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
m_log.DebugFormat(
"[NPC MODULE]: Queueing request to create NPC {0} {1} at {2} in {3} cloning appearance of {4}",
firstname, lastname, position, scene.RegionInfo.RegionName, cloneAppearanceFrom);
"[NPC MODULE]: Creating NPC {0} {1} {2} at {3} in {4}",
firstname, lastname, npcAvatar.AgentId, position, scene.RegionInfo.RegionName);
// Block.
m_createMutex.WaitOne();
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = npcAvatar.AgentId;
acd.firstname = firstname;
acd.lastname = lastname;
acd.ServiceURLs = new Dictionary<string, object>();
// Copy Temp Variables for Timer to pick up.
lock (p_lock)
AvatarAppearance originalAppearance = GetAppearance(cloneAppearanceFrom, scene);
AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true);
acd.Appearance = npcAppearance;
scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd);
scene.AddNewClient(npcAvatar);
ScenePresence sp;
if (scene.TryGetScenePresence(npcAvatar.AgentId, out sp))
{
p_firstname = firstname;
p_lastname = lastname;
p_position = position;
p_scene = scene;
p_cloneAppearanceFrom = cloneAppearanceFrom;
p_inUse = true;
p_returnUuid = UUID.Zero;
m_log.DebugFormat(
"[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID);
// Shouldn't call this - temporary.
sp.CompleteMovement(npcAvatar);
// sp.SendAppearanceToAllOtherAgents();
//
// // Send animations back to the avatar as well
// sp.Animator.SendAnimPack();
}
else
{
m_log.WarnFormat("[NPC MODULE]: Could not find scene presence for NPC {0} {1}", sp.Name, sp.UUID);
}
while (p_returnUuid == UUID.Zero)
{
Thread.Sleep(250);
}
lock (m_avatars)
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
m_createMutex.ReleaseMutex();
m_log.DebugFormat("[NPC MODULE]: Created NPC with id {0}", npcAvatar.AgentId);
return p_returnUuid;
return npcAvatar.AgentId;
}
public void Autopilot(UUID agentID, Scene scene, Vector3 pos)
@ -157,69 +154,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC
}
}
void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
lock (p_lock)
{
if (p_inUse)
{
p_inUse = false;
NPCAvatar npcAvatar = new NPCAvatar(p_firstname, p_lastname, p_position, p_scene);
npcAvatar.CircuitCode = (uint) Util.RandomClass.Next(0, int.MaxValue);
m_log.DebugFormat(
"[NPC MODULE]: Creating NPC {0} {1} {2} at {3} in {4}",
p_firstname, p_lastname, npcAvatar.AgentId, p_position, p_scene.RegionInfo.RegionName);
AgentCircuitData acd = new AgentCircuitData();
acd.AgentID = npcAvatar.AgentId;
acd.firstname = p_firstname;
acd.lastname = p_lastname;
acd.ServiceURLs = new Dictionary<string, object>();
AvatarAppearance originalAppearance = GetAppearance(p_cloneAppearanceFrom, p_scene);
AvatarAppearance npcAppearance = new AvatarAppearance(originalAppearance, true);
acd.Appearance = npcAppearance;
p_scene.AuthenticateHandler.AddNewCircuit(npcAvatar.CircuitCode, acd);
p_scene.AddNewClient(npcAvatar);
ScenePresence sp;
if (p_scene.TryGetScenePresence(npcAvatar.AgentId, out sp))
{
m_log.DebugFormat(
"[NPC MODULE]: Successfully retrieved scene presence for NPC {0} {1}", sp.Name, sp.UUID);
// Shouldn't call this - temporary.
sp.CompleteMovement(npcAvatar);
// sp.SendAppearanceToAllOtherAgents();
//
// // Send animations back to the avatar as well
// sp.Animator.SendAnimPack();
}
else
{
m_log.WarnFormat("[NPC MODULE]: Could not find scene presence for NPC {0} {1}", sp.Name, sp.UUID);
}
m_avatars.Add(npcAvatar.AgentId, npcAvatar);
p_returnUuid = npcAvatar.AgentId;
m_log.DebugFormat("[NPC MODULE]: Created NPC with id {0}", p_returnUuid);
}
}
}
catch (Exception ex)
{
m_log.ErrorFormat("[NPC MODULE]: NPC creation failed with exception {0} {1}", ex.Message, ex.StackTrace);
}
}
public void PostInitialise()
{
}

View File

@ -0,0 +1,71 @@
/*
* 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.Reflection;
using Nini.Config;
using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.AvatarService;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
namespace OpenSim.Region.OptionalModules.World.NPC.Tests
{
[TestFixture]
public class NPCModuleTests
{
[Test]
public void TestCreate()
{
TestHelper.InMethod();
// log4net.Config.XmlConfigurator.Configure();
IConfigSource config = new IniConfigSource();
config.AddConfig("Modules");
config.Configs["Modules"].Set("AvatarServices", "LocalAvatarServicesConnector");
config.AddConfig("AvatarService");
config.Configs["AvatarService"].Set("LocalServiceModule", "OpenSim.Services.AvatarService.dll:AvatarService");
config.Configs["AvatarService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
TestScene scene = SceneSetupHelpers.SetupScene();
SceneSetupHelpers.SetupSceneModules(scene, config, new NPCModule(), new LocalAvatarServicesConnector());
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, UUID.Zero);
ScenePresence npc = scene.GetScenePresence(npcId);
Assert.That(npc, Is.Not.Null);
}
}
}

View File

@ -291,7 +291,14 @@ namespace OpenSim.Region.Physics.Meshing
{
try
{
meshOsd = (OSDMap)OSDParser.DeserializeLLSDBinary(data);
OSD osd = OSDParser.DeserializeLLSDBinary(data);
if (osd is OSDMap)
meshOsd = (OSDMap)osd;
else
{
m_log.Warn("[Mesh}: unable to cast mesh asset to OSDMap");
return null;
}
}
catch (Exception e)
{
@ -302,11 +309,17 @@ namespace OpenSim.Region.Physics.Meshing
if (meshOsd is OSDMap)
{
OSDMap physicsParms = null;
OSDMap map = (OSDMap)meshOsd;
OSDMap physicsParms = (OSDMap)map["physics_shape"]; // old asset format
if (physicsParms.Count == 0)
if (map.ContainsKey("physics_shape"))
physicsParms = (OSDMap)map["physics_shape"]; // old asset format
else if (map.ContainsKey("physics_mesh"))
physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
if (physicsParms == null)
{
m_log.Warn("[Mesh]: no recognized physics mesh found in mesh asset");
return null;
}
int physOffset = physicsParms["offset"].AsInteger() + (int)start;
int physSize = physicsParms["size"].AsInteger();

View File

@ -2502,7 +2502,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
// if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
if (!forceSimplePrimMeshing)
if (!forceSimplePrimMeshing && !pbs.SculptEntry)
{
if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
|| (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
@ -2592,6 +2592,9 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
if (pbs.SculptEntry && meshSculptedPrim)
iPropertiesNotSupportedDefault++;
if (iPropertiesNotSupportedDefault == 0)
{

View File

@ -38,7 +38,6 @@ using OpenSim;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.CoreModules.Avatar.NPC;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.ScriptEngine.Shared;

View File

@ -36,6 +36,15 @@ namespace OpenSim.Tests.Common
{
public class AssetHelpers
{
/// <summary>
/// Create a notecard asset with a random uuids and dummy text.
/// </summary>
/// <returns></returns>
public static AssetBase CreateAsset()
{
return CreateAsset(UUID.Random(), AssetType.Notecard, "hello", UUID.Random());
}
/// <summary>
/// Create a notecard asset with a random uuid and dummy text.
/// </summary>

View File

@ -28,6 +28,7 @@
using System;
using System.Diagnostics;
using NUnit.Framework;
using OpenMetaverse;
namespace OpenSim.Tests.Common
{
@ -56,5 +57,15 @@ namespace OpenSim.Tests.Common
Console.WriteLine();
Console.WriteLine("===> In Test Method : {0} <===", stackTrace.GetFrame(1).GetMethod().Name);
}
/// <summary>
/// Parse tail section into full UUID.
/// </summary>
/// <param name="tail"></param>
/// <returns></returns>
public static UUID ParseTail(int tail)
{
return new UUID(string.Format("00000000-0000-0000-0000-{0:X12}", tail));
}
}
}

View File

@ -239,7 +239,7 @@ namespace OpenSim.Tools.Configger
config.Set("meshing", "Meshmerizer");
config.Set("physical_prim", true);
config.Set("see_into_this_sim_from_neighbor", true);
config.Set("serverside_object_permissions", false);
config.Set("serverside_object_permissions", true);
config.Set("storage_plugin", "OpenSim.Data.SQLite.dll");
config.Set("storage_connection_string", "URI=file:OpenSim.db,version=3");
config.Set("storage_prim_inventories", true);

View File

@ -78,20 +78,19 @@
; DrawPrimOnMapTile = true
;# {NonPhysicalPrimMax} {} {Maximum size of nonphysical prims?} {} 256
;; Maximum size for non-physical prims
;; Maximum size for non-physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
; NonPhysicalPrimMax = 256
;# {PhysicalPrimMax} {} {Maximum size of physical prims?} {} 10
;; Maximum size where a prim can be physical
;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file.
; PhysicalPrimMax = 10
;; Prevent the creation, import and rez of prims that exceed the
;; maximum size.
;; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum
;; This can be overriden in the region config file.
; ClampPrimSize = false
;# {AllowScriptCrossing} {} {Allow scripts to cross into this region} {true false} false
;; Allow scripts to cross region boundaries. These are recompiled on the
;; new region.
;; Allow scripts to keep running when they cross region boundaries, rather than being restarted. Script code is recompiled on the destination region and the state reloaded.
; AllowScriptCrossing = false
;# {TrustBinaries} {AllowScriptCrossing:true} {Accept compiled binary script code? (DANGEROUS!)} {true false} false
@ -173,7 +172,7 @@
;; permission checks (allowing anybody to copy
;; any item, etc. This may not yet be implemented uniformally.
;; If set to true, then all permissions checks are carried out
; serverside_object_permissions = false
; serverside_object_permissions = true
;; This allows users with a UserLevel of 200 or more to assume god
;; powers in the regions in this simulator.
@ -292,28 +291,31 @@
;; building's lights to possibly not be rendered.
; DisableFacelights = "false"
[ClientStack.LindenCaps]
;; For the long list of capabilities, see OpenSimDefaults.ini
;; Here are the few ones you may want to change. Possible values
;; are:
;; "" -- empty, capability disabled
;; "localhost" -- capability enabled and served by the simulator
;; "<url>" -- capability enabled and served by some other server
;;
; These are enabled by default to localhost. Change if you see fit.
Cap_GetTexture = "localhost"
Cap_GetMesh = "localhost"
; This is disabled by default. Change if you see fit. Note that
; serving this cap from the simulators may lead to poor performace.
Cap_WebFetchInventoryDescendents = ""
;; For the long list of capabilities, see OpenSimDefaults.ini
;; Here are the few ones you may want to change. Possible values
;; are:
;; "" -- empty, capability disabled
;; "localhost" -- capability enabled and served by the simulator
;; "<url>" -- capability enabled and served by some other server
;;
; These are enabled by default to localhost. Change if you see fit.
Cap_GetTexture = "localhost"
Cap_GetMesh = "localhost"
; This is disabled by default. Change if you see fit. Note that
; serving this cap from the simulators may lead to poor performace.
Cap_WebFetchInventoryDescendents = ""
[SimulatorFeatures]
; Experimental new information sent in SimulatorFeatures cap for Kokua viewers
; meant to override the MapImage and search server url given at login, and varying
; on a sim-basis.
; Viewers that don't understand it, will ignore it
;MapImageServerURI = "http://127.0.0.1:9000/
;SearchServerURI = "http://127.0.0.1:9000/
; Experimental new information sent in SimulatorFeatures cap for Kokua viewers
; meant to override the MapImage and search server url given at login, and varying
; on a sim-basis.
; Viewers that don't understand it, will ignore it
;MapImageServerURI = "http://127.0.0.1:9000/
;SearchServerURI = "http://127.0.0.1:9000/
[Chat]
;# {whisper_distance} {} {Distance at which a whisper is heard, in meters?} {} 10
@ -650,6 +652,7 @@
;; If using a remote connector, specify the server URL
; FreeswitchServiceURL = http://my.grid.server:8004/fsapi
[Groups]
;# {Enabled} {} {Enable groups?} {true false} false
;; Enables the groups module
@ -707,11 +710,13 @@
;; Enable media on a prim facilities
; Enabled = true;
[PrimLimitsModule]
;# {EnforcePrimLimits} {} {Enforce parcel prim limits} {true false} false
;; Enable parcel prim limits. Off by default to emulate pre-existing behavior.
; EnforcePrimLimits = false
[Architecture]
;# {Include-Architecture} {} {Choose one of the following architectures} {config-include/Standalone.ini config-include/StandaloneHypergrid.ini config-include/Grid.ini config-include/GridHypergrid.ini config-include/SimianGrid.ini config-include/HyperSimianGrid.ini} config-include/Standalone.ini
;; Uncomment one of the following includes as required. For instance, to create a standalone OpenSim,

View File

@ -14,10 +14,13 @@
; Place to create a PID file
; PIDFile = "/tmp/my.pid"
; Console commands run at startup
startup_console_commands_file = "startup_commands.txt"
; Console commands run on shutdown
shutdown_console_commands_file = "shutdown_commands.txt"
; To run a script every few minutes, set the script filename here
; Console commands run every 20 minutes
; timer_Script = "filename"
; ##
@ -70,12 +73,17 @@
; Use terrain texture for maptiles if true, use shaded green if false
TextureOnMapTile = false
; Maximum total size, and maximum size where a prim can be physical
; Maximum size of non physical prims. Affects resizing of existing prims. This can be overriden in the region config file (as NonphysicalPrimMax!).
NonPhysicalPrimMax = 256
PhysicalPrimMax = 10 ; (I think this was moved to the Regions.ini!)
; Maximum size of physical prims. Affects resizing of existing prims. This can be overriden in the region config file.
PhysicalPrimMax = 10
; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum
; This can be overriden in the region config file.
ClampPrimSize = false
; Allow scripts to cross region boundaries. These are recompiled on the new region.
; Allow scripts to keep running when they cross region boundaries, rather than being restarted. Script code is recompiled on the destination region and the state reloaded.
AllowScriptCrossing = false
; Allow compiled script binary code to cross region boundaries.
@ -94,7 +102,7 @@
; neighbors on each side for a total of 49 regions in view. Warning, unless
; all the regions have the same drawdistance, you will end up with strange
; effects because the agents that get closed may be inconsistent.
; DefaultDrawDistance = 255.0
DefaultDrawDistance = 255.0
; If you have only one region in an instance, or to avoid the many bugs
; that you can trigger in modules by restarting a region, set this to
@ -102,7 +110,7 @@
; This is meant to be used on systems where some external system like
; Monit will restart any instance that exits, thereby making the shutdown
; into a restart.
;InworldRestartShutsDown = false
InworldRestartShutsDown = false
; ##
; ## PRIM STORAGE
@ -227,7 +235,6 @@
; If enabled, enableFlySlow will change the primary fly state to
; FLYSLOW, and the "always run" state will be the regular fly.
enableflyslow = false
; PreJump is an additional animation state, but it probably
@ -236,7 +243,6 @@
; This is commented so it will come on automatically once it's
; supported.
; enableprejump = true
; Simulator Stats URI
@ -265,6 +271,7 @@
DelayBeforeAppearanceSave = 5
DelayBeforeAppearanceSend = 2
[SMTP]
enabled=false

View File

@ -19,9 +19,12 @@
; 0 to disable
HitRateDisplay = 100
; Set to false for disk cache only.
; Set to false for no memory cache
MemoryCacheEnabled = false
; Set to false for no file cache
FileCacheEnabled = true
; How long {in hours} to keep assets cached in memory, .5 == 30 minutes
; Optimization: for VPS or limited memory system installs set Timeout to .016 (1 minute)
; increases performance without large memory impact

View File

@ -2985,6 +2985,7 @@
<Files>
<!-- SADLY the way this works means you need to keep adding these paths -->
<Match path="Agent/TextureSender/Tests" pattern="*.cs" recurse="true"/>
<Match path="Asset/Tests" pattern="*.cs" recurse="true"/>
<Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true"/>
<Match path="Framework/InventoryAccess/Tests" pattern="*.cs" recurse="true"/>
<Match path="World/Archiver/Tests" pattern="*.cs" recurse="true"/>
@ -3029,6 +3030,7 @@
<Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.OptionalModules"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Services.AvatarService"/>
<Reference name="OpenSim.Services.Interfaces"/>
<!-- Unit tests -->
@ -3052,6 +3054,7 @@
<Files>
<!-- SADLY the way this works means you need to keep adding these paths -->
<Match path="Avatar/XmlRpcGroups/Tests" pattern="*.cs" recurse="true"/>
<Match path="World/NPC/Tests" pattern="*.cs" recurse="true"/>
</Files>
</Project>