Merge branch 'master' of ssh://MyConnection/var/git/opensim
commit
2f40161f38
|
@ -13,7 +13,7 @@ people that make the day to day of OpenSim happen.
|
|||
* lbsa71 (Tribal Media AB)
|
||||
* Sean Dague / sdague (IBM)
|
||||
* Tedd
|
||||
* justincc (Black Dress Technology)
|
||||
* justincc
|
||||
* Teravus (w3z)
|
||||
* Johan Berntsson (3Di)
|
||||
* Ckrinke (Charles Krinke)
|
||||
|
@ -29,6 +29,7 @@ people that make the day to day of OpenSim happen.
|
|||
* nlin (3Di)
|
||||
* Arthur Rodrigo S Valadares (IBM)
|
||||
|
||||
|
||||
= Past Open Sim Developers =
|
||||
These folks are alumns of the OpenSim core group, but are now
|
||||
currently not active. Their great contributions helped get us to
|
||||
|
@ -44,6 +45,7 @@ where we are today.
|
|||
* Darok
|
||||
* Alondria
|
||||
|
||||
|
||||
= Additional OpenSim Contributors =
|
||||
These folks have contributed code patches to OpenSim to help make it
|
||||
what it is today.
|
||||
|
@ -90,6 +92,7 @@ what it is today.
|
|||
* maimedleech
|
||||
* Mic Bowman
|
||||
* Michelle Argus
|
||||
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
||||
* Mike Osias (IBM)
|
||||
* Mike Pitman (IBM)
|
||||
* mikkopa/_someone - RealXtend
|
||||
|
@ -123,8 +126,7 @@ what it is today.
|
|||
* Zha Ewry
|
||||
|
||||
|
||||
|
||||
LSL Devs
|
||||
= LSL Devs =
|
||||
|
||||
* Alondria
|
||||
* CharlieO
|
||||
|
@ -132,7 +134,7 @@ LSL Devs
|
|||
* Melanie Thielker
|
||||
|
||||
|
||||
Testers
|
||||
= Testers =
|
||||
|
||||
* Ai Austin
|
||||
* CharlieO (LSL)
|
||||
|
@ -140,10 +142,6 @@ Testers
|
|||
* openlifegrid.com
|
||||
|
||||
|
||||
AssetInventory Server and some plugins are based on Cable Beach
|
||||
Cable Beach is Copyright (c) 2008 Intel Corporation
|
||||
see http://forge.opensimulator.org/gf/project/assetserver/
|
||||
|
||||
This software uses components from the following developers:
|
||||
* Sleepycat Software (Berkeley DB)
|
||||
* SQLite (Public Domain)
|
||||
|
@ -161,6 +159,10 @@ This software uses components from the following developers:
|
|||
* log4net (http://logging.apache.org/log4net/)
|
||||
* GlynnTucker.Cache (http://gtcache.sourceforge.net/)
|
||||
|
||||
Some plugins are based on Cable Beach
|
||||
Cable Beach is Copyright (c) 2008 Intel Corporation
|
||||
see http://forge.opensimulator.org/gf/project/assetserver/
|
||||
|
||||
In addition, we would like to thank:
|
||||
* The Mono Project
|
||||
* The NANT Developers
|
||||
|
|
|
@ -139,15 +139,8 @@ namespace OpenSim.Client.Linden
|
|||
return m_regionsConnector.RequestNeighbourInfo(homeRegionId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prepare a login to the given region. This involves both telling the region to expect a connection
|
||||
/// and appropriately customising the response to the user.
|
||||
/// </summary>
|
||||
/// <param name="sim"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="response"></param>
|
||||
/// <returns>true if the region was successfully contacted, false otherwise</returns>
|
||||
protected override bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint remoteClient)
|
||||
protected override bool PrepareLoginToRegion(
|
||||
RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint remoteClient)
|
||||
{
|
||||
IPEndPoint endPoint = regionInfo.ExternalEndPoint;
|
||||
response.SimAddress = endPoint.Address.ToString();
|
||||
|
@ -204,7 +197,8 @@ namespace OpenSim.Client.Linden
|
|||
agent.Appearance = m_userManager.GetUserAppearance(user.ID);
|
||||
if (agent.Appearance == null)
|
||||
{
|
||||
m_log.WarnFormat("[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname);
|
||||
m_log.WarnFormat(
|
||||
"[INTER]: Appearance not found for {0} {1}. Creating default.", agent.firstname, agent.lastname);
|
||||
agent.Appearance = new AvatarAppearance(agent.AgentID);
|
||||
}
|
||||
|
||||
|
@ -243,7 +237,8 @@ namespace OpenSim.Client.Linden
|
|||
return;
|
||||
}
|
||||
|
||||
m_regionsConnector.LogOffUserFromGrid(SimInfo.RegionHandle, theUser.ID, theUser.CurrentAgent.SecureSessionID, "Logging you off");
|
||||
m_regionsConnector.LogOffUserFromGrid(
|
||||
SimInfo.RegionHandle, theUser.ID, theUser.CurrentAgent.SecureSessionID, "Logging you off");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,8 +57,8 @@ namespace OpenSim.Framework.Capabilities
|
|||
public delegate void TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
|
||||
bool isScriptRunning, byte[] data);
|
||||
|
||||
public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
||||
bool fetchFolders, bool fetchItems, int sortOrder);
|
||||
public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
||||
bool fetchFolders, bool fetchItems, int sortOrder, out int version);
|
||||
|
||||
/// <summary>
|
||||
/// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
|
||||
|
@ -89,7 +89,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
//private static readonly string m_requestTexture = "0003/";
|
||||
private static readonly string m_notecardUpdatePath = "0004/";
|
||||
private static readonly string m_notecardTaskUpdatePath = "0005/";
|
||||
// private static readonly string m_fetchInventoryPath = "0006/";
|
||||
private static readonly string m_fetchInventoryPath = "0006/";
|
||||
|
||||
// The following entries are in a module, however, they are also here so that we don't re-assign
|
||||
// the path to another cap by mistake.
|
||||
|
@ -207,7 +207,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
// As of RC 1.22.9 of the Linden client this is
|
||||
// supported
|
||||
|
||||
// m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest);
|
||||
m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest);
|
||||
|
||||
// justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and
|
||||
// subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires
|
||||
|
@ -449,57 +449,58 @@ namespace OpenSim.Framework.Capabilities
|
|||
contents.owner_id = invFetch.owner_id;
|
||||
contents.folder_id = invFetch.folder_id;
|
||||
|
||||
// The version number being sent back was originally 1.
|
||||
// Unfortunately, on 1.19.1.4, this means that we see a problem where on subsequent logins
|
||||
// without clearing client cache, objects in the root folder disappear until the cache is cleared,
|
||||
// at which point they reappear.
|
||||
//
|
||||
// Seeing the version to something other than 0 may be the right thing to do, but there is
|
||||
// a greater subtlety of the second life protocol that needs to be understood first.
|
||||
contents.version = 0;
|
||||
|
||||
contents.descendents = 0;
|
||||
reply.folders.Array.Add(contents);
|
||||
List<InventoryItemBase> itemList = null;
|
||||
InventoryCollection inv = new InventoryCollection();
|
||||
inv.Folders = new List<InventoryFolderBase>();
|
||||
inv.Items = new List<InventoryItemBase>();
|
||||
int version = 0;
|
||||
if (CAPSFetchInventoryDescendents != null)
|
||||
{
|
||||
itemList = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order);
|
||||
inv = CAPSFetchInventoryDescendents(m_agentID, invFetch.folder_id, invFetch.owner_id, invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version);
|
||||
}
|
||||
|
||||
if (itemList != null)
|
||||
if (inv.Folders != null)
|
||||
{
|
||||
foreach (InventoryItemBase invItem in itemList)
|
||||
foreach (InventoryFolderBase invFolder in inv.Folders)
|
||||
{
|
||||
contents.categories.Array.Add(ConvertInventoryFolder(invFolder));
|
||||
}
|
||||
}
|
||||
|
||||
if (inv.Items != null)
|
||||
{
|
||||
foreach (InventoryItemBase invItem in inv.Items)
|
||||
{
|
||||
contents.items.Array.Add(ConvertInventoryItem(invItem));
|
||||
}
|
||||
}
|
||||
/* The following block is removed as it ALWAYS sends the error to the client because the RC 1.22.9 client tries to
|
||||
find items that have become dissasociated with a paret folder and have parent of 00000000-0000-00000....
|
||||
else
|
||||
{
|
||||
IClientAPI client = GetClient(m_agentID);
|
||||
|
||||
// We're going to both notify the client of inventory service failure and send back a 'no folder contents' response.
|
||||
// If we don't send back the response,
|
||||
// the client becomes unhappy (see Teravus' comment in FetchInventoryRequest())
|
||||
if (client != null)
|
||||
{
|
||||
client.SendAgentAlertMessage(
|
||||
"AGIN0001E: The inventory service has either failed or is not responding. Your inventory will not function properly for the rest of this session. Please clear your cache and relog.",
|
||||
true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[AGENT INVENTORY]: Could not lookup controlling client for {0} in order to notify them of the inventory service failure",
|
||||
m_agentID);
|
||||
}
|
||||
}*/
|
||||
contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
|
||||
contents.version = version;
|
||||
|
||||
contents.descendents = contents.items.Array.Count;
|
||||
return reply;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an internal inventory folder object into an LLSD object.
|
||||
/// </summary>
|
||||
/// <param name="invFolder"></param>
|
||||
/// <returns></returns>
|
||||
private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder)
|
||||
{
|
||||
LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder();
|
||||
llsdFolder.folder_id = invFolder.ID;
|
||||
llsdFolder.parent_id = invFolder.ParentID;
|
||||
llsdFolder.name = invFolder.Name;
|
||||
if (invFolder.Type == -1)
|
||||
llsdFolder.type = "-1";
|
||||
else
|
||||
llsdFolder.type = TaskInventoryItem.Types[invFolder.Type];
|
||||
llsdFolder.preferred_type = "-1";
|
||||
|
||||
return llsdFolder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert an internal inventory item object into an LLSD object.
|
||||
/// </summary>
|
||||
|
@ -529,15 +530,29 @@ namespace OpenSim.Framework.Capabilities
|
|||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
|
||||
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
|
||||
llsdItem.permissions.group_id = UUID.Zero;
|
||||
llsdItem.permissions.group_mask = 0;
|
||||
llsdItem.permissions.is_owner_group = false;
|
||||
llsdItem.permissions.group_id = invItem.GroupID;
|
||||
llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
|
||||
llsdItem.permissions.is_owner_group = invItem.GroupOwned;
|
||||
llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
|
||||
llsdItem.permissions.owner_id = m_agentID; // FixMe
|
||||
llsdItem.permissions.owner_id = m_agentID;
|
||||
llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||
llsdItem.sale_info = new LLSDSaleInfo();
|
||||
llsdItem.sale_info.sale_price = 10;
|
||||
llsdItem.sale_info.sale_type = "not";
|
||||
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||
switch (invItem.SaleType)
|
||||
{
|
||||
default:
|
||||
llsdItem.sale_info.sale_type = "not";
|
||||
break;
|
||||
case 1:
|
||||
llsdItem.sale_info.sale_type = "original";
|
||||
break;
|
||||
case 2:
|
||||
llsdItem.sale_info.sale_type = "copy";
|
||||
break;
|
||||
case 3:
|
||||
llsdItem.sale_info.sale_type = "contents";
|
||||
break;
|
||||
}
|
||||
|
||||
return llsdItem;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Framework.Capabilities
|
||||
{
|
||||
[OSDMap]
|
||||
public class LLSDInventoryFolder
|
||||
{
|
||||
public UUID folder_id;
|
||||
public UUID parent_id;
|
||||
public string name;
|
||||
public string type;
|
||||
public string preferred_type;
|
||||
}
|
||||
}
|
|
@ -90,6 +90,7 @@ namespace OpenSim.Framework.Capabilities
|
|||
public UUID agent_id;
|
||||
public int descendents;
|
||||
public UUID folder_id;
|
||||
public OSDArray categories = new OSDArray();
|
||||
public OSDArray items = new OSDArray();
|
||||
public UUID owner_id;
|
||||
public int version;
|
||||
|
|
|
@ -1063,7 +1063,18 @@ namespace OpenSim.Framework.Communications.Services
|
|||
protected abstract RegionInfo RequestClosestRegion(string region);
|
||||
protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle);
|
||||
protected abstract RegionInfo GetRegionInfo(UUID homeRegionId);
|
||||
protected abstract bool PrepareLoginToRegion(RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint client);
|
||||
|
||||
/// <summary>
|
||||
/// Prepare a login to the given region. This involves both telling the region to expect a connection
|
||||
/// and appropriately customising the response to the user.
|
||||
/// </summary>
|
||||
/// <param name="sim"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="response"></param>
|
||||
/// <param name="remoteClient"></param>
|
||||
/// <returns>true if the region was successfully contacted, false otherwise</returns>
|
||||
protected abstract bool PrepareLoginToRegion(
|
||||
RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint client);
|
||||
|
||||
/// <summary>
|
||||
/// Add active gestures of the user to the login response.
|
||||
|
|
|
@ -30,7 +30,7 @@ using OpenMetaverse;
|
|||
namespace OpenSim.Framework
|
||||
{
|
||||
/// <summary>
|
||||
/// A Class for folders which contain users inventory
|
||||
/// User inventory folder
|
||||
/// </summary>
|
||||
public class InventoryFolderBase : InventoryNodeBase
|
||||
{
|
||||
|
|
|
@ -94,6 +94,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
|
||||
Stream requestStream = request.GetRequestStream();
|
||||
requestStream.Write(buffer.ToArray(), 0, length);
|
||||
requestStream.Close();
|
||||
TResponse deserial = default(TResponse);
|
||||
using (WebResponse resp = request.GetResponse())
|
||||
{
|
||||
|
@ -101,7 +102,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
|||
deserial = (TResponse)deserializer.Deserialize(resp.GetResponseStream());
|
||||
resp.Close();
|
||||
}
|
||||
requestStream.Close();
|
||||
return deserial;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using OpenMetaverse;
|
||||
|
@ -38,9 +39,12 @@ using OpenMetaverse.Imaging;
|
|||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||
{
|
||||
public delegate void J2KDecodeDelegate(UUID AssetId);
|
||||
|
||||
public class J2KDecoderModule : IRegionModule, IJ2KDecoder
|
||||
{
|
||||
#region IRegionModule Members
|
||||
|
@ -53,8 +57,12 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
|||
/// </summary>
|
||||
private readonly Dictionary<UUID, OpenJPEG.J2KLayerInfo[]> m_cacheddecode = new Dictionary<UUID, OpenJPEG.J2KLayerInfo[]>();
|
||||
private bool OpenJpegFail = false;
|
||||
private readonly string CacheFolder = Util.dataDir() + "/j2kDecodeCache";
|
||||
private readonly J2KDecodeFileCache fCache;
|
||||
private string CacheFolder = Util.dataDir() + "/j2kDecodeCache";
|
||||
private int CacheTimeout = 720;
|
||||
private J2KDecodeFileCache fCache = null;
|
||||
private Thread CleanerThread = null;
|
||||
private IAssetService AssetService = null;
|
||||
private Scene m_Scene = null;
|
||||
|
||||
/// <summary>
|
||||
/// List of client methods to notify of results of decode
|
||||
|
@ -63,17 +71,37 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
|||
|
||||
public J2KDecoderModule()
|
||||
{
|
||||
fCache = new J2KDecodeFileCache(CacheFolder);
|
||||
}
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource source)
|
||||
{
|
||||
if (m_Scene == null)
|
||||
m_Scene = scene;
|
||||
|
||||
IConfig j2kConfig = source.Configs["J2KDecoder"];
|
||||
if (j2kConfig != null)
|
||||
{
|
||||
CacheFolder = j2kConfig.GetString("CacheDir", CacheFolder);
|
||||
CacheTimeout = j2kConfig.GetInt("CacheTimeout", CacheTimeout);
|
||||
}
|
||||
|
||||
if (fCache == null)
|
||||
fCache = new J2KDecodeFileCache(CacheFolder, CacheTimeout);
|
||||
|
||||
scene.RegisterModuleInterface<IJ2KDecoder>(this);
|
||||
|
||||
if (CleanerThread == null && CacheTimeout != 0)
|
||||
{
|
||||
CleanerThread = new Thread(CleanCache);
|
||||
CleanerThread.Name = "J2KCleanerThread";
|
||||
CleanerThread.IsBackground = true;
|
||||
CleanerThread.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
{
|
||||
|
||||
AssetService = m_Scene.AssetService;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
|
@ -329,8 +357,9 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
|||
// Cache Decoded layers
|
||||
lock (m_cacheddecode)
|
||||
{
|
||||
if (!m_cacheddecode.ContainsKey(AssetId))
|
||||
m_cacheddecode.Add(AssetId, layers);
|
||||
if (m_cacheddecode.ContainsKey(AssetId))
|
||||
m_cacheddecode.Remove(AssetId);
|
||||
m_cacheddecode.Add(AssetId, layers);
|
||||
|
||||
}
|
||||
|
||||
|
@ -348,11 +377,34 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanCache()
|
||||
{
|
||||
m_log.Info("[J2KDecoderModule]: Cleaner thread started");
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (AssetService != null)
|
||||
fCache.ScanCacheFiles(RedecodeTexture);
|
||||
|
||||
System.Threading.Thread.Sleep(600000);
|
||||
}
|
||||
}
|
||||
|
||||
private void RedecodeTexture(UUID assetID)
|
||||
{
|
||||
AssetBase texture = AssetService.Get(assetID.ToString());
|
||||
if (texture == null)
|
||||
return;
|
||||
|
||||
doJ2kDecode(assetID, texture.Data);
|
||||
}
|
||||
}
|
||||
|
||||
public class J2KDecodeFileCache
|
||||
{
|
||||
private readonly string m_cacheDecodeFolder;
|
||||
private readonly int m_cacheTimeout;
|
||||
private bool enabled = true;
|
||||
|
||||
private static readonly ILog m_log
|
||||
|
@ -362,9 +414,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
|||
/// Creates a new instance of a file cache
|
||||
/// </summary>
|
||||
/// <param name="pFolder">base folder for the cache. Will be created if it doesn't exist</param>
|
||||
public J2KDecodeFileCache(string pFolder)
|
||||
public J2KDecodeFileCache(string pFolder, int timeout)
|
||||
{
|
||||
m_cacheDecodeFolder = pFolder;
|
||||
m_cacheTimeout = timeout;
|
||||
if (!Directory.Exists(pFolder))
|
||||
{
|
||||
Createj2KCacheFolder(pFolder);
|
||||
|
@ -555,6 +608,16 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
|||
return String.Format("j2kCache_{0}.cache", AssetId);
|
||||
}
|
||||
|
||||
public UUID AssetIdFromFileName(string fileName)
|
||||
{
|
||||
string rawId = fileName.Replace("j2kCache_", "").Replace(".cache", "");
|
||||
UUID asset;
|
||||
if (!UUID.TryParse(rawId, out asset))
|
||||
return UUID.Zero;
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the Cache Folder
|
||||
/// </summary>
|
||||
|
@ -619,5 +682,23 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
|||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void ScanCacheFiles(J2KDecodeDelegate decode)
|
||||
{
|
||||
DirectoryInfo dir = new DirectoryInfo(m_cacheDecodeFolder);
|
||||
FileInfo[] files = dir.GetFiles("j2kCache_*.cache");
|
||||
|
||||
foreach (FileInfo f in files)
|
||||
{
|
||||
TimeSpan fileAge = DateTime.Now - f.CreationTime;
|
||||
|
||||
if (m_cacheTimeout != 0 && fileAge >= TimeSpan.FromMinutes(m_cacheTimeout))
|
||||
{
|
||||
File.Delete(f.Name);
|
||||
decode(AssetIdFromFileName(f.Name));
|
||||
System.Threading.Thread.Sleep(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/*
|
||||
Copyright (c) Contributors, http://osflotsam.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 Flotsam 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. */
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Uncomment to make asset Get requests for existing
|
||||
// #define WAIT_ON_INPROGRESS_REQUESTS
|
||||
|
|
|
@ -45,6 +45,7 @@ using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver;
|
|||
using OpenSim.Region.CoreModules.World.Serialiser;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenSim.Tests.Common;
|
||||
using OpenSim.Tests.Common.Mock;
|
||||
using OpenSim.Tests.Common.Setup;
|
||||
|
@ -102,18 +103,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
|||
Monitor.Wait(this, 60000);
|
||||
}
|
||||
|
||||
/*
|
||||
cm.UserAdminService.AddUser(userFirstName, userLastName, string.Empty, string.Empty, 1000, 1000, userId);
|
||||
CachedUserInfo userInfo = cm.UserProfileCacheService.GetUserDetails(userId, InventoryReceived);
|
||||
userInfo.FetchInventory();
|
||||
for (int i = 0 ; i < 50 ; i++)
|
||||
{
|
||||
if (userInfo.HasReceivedInventory == true)
|
||||
break;
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
Assert.That(userInfo.HasReceivedInventory, Is.True, "FetchInventory timed out (10 seconds)");
|
||||
*/
|
||||
Console.WriteLine("here");
|
||||
|
||||
// Create asset
|
||||
SceneObjectGroup object1;
|
||||
|
@ -148,7 +138,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
|||
item1.AssetID = asset1.FullID;
|
||||
item1.ID = item1Id;
|
||||
//userInfo.RootFolder.FindFolderByPath("Objects").ID;
|
||||
InventoryFolderBase objsFolder = scene.InventoryService.GetFolderForType(userId, AssetType.Object);
|
||||
//InventoryFolderBase objsFolder = scene.InventoryService.GetFolderForType(userId, AssetType.Object);
|
||||
Console.WriteLine("here2");
|
||||
IInventoryService inventoryService = scene.InventoryService;
|
||||
InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
|
||||
InventoryCollection rootContents = inventoryService.GetFolderContent(userId, rootFolder.ID);
|
||||
InventoryFolderBase objsFolder = null;
|
||||
foreach (InventoryFolderBase folder in rootContents.Folders)
|
||||
if (folder.Name == "Objects")
|
||||
objsFolder = folder;
|
||||
item1.Folder = objsFolder.ID;
|
||||
scene.AddInventoryItem(userId, item1);
|
||||
|
||||
|
|
|
@ -484,6 +484,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
|||
GetParams(partsDelimiter, ref nextLine, 11, ref points);
|
||||
graph.FillPolygon(myBrush, points);
|
||||
}
|
||||
else if (nextLine.StartsWith("Polygon"))
|
||||
{
|
||||
PointF[] points = null;
|
||||
GetParams(partsDelimiter, ref nextLine, 7, ref points);
|
||||
graph.DrawPolygon(drawPen, points);
|
||||
}
|
||||
else if (nextLine.StartsWith("Ellipse"))
|
||||
{
|
||||
float x = 0;
|
||||
|
|
|
@ -88,13 +88,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
|||
}
|
||||
|
||||
// If not, go get them and place them in the cache
|
||||
Dictionary<AssetType, InventoryFolderBase> folders = m_Connector.GetSystemFolders(presence.UUID);
|
||||
Dictionary<AssetType, InventoryFolderBase> folders = CacheSystemFolders(presence.UUID);
|
||||
m_log.DebugFormat("[INVENTORY CACHE]: OnMakeRootAgent in {0}, fetched system folders for {1} {2}: count {3}",
|
||||
presence.Scene.RegionInfo.RegionName, presence.Firstname, presence.Lastname, folders.Count);
|
||||
|
||||
if (folders.Count > 0)
|
||||
lock (m_InventoryCache)
|
||||
m_InventoryCache.Add(presence.UUID, folders);
|
||||
}
|
||||
|
||||
void OnClientClosed(UUID clientID, Scene scene)
|
||||
|
@ -113,26 +109,64 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
|||
}
|
||||
}
|
||||
|
||||
// Drop system folders
|
||||
lock (m_InventoryCache)
|
||||
if (m_InventoryCache.ContainsKey(clientID))
|
||||
{
|
||||
m_log.DebugFormat("[INVENTORY CACHE]: OnClientClosed in {0}, user {1} out of sim. Dropping system folders",
|
||||
scene.RegionInfo.RegionName, clientID);
|
||||
|
||||
m_InventoryCache.Remove(clientID);
|
||||
}
|
||||
m_log.DebugFormat(
|
||||
"[INVENTORY CACHE]: OnClientClosed in {0}, user {1} out of sim. Dropping system folders",
|
||||
scene.RegionInfo.RegionName, clientID);
|
||||
DropCachedSystemFolders(clientID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cache a user's 'system' folders.
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <returns>Folders cached</returns>
|
||||
protected Dictionary<AssetType, InventoryFolderBase> CacheSystemFolders(UUID userID)
|
||||
{
|
||||
// If not, go get them and place them in the cache
|
||||
Dictionary<AssetType, InventoryFolderBase> folders = m_Connector.GetSystemFolders(userID);
|
||||
|
||||
if (folders.Count > 0)
|
||||
lock (m_InventoryCache)
|
||||
m_InventoryCache.Add(userID, folders);
|
||||
|
||||
return folders;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Drop a user's cached 'system' folders
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
protected void DropCachedSystemFolders(UUID userID)
|
||||
{
|
||||
// Drop system folders
|
||||
lock (m_InventoryCache)
|
||||
if (m_InventoryCache.ContainsKey(userID))
|
||||
m_InventoryCache.Remove(userID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the system folder for a particular asset type
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
|
||||
{
|
||||
Dictionary<AssetType, InventoryFolderBase> folders = null;
|
||||
|
||||
lock (m_InventoryCache)
|
||||
{
|
||||
m_InventoryCache.TryGetValue(userID, out folders);
|
||||
|
||||
// In some situations (such as non-secured standalones), system folders can be requested without
|
||||
// the user being logged in. So we need to try caching them here if we don't already have them.
|
||||
if (null == folders)
|
||||
CacheSystemFolders(userID);
|
||||
|
||||
m_InventoryCache.TryGetValue(userID, out folders);
|
||||
}
|
||||
|
||||
if ((folders != null) && folders.ContainsKey(type))
|
||||
{
|
||||
return folders[type];
|
||||
|
|
|
@ -535,7 +535,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
|
||||
UUID newFolderId = UUID.Random();
|
||||
InventoryFolderBase newFolder = new InventoryFolderBase(newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version);
|
||||
InventoryFolderBase newFolder
|
||||
= new InventoryFolderBase(
|
||||
newFolderId, folder.Name, recipientId, folder.Type, recipientParentFolderId, folder.Version);
|
||||
InventoryService.AddFolder(newFolder);
|
||||
|
||||
// Give all the subfolders
|
||||
|
|
|
@ -472,8 +472,8 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="fetchItems"></param>
|
||||
/// <param name="sortOrder"></param>
|
||||
/// <returns>null if the inventory look up failed</returns>
|
||||
public List<InventoryItemBase> HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
||||
bool fetchFolders, bool fetchItems, int sortOrder)
|
||||
public InventoryCollection HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
||||
bool fetchFolders, bool fetchItems, int sortOrder, out int version)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
||||
|
@ -487,11 +487,31 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
InventoryFolderImpl fold;
|
||||
if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null)
|
||||
{
|
||||
return fold.RequestListOfItems();
|
||||
version = 0;
|
||||
InventoryCollection ret = new InventoryCollection();
|
||||
ret.Folders = new List<InventoryFolderBase>();
|
||||
ret.Items = fold.RequestListOfItems();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
InventoryCollection contents = InventoryService.GetFolderContent(agentID, folderID);
|
||||
return contents.Items;
|
||||
|
||||
if (folderID != UUID.Zero)
|
||||
{
|
||||
InventoryFolderBase containingFolder = new InventoryFolderBase();
|
||||
containingFolder.ID = folderID;
|
||||
containingFolder.Owner = agentID;
|
||||
containingFolder = InventoryService.GetFolder(containingFolder);
|
||||
version = containingFolder.Version;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Lost itemsm don't really need a version
|
||||
version = 1;
|
||||
}
|
||||
|
||||
return contents;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -852,6 +852,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
return drawList;
|
||||
}
|
||||
|
||||
public string osDrawPolygon(string drawList, LSL_List x, LSL_List y)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.None, "osDrawFilledPolygon");
|
||||
|
||||
m_host.AddScriptLPS(1);
|
||||
|
||||
if (x.Length != y.Length || x.Length < 3)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
drawList += "Polygon " + x.GetLSLStringItem(0) + "," + y.GetLSLStringItem(0);
|
||||
for (int i = 1; i < x.Length; i++)
|
||||
{
|
||||
drawList += "," + x.GetLSLStringItem(i) + "," + y.GetLSLStringItem(i);
|
||||
}
|
||||
drawList += "; ";
|
||||
return drawList;
|
||||
}
|
||||
|
||||
public string osSetFontSize(string drawList, int fontSize)
|
||||
{
|
||||
CheckThreatLevel(ThreatLevel.None, "osSetFontSize");
|
||||
|
|
|
@ -97,6 +97,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
|||
string osDrawEllipse(string drawList, int width, int height);
|
||||
string osDrawRectangle(string drawList, int width, int height);
|
||||
string osDrawFilledRectangle(string drawList, int width, int height);
|
||||
string osDrawPolygon(string drawList, LSL_List x, LSL_List y);
|
||||
string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y);
|
||||
string osSetFontSize(string drawList, int fontSize);
|
||||
string osSetPenSize(string drawList, int penSize);
|
||||
|
|
|
@ -267,6 +267,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
|||
return m_OSSL_Functions.osDrawFilledRectangle(drawList, width, height);
|
||||
}
|
||||
|
||||
public string osDrawPolygon(string drawList, LSL_List x, LSL_List y)
|
||||
{
|
||||
return m_OSSL_Functions.osDrawPolygon(drawList, x, y);
|
||||
}
|
||||
|
||||
public string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y)
|
||||
{
|
||||
return m_OSSL_Functions.osDrawFilledPolygon(drawList, x, y);
|
||||
|
|
|
@ -110,12 +110,13 @@ namespace OpenSim.Server.Handlers.Neighbour
|
|||
httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
return result;
|
||||
}
|
||||
if (!m_AuthenticationService.VerifyKey(regionID, authToken))
|
||||
{
|
||||
m_log.InfoFormat("[RegionPostHandler]: Authentication failed for neighbour message {0}", path);
|
||||
httpResponse.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return result;
|
||||
}
|
||||
// TODO: Rethink this
|
||||
//if (!m_AuthenticationService.VerifyKey(regionID, authToken))
|
||||
//{
|
||||
// m_log.InfoFormat("[RegionPostHandler]: Authentication failed for neighbour message {0}", path);
|
||||
// httpResponse.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
// return result;
|
||||
//}
|
||||
m_log.DebugFormat("[RegionPostHandler]: Authentication succeeded for {0}", regionID);
|
||||
}
|
||||
|
||||
|
|
|
@ -109,12 +109,13 @@ namespace OpenSim.Server.Handlers.Simulation
|
|||
httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||
return result;
|
||||
}
|
||||
if (!m_AuthenticationService.VerifyKey(agentID, authToken))
|
||||
{
|
||||
m_log.InfoFormat("[AgentPostHandler]: Authentication failed for agent message {0}", path);
|
||||
httpResponse.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return result;
|
||||
}
|
||||
// TODO: Rethink this
|
||||
//if (!m_AuthenticationService.VerifyKey(agentID, authToken))
|
||||
//{
|
||||
// m_log.InfoFormat("[AgentPostHandler]: Authentication failed for agent message {0}", path);
|
||||
// httpResponse.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
// return result;
|
||||
//}
|
||||
m_log.DebugFormat("[AgentPostHandler]: Authentication succeeded for {0}", agentID);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,312 +0,0 @@
|
|||
/*
|
||||
* 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 Nini.Config;
|
||||
using log4net;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data;
|
||||
using OpenSim.Services.Base;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Services.AuthenticationService
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple authentication service implementation dealing only with users.
|
||||
/// It uses the user DB directly to access user information.
|
||||
/// It takes two config vars:
|
||||
/// - Authenticate = {true|false} : to do or not to do authentication
|
||||
/// - Authority = string like "osgrid.org" : this identity authority
|
||||
/// that will be called back for identity verification
|
||||
/// </summary>
|
||||
public class HGAuthenticationService : ServiceBase, IAuthenticationService
|
||||
{
|
||||
private static readonly ILog m_log
|
||||
= LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected IUserDataPlugin m_Database;
|
||||
protected string m_AuthorityURL;
|
||||
protected bool m_PerformAuthentication;
|
||||
protected Dictionary<UUID, List<string>> m_UserKeys = new Dictionary<UUID, List<string>>();
|
||||
|
||||
|
||||
public HGAuthenticationService(IConfigSource config) : base(config)
|
||||
{
|
||||
string dllName = String.Empty;
|
||||
string connString = String.Empty;
|
||||
|
||||
//
|
||||
// Try reading the [DatabaseService] section first, if it exists
|
||||
//
|
||||
IConfig dbConfig = config.Configs["DatabaseService"];
|
||||
if (dbConfig != null)
|
||||
{
|
||||
dllName = dbConfig.GetString("StorageProvider", String.Empty);
|
||||
connString = dbConfig.GetString("ConnectionString", String.Empty);
|
||||
}
|
||||
|
||||
//
|
||||
// Try reading the more specific [InventoryService] section, if it exists
|
||||
//
|
||||
IConfig authConfig = config.Configs["AuthenticationService"];
|
||||
if (authConfig != null)
|
||||
{
|
||||
dllName = authConfig.GetString("StorageProvider", dllName);
|
||||
connString = authConfig.GetString("ConnectionString", connString);
|
||||
|
||||
m_PerformAuthentication = authConfig.GetBoolean("Authenticate", true);
|
||||
m_AuthorityURL = "http://" + authConfig.GetString("Authority", "localhost");
|
||||
if (!m_AuthorityURL.EndsWith("/"))
|
||||
m_AuthorityURL += "/";
|
||||
}
|
||||
|
||||
//
|
||||
// We tried, but this doesn't exist. We can't proceed.
|
||||
//
|
||||
if (dllName.Equals(String.Empty))
|
||||
throw new Exception("No InventoryService configuration");
|
||||
|
||||
m_Database = LoadPlugin<IUserDataPlugin>(dllName);
|
||||
if (m_Database == null)
|
||||
throw new Exception("Could not find a storage interface in the given module");
|
||||
|
||||
m_Database.Initialise(connString);
|
||||
}
|
||||
|
||||
public UUID AuthenticateKey(UUID principalID, string key)
|
||||
{
|
||||
bool writeAgentData = false;
|
||||
|
||||
UserAgentData agent = m_Database.GetAgentByUUID(principalID);
|
||||
if (agent == null)
|
||||
{
|
||||
agent = new UserAgentData();
|
||||
agent.ProfileID = principalID;
|
||||
agent.SessionID = UUID.Random();
|
||||
agent.SecureSessionID = UUID.Random();
|
||||
agent.AgentIP = "127.0.0.1";
|
||||
agent.AgentPort = 0;
|
||||
agent.AgentOnline = false;
|
||||
|
||||
writeAgentData = true;
|
||||
}
|
||||
|
||||
if (!m_PerformAuthentication)
|
||||
{
|
||||
if (writeAgentData)
|
||||
m_Database.AddNewUserAgent(agent);
|
||||
return agent.SessionID;
|
||||
}
|
||||
|
||||
if (!VerifyKey(principalID, key))
|
||||
return UUID.Zero;
|
||||
|
||||
if (writeAgentData)
|
||||
m_Database.AddNewUserAgent(agent);
|
||||
|
||||
return agent.SessionID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This implementation only authenticates users.
|
||||
/// </summary>
|
||||
/// <param name="principalID"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
public UUID AuthenticatePassword(UUID principalID, string password)
|
||||
{
|
||||
bool writeAgentData = false;
|
||||
|
||||
UserAgentData agent = m_Database.GetAgentByUUID(principalID);
|
||||
if (agent == null)
|
||||
{
|
||||
agent = new UserAgentData();
|
||||
agent.ProfileID = principalID;
|
||||
agent.SessionID = UUID.Random();
|
||||
agent.SecureSessionID = UUID.Random();
|
||||
agent.AgentIP = "127.0.0.1";
|
||||
agent.AgentPort = 0;
|
||||
agent.AgentOnline = false;
|
||||
|
||||
writeAgentData = true;
|
||||
}
|
||||
|
||||
if (!m_PerformAuthentication)
|
||||
{
|
||||
if (writeAgentData)
|
||||
m_Database.AddNewUserAgent(agent);
|
||||
return agent.SessionID;
|
||||
}
|
||||
|
||||
UserProfileData profile = m_Database.GetUserByUUID(principalID);
|
||||
bool passwordSuccess = false;
|
||||
m_log.InfoFormat("[AUTH]: Authenticating {0} {1} ({2})", profile.FirstName, profile.SurName, profile.ID);
|
||||
|
||||
// we do this to get our hash in a form that the server password code can consume
|
||||
// when the web-login-form submits the password in the clear (supposed to be over SSL!)
|
||||
if (!password.StartsWith("$1$"))
|
||||
password = "$1$" + Util.Md5Hash(password);
|
||||
|
||||
password = password.Remove(0, 3); //remove $1$
|
||||
|
||||
string s = Util.Md5Hash(password + ":" + profile.PasswordSalt);
|
||||
// Testing...
|
||||
//m_log.Info("[LOGIN]: SubHash:" + s + " userprofile:" + profile.passwordHash);
|
||||
//m_log.Info("[LOGIN]: userprofile:" + profile.passwordHash + " SubCT:" + password);
|
||||
|
||||
passwordSuccess = (profile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
|
||||
|| profile.PasswordHash.Equals(password, StringComparison.InvariantCulture));
|
||||
|
||||
if (!passwordSuccess)
|
||||
return UUID.Zero;
|
||||
|
||||
if (writeAgentData)
|
||||
m_Database.AddNewUserAgent(agent);
|
||||
|
||||
return agent.SessionID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This generates authorization keys in the form
|
||||
/// http://authority/uuid
|
||||
/// after verifying that the caller is, indeed, authorized to request a key
|
||||
/// </summary>
|
||||
/// <param name="userID">The principal ID requesting the new key</param>
|
||||
/// <param name="authToken">The original authorization token for that principal, obtained during login</param>
|
||||
/// <returns></returns>
|
||||
public string GetKey(UUID principalID, string authToken)
|
||||
{
|
||||
UserProfileData profile = m_Database.GetUserByUUID(principalID);
|
||||
string newKey = string.Empty;
|
||||
|
||||
if (profile != null)
|
||||
{
|
||||
m_log.DebugFormat("[AUTH]: stored auth token is {0}. Given token is {1}", profile.WebLoginKey.ToString(), authToken);
|
||||
// I'm overloading webloginkey for this, so that no changes are needed in the DB
|
||||
// The uses of webloginkey are fairly mutually exclusive
|
||||
if (profile.WebLoginKey.ToString().Equals(authToken))
|
||||
{
|
||||
newKey = UUID.Random().ToString();
|
||||
List<string> keys;
|
||||
lock (m_UserKeys)
|
||||
{
|
||||
if (m_UserKeys.ContainsKey(principalID))
|
||||
{
|
||||
keys = m_UserKeys[principalID];
|
||||
}
|
||||
else
|
||||
{
|
||||
keys = new List<string>();
|
||||
m_UserKeys.Add(principalID, keys);
|
||||
}
|
||||
keys.Add(newKey);
|
||||
}
|
||||
m_log.InfoFormat("[AUTH]: Successfully generated new auth key for {0}", principalID);
|
||||
}
|
||||
else
|
||||
m_log.Warn("[AUTH]: Unauthorized key generation request. Denying new key.");
|
||||
}
|
||||
else
|
||||
m_log.Warn("[AUTH]: Principal not found.");
|
||||
|
||||
return m_AuthorityURL + newKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This verifies the uuid portion of the key given out by GenerateKey
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public bool VerifyKey(UUID userID, string key)
|
||||
{
|
||||
lock (m_UserKeys)
|
||||
{
|
||||
if (m_UserKeys.ContainsKey(userID))
|
||||
{
|
||||
List<string> keys = m_UserKeys[userID];
|
||||
if (keys.Contains(key))
|
||||
{
|
||||
// Keys are one-time only, so remove it
|
||||
keys.Remove(key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public UUID CreateUserSession(UUID userID, UUID oldSessionID)
|
||||
{
|
||||
UserAgentData agent = m_Database.GetAgentByUUID(userID);
|
||||
|
||||
if (agent == null)
|
||||
return UUID.Zero;
|
||||
|
||||
agent.SessionID = UUID.Random();
|
||||
|
||||
m_Database.AddNewUserAgent(agent);
|
||||
return agent.SessionID;
|
||||
}
|
||||
|
||||
public bool VerifyUserSession(UUID userID, UUID sessionID)
|
||||
{
|
||||
UserProfileData userProfile = m_Database.GetUserByUUID(userID);
|
||||
|
||||
if (userProfile != null && userProfile.CurrentAgent != null)
|
||||
{
|
||||
m_log.DebugFormat("[AUTH]: Verifying session {0} for {1}; current session {2}", sessionID, userID, userProfile.CurrentAgent.SessionID);
|
||||
if (userProfile.CurrentAgent.SessionID == sessionID)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DestroyUserSession(UUID userID, UUID sessionID)
|
||||
{
|
||||
if (!VerifyUserSession(userID, sessionID))
|
||||
return false;
|
||||
|
||||
UserAgentData agent = m_Database.GetAgentByUUID(userID);
|
||||
if (agent == null)
|
||||
return false;
|
||||
|
||||
agent.SessionID = UUID.Zero;
|
||||
m_Database.AddNewUserAgent(agent);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,57 +38,89 @@ namespace OpenSim.Services.Interfaces
|
|||
//
|
||||
public interface IAuthenticationService
|
||||
{
|
||||
//////////////////////////////////////////////////
|
||||
// Web login key portion
|
||||
//////////////////////////////////////////////////////
|
||||
// PKI Zone!
|
||||
//
|
||||
// HG2 authentication works by using a cryptographic
|
||||
// exchange.
|
||||
// This method must provide a public key, the other
|
||||
// crypto methods must understand hoow to deal with
|
||||
// messages encrypted to it.
|
||||
//
|
||||
// If the public key is of zero length, you will
|
||||
// get NO encryption and NO security.
|
||||
//
|
||||
// For non-HG installations, this is not relevant
|
||||
//
|
||||
// Implementors who are not using PKI can treat the
|
||||
// cyphertext as a string and provide a zero-length
|
||||
// key. Encryptionless implementations will not
|
||||
// interoperate with implementations using encryption.
|
||||
// If one side uses encryption, both must do so.
|
||||
//
|
||||
byte[] GetPublicKey();
|
||||
|
||||
// Get a service key given that principal's
|
||||
// authentication token (master key).
|
||||
//////////////////////////////////////////////////////
|
||||
// Authentication
|
||||
//
|
||||
string GetKey(UUID principalID, string authToken);
|
||||
// These methods will return a token, which can be used to access
|
||||
// various services.
|
||||
//
|
||||
// The encrypted versions take the received cyphertext and
|
||||
// the public key of the peer, which the connector must have
|
||||
// obtained using a remote GetPublicKey call.
|
||||
//
|
||||
string AuthenticatePassword(UUID principalID, string password);
|
||||
byte[] AuthenticatePasswordEncrypted(byte[] cyphertext, byte[] key);
|
||||
|
||||
// Verify that a principal key is valid
|
||||
//
|
||||
bool VerifyKey(UUID principalID, string key);
|
||||
string AuthenticateWebkey(UUID principalID, string webkey);
|
||||
byte[] AuthenticateWebkeyEncrypted(byte[] cyphertext, byte[] key);
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// Password auth portion
|
||||
//////////////////////////////////////////////////////
|
||||
// Verification
|
||||
//
|
||||
// Allows to verify the authenticity of a token
|
||||
//
|
||||
// Tokens expire after 30 minutes and can be refreshed by
|
||||
// re-verifying.
|
||||
//
|
||||
// If encrypted authentication was used, encrypted verification
|
||||
// must be used to refresh. Unencrypted verification is still
|
||||
// performed, but doesn't refresh token lifetime.
|
||||
//
|
||||
bool Verify(UUID principalID, string token);
|
||||
bool VerifyEncrypted(byte[] cyphertext, byte[] key);
|
||||
|
||||
// Here's how thos works, and why.
|
||||
//////////////////////////////////////////////////////
|
||||
// Teardown
|
||||
//
|
||||
// The authentication methods will return the existing session,
|
||||
// or UUID.Zero if authentication failed. If there is no session,
|
||||
// they will create one.
|
||||
// The CreateUserSession method will unconditionally create a session
|
||||
// and invalidate the prior session.
|
||||
// Grid login uses this method to make sure that the session is
|
||||
// fresh and new. Other software, like management applications,
|
||||
// can obtain this existing session if they have a key or password
|
||||
// for that account, this allows external apps to obtain credentials
|
||||
// and use authenticating interface methods.
|
||||
// A token can be returned before the timeout. This
|
||||
// invalidates it and it can not subsequently be used
|
||||
// or refreshed.
|
||||
//
|
||||
|
||||
// Check the pricipal's password
|
||||
// Tokens created by encrypted authentication must
|
||||
// be returned by encrypted release calls;
|
||||
//
|
||||
UUID AuthenticatePassword(UUID principalID, string password);
|
||||
bool Release(UUID principalID, string token);
|
||||
bool ReleaseEncrypted(byte[] cyphertext, byte[] key);
|
||||
|
||||
// Check the principal's key
|
||||
//////////////////////////////////////////////////////
|
||||
// Grid
|
||||
//
|
||||
UUID AuthenticateKey(UUID principalID, string password);
|
||||
// We no longer need a shared secret between grid
|
||||
// servers. Anything a server requests from another
|
||||
// server is either done on behalf of a user, in which
|
||||
// case there is a token, or on behalf of a region,
|
||||
// which has a session. So, no more keys.
|
||||
// If sniffing on the local lan is an issue, admins
|
||||
// need to take approriate action (IPSec is recommended)
|
||||
// to secure inter-server traffic.
|
||||
|
||||
// Create a new session, invalidating the old ones
|
||||
//////////////////////////////////////////////////////
|
||||
// NOTE
|
||||
//
|
||||
UUID CreateUserSession(UUID principalID, UUID oldSessionID);
|
||||
|
||||
// Verify that a user session ID is valid. A session ID is
|
||||
// considered valid when a user has successfully authenticated
|
||||
// at least one time inside that session.
|
||||
//
|
||||
bool VerifyUserSession(UUID principalID, UUID sessionID);
|
||||
|
||||
// Deauthenticate user
|
||||
//
|
||||
bool DestroyUserSession(UUID principalID, UUID sessionID);
|
||||
// Session IDs are not handled here. After obtaining
|
||||
// a token, the session ID regions use can be
|
||||
// obtained from the presence service.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,8 @@ namespace OpenSim.Services.InventoryService
|
|||
// See IInventoryServices
|
||||
public virtual InventoryFolderBase GetRootFolder(UUID userID)
|
||||
{
|
||||
//m_log.DebugFormat("[INVENTORY SERVICE]: Getting root folder for {0}", userID);
|
||||
|
||||
// Retrieve the first root folder we get from the DB.
|
||||
InventoryFolderBase rootFolder = m_Database.getUserRootFolder(userID);
|
||||
if (rootFolder != null)
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Data;
|
||||
|
@ -39,7 +41,9 @@ namespace OpenSim.Tests.Common.Mock
|
|||
/// tests are single threaded.
|
||||
/// </summary>
|
||||
public class TestInventoryDataPlugin : IInventoryDataPlugin
|
||||
{
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <value>
|
||||
/// Inventory folders
|
||||
/// </value>
|
||||
|
@ -87,6 +91,8 @@ namespace OpenSim.Tests.Common.Mock
|
|||
|
||||
public InventoryFolderBase getUserRootFolder(UUID user)
|
||||
{
|
||||
m_log.DebugFormat("[MOCK INV DB]: Looking for root folder for {0}", user);
|
||||
|
||||
InventoryFolderBase folder = null;
|
||||
m_rootFolders.TryGetValue(user, out folder);
|
||||
|
||||
|
@ -124,7 +130,11 @@ namespace OpenSim.Tests.Common.Mock
|
|||
m_folders[folder.ID] = folder;
|
||||
|
||||
if (folder.ParentID == UUID.Zero)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[MOCK INV DB]: Adding root folder {0} {1} for {2}", folder.Name, folder.ID, folder.Owner);
|
||||
m_rootFolders[folder.Owner] = folder;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateInventoryFolder(InventoryFolderBase folder)
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
|
||||
</configSections>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="Neutral" />
|
||||
<bindingRedirect oldVersion="2.0.6.0" newVersion="2.4.6.0" />
|
||||
<bindingRedirect oldVersion="2.1.4.0" newVersion="2.4.6.0" />
|
||||
<bindingRedirect oldVersion="2.2.8.0" newVersion="2.4.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<log4net>
|
||||
<!-- A1 is set to be a ConsoleAppender -->
|
||||
<appender name="A1" type="log4net.Appender.ConsoleAppender">
|
||||
|
||||
<!-- A1 uses PatternLayout -->
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<!-- Print the date in ISO 8601 format -->
|
||||
<conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- Set root logger level to DEBUG and its only appender to A1 -->
|
||||
<root>
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="A1" />
|
||||
</root>
|
||||
</log4net>
|
||||
</configuration>
|
|
@ -1,33 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
|
||||
</configSections>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="Neutral" />
|
||||
<bindingRedirect oldVersion="2.0.6.0" newVersion="2.4.6.0" />
|
||||
<bindingRedirect oldVersion="2.1.4.0" newVersion="2.4.6.0" />
|
||||
<bindingRedirect oldVersion="2.2.8.0" newVersion="2.4.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<log4net>
|
||||
<!-- A1 is set to be a ConsoleAppender -->
|
||||
<appender name="A1" type="log4net.Appender.ConsoleAppender">
|
||||
|
||||
<!-- A1 uses PatternLayout -->
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<!-- Print the date in ISO 8601 format -->
|
||||
<conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- Set root logger level to DEBUG and its only appender to A1 -->
|
||||
<root>
|
||||
<level value="Info" />
|
||||
<appender-ref ref="A1" />
|
||||
</root>
|
||||
</log4net>
|
||||
</configuration>
|
|
@ -1,33 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
|
||||
</configSections>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="Neutral" />
|
||||
<bindingRedirect oldVersion="2.0.6.0" newVersion="2.4.6.0" />
|
||||
<bindingRedirect oldVersion="2.1.4.0" newVersion="2.4.6.0" />
|
||||
<bindingRedirect oldVersion="2.2.8.0" newVersion="2.4.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<log4net>
|
||||
<!-- A1 is set to be a ConsoleAppender -->
|
||||
<appender name="A1" type="log4net.Appender.ConsoleAppender">
|
||||
|
||||
<!-- A1 uses PatternLayout -->
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<!-- Print the date in ISO 8601 format -->
|
||||
<conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- Set root logger level to DEBUG and its only appender to A1 -->
|
||||
<root>
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="A1" />
|
||||
</root>
|
||||
</log4net>
|
||||
</configuration>
|
|
@ -1,33 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
|
||||
</configSections>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="Neutral" />
|
||||
<bindingRedirect oldVersion="2.0.6.0" newVersion="2.4.6.0" />
|
||||
<bindingRedirect oldVersion="2.1.4.0" newVersion="2.4.6.0" />
|
||||
<bindingRedirect oldVersion="2.2.8.0" newVersion="2.4.6.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<log4net>
|
||||
<!-- A1 is set to be a ConsoleAppender -->
|
||||
<appender name="A1" type="log4net.Appender.ConsoleAppender">
|
||||
|
||||
<!-- A1 uses PatternLayout -->
|
||||
<layout type="log4net.Layout.PatternLayout">
|
||||
<!-- Print the date in ISO 8601 format -->
|
||||
<conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- Set root logger level to DEBUG and its only appender to A1 -->
|
||||
<root>
|
||||
<level value="DEBUG" />
|
||||
<appender-ref ref="A1" />
|
||||
</root>
|
||||
</log4net>
|
||||
</configuration>
|
|
@ -1366,6 +1366,13 @@
|
|||
;
|
||||
;TextureDataLimit = 5
|
||||
|
||||
;; The JPEG2000 decode cache
|
||||
;; Timeout is in minutes
|
||||
|
||||
[J2KDecoder]
|
||||
;CacheDir = "./j2kDecodeCache"
|
||||
;CacheTimeout = 720
|
||||
|
||||
;;
|
||||
;; These are defaults that are overwritten below in [Architecture].
|
||||
;; These defaults allow OpenSim to work out of the box with
|
||||
|
|
Loading…
Reference in New Issue