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)
|
* lbsa71 (Tribal Media AB)
|
||||||
* Sean Dague / sdague (IBM)
|
* Sean Dague / sdague (IBM)
|
||||||
* Tedd
|
* Tedd
|
||||||
* justincc (Black Dress Technology)
|
* justincc
|
||||||
* Teravus (w3z)
|
* Teravus (w3z)
|
||||||
* Johan Berntsson (3Di)
|
* Johan Berntsson (3Di)
|
||||||
* Ckrinke (Charles Krinke)
|
* Ckrinke (Charles Krinke)
|
||||||
|
@ -29,6 +29,7 @@ people that make the day to day of OpenSim happen.
|
||||||
* nlin (3Di)
|
* nlin (3Di)
|
||||||
* Arthur Rodrigo S Valadares (IBM)
|
* Arthur Rodrigo S Valadares (IBM)
|
||||||
|
|
||||||
|
|
||||||
= Past Open Sim Developers =
|
= Past Open Sim Developers =
|
||||||
These folks are alumns of the OpenSim core group, but are now
|
These folks are alumns of the OpenSim core group, but are now
|
||||||
currently not active. Their great contributions helped get us to
|
currently not active. Their great contributions helped get us to
|
||||||
|
@ -44,6 +45,7 @@ where we are today.
|
||||||
* Darok
|
* Darok
|
||||||
* Alondria
|
* Alondria
|
||||||
|
|
||||||
|
|
||||||
= Additional OpenSim Contributors =
|
= Additional OpenSim Contributors =
|
||||||
These folks have contributed code patches to OpenSim to help make it
|
These folks have contributed code patches to OpenSim to help make it
|
||||||
what it is today.
|
what it is today.
|
||||||
|
@ -90,6 +92,7 @@ what it is today.
|
||||||
* maimedleech
|
* maimedleech
|
||||||
* Mic Bowman
|
* Mic Bowman
|
||||||
* Michelle Argus
|
* Michelle Argus
|
||||||
|
* Michael Cortez (The Flotsam Project, http://osflotsam.org/)
|
||||||
* Mike Osias (IBM)
|
* Mike Osias (IBM)
|
||||||
* Mike Pitman (IBM)
|
* Mike Pitman (IBM)
|
||||||
* mikkopa/_someone - RealXtend
|
* mikkopa/_someone - RealXtend
|
||||||
|
@ -123,8 +126,7 @@ what it is today.
|
||||||
* Zha Ewry
|
* Zha Ewry
|
||||||
|
|
||||||
|
|
||||||
|
= LSL Devs =
|
||||||
LSL Devs
|
|
||||||
|
|
||||||
* Alondria
|
* Alondria
|
||||||
* CharlieO
|
* CharlieO
|
||||||
|
@ -132,7 +134,7 @@ LSL Devs
|
||||||
* Melanie Thielker
|
* Melanie Thielker
|
||||||
|
|
||||||
|
|
||||||
Testers
|
= Testers =
|
||||||
|
|
||||||
* Ai Austin
|
* Ai Austin
|
||||||
* CharlieO (LSL)
|
* CharlieO (LSL)
|
||||||
|
@ -140,10 +142,6 @@ Testers
|
||||||
* openlifegrid.com
|
* 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:
|
This software uses components from the following developers:
|
||||||
* Sleepycat Software (Berkeley DB)
|
* Sleepycat Software (Berkeley DB)
|
||||||
* SQLite (Public Domain)
|
* SQLite (Public Domain)
|
||||||
|
@ -161,6 +159,10 @@ This software uses components from the following developers:
|
||||||
* log4net (http://logging.apache.org/log4net/)
|
* log4net (http://logging.apache.org/log4net/)
|
||||||
* GlynnTucker.Cache (http://gtcache.sourceforge.net/)
|
* 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:
|
In addition, we would like to thank:
|
||||||
* The Mono Project
|
* The Mono Project
|
||||||
* The NANT Developers
|
* The NANT Developers
|
||||||
|
|
|
@ -139,15 +139,8 @@ namespace OpenSim.Client.Linden
|
||||||
return m_regionsConnector.RequestNeighbourInfo(homeRegionId);
|
return m_regionsConnector.RequestNeighbourInfo(homeRegionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
protected override bool PrepareLoginToRegion(
|
||||||
/// Prepare a login to the given region. This involves both telling the region to expect a connection
|
RegionInfo regionInfo, UserProfileData user, LoginResponse response, IPEndPoint remoteClient)
|
||||||
/// 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)
|
|
||||||
{
|
{
|
||||||
IPEndPoint endPoint = regionInfo.ExternalEndPoint;
|
IPEndPoint endPoint = regionInfo.ExternalEndPoint;
|
||||||
response.SimAddress = endPoint.Address.ToString();
|
response.SimAddress = endPoint.Address.ToString();
|
||||||
|
@ -204,7 +197,8 @@ namespace OpenSim.Client.Linden
|
||||||
agent.Appearance = m_userManager.GetUserAppearance(user.ID);
|
agent.Appearance = m_userManager.GetUserAppearance(user.ID);
|
||||||
if (agent.Appearance == null)
|
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);
|
agent.Appearance = new AvatarAppearance(agent.AgentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +237,8 @@ namespace OpenSim.Client.Linden
|
||||||
return;
|
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,
|
public delegate void TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
|
||||||
bool isScriptRunning, byte[] data);
|
bool isScriptRunning, byte[] data);
|
||||||
|
|
||||||
public delegate List<InventoryItemBase> FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
||||||
bool fetchFolders, bool fetchItems, int sortOrder);
|
bool fetchFolders, bool fetchItems, int sortOrder, out int version);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
|
/// 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_requestTexture = "0003/";
|
||||||
private static readonly string m_notecardUpdatePath = "0004/";
|
private static readonly string m_notecardUpdatePath = "0004/";
|
||||||
private static readonly string m_notecardTaskUpdatePath = "0005/";
|
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 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.
|
// 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
|
// As of RC 1.22.9 of the Linden client this is
|
||||||
// supported
|
// 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
|
// 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
|
// 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.owner_id = invFetch.owner_id;
|
||||||
contents.folder_id = invFetch.folder_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);
|
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)
|
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));
|
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.
|
contents.descendents = contents.items.Array.Count + contents.categories.Array.Count;
|
||||||
// If we don't send back the response,
|
contents.version = version;
|
||||||
// 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;
|
|
||||||
return reply;
|
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>
|
/// <summary>
|
||||||
/// Convert an internal inventory item object into an LLSD object.
|
/// Convert an internal inventory item object into an LLSD object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -529,15 +530,29 @@ namespace OpenSim.Framework.Capabilities
|
||||||
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid;
|
||||||
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
|
llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions;
|
||||||
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
|
llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions;
|
||||||
llsdItem.permissions.group_id = UUID.Zero;
|
llsdItem.permissions.group_id = invItem.GroupID;
|
||||||
llsdItem.permissions.group_mask = 0;
|
llsdItem.permissions.group_mask = (int)invItem.GroupPermissions;
|
||||||
llsdItem.permissions.is_owner_group = false;
|
llsdItem.permissions.is_owner_group = invItem.GroupOwned;
|
||||||
llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions;
|
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.permissions.owner_mask = (int)invItem.CurrentPermissions;
|
||||||
llsdItem.sale_info = new LLSDSaleInfo();
|
llsdItem.sale_info = new LLSDSaleInfo();
|
||||||
llsdItem.sale_info.sale_price = 10;
|
llsdItem.sale_info.sale_price = invItem.SalePrice;
|
||||||
llsdItem.sale_info.sale_type = "not";
|
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;
|
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 UUID agent_id;
|
||||||
public int descendents;
|
public int descendents;
|
||||||
public UUID folder_id;
|
public UUID folder_id;
|
||||||
|
public OSDArray categories = new OSDArray();
|
||||||
public OSDArray items = new OSDArray();
|
public OSDArray items = new OSDArray();
|
||||||
public UUID owner_id;
|
public UUID owner_id;
|
||||||
public int version;
|
public int version;
|
||||||
|
|
|
@ -1063,7 +1063,18 @@ namespace OpenSim.Framework.Communications.Services
|
||||||
protected abstract RegionInfo RequestClosestRegion(string region);
|
protected abstract RegionInfo RequestClosestRegion(string region);
|
||||||
protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle);
|
protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle);
|
||||||
protected abstract RegionInfo GetRegionInfo(UUID homeRegionId);
|
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>
|
/// <summary>
|
||||||
/// Add active gestures of the user to the login response.
|
/// Add active gestures of the user to the login response.
|
||||||
|
|
|
@ -30,7 +30,7 @@ using OpenMetaverse;
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A Class for folders which contain users inventory
|
/// User inventory folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class InventoryFolderBase : InventoryNodeBase
|
public class InventoryFolderBase : InventoryNodeBase
|
||||||
{
|
{
|
||||||
|
|
|
@ -94,6 +94,7 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
|
|
||||||
Stream requestStream = request.GetRequestStream();
|
Stream requestStream = request.GetRequestStream();
|
||||||
requestStream.Write(buffer.ToArray(), 0, length);
|
requestStream.Write(buffer.ToArray(), 0, length);
|
||||||
|
requestStream.Close();
|
||||||
TResponse deserial = default(TResponse);
|
TResponse deserial = default(TResponse);
|
||||||
using (WebResponse resp = request.GetResponse())
|
using (WebResponse resp = request.GetResponse())
|
||||||
{
|
{
|
||||||
|
@ -101,7 +102,6 @@ namespace OpenSim.Framework.Servers.HttpServer
|
||||||
deserial = (TResponse)deserializer.Deserialize(resp.GetResponseStream());
|
deserial = (TResponse)deserializer.Deserialize(resp.GetResponseStream());
|
||||||
resp.Close();
|
resp.Close();
|
||||||
}
|
}
|
||||||
requestStream.Close();
|
|
||||||
return deserial;
|
return deserial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
using log4net;
|
using log4net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
@ -38,9 +39,12 @@ using OpenMetaverse.Imaging;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
{
|
{
|
||||||
|
public delegate void J2KDecodeDelegate(UUID AssetId);
|
||||||
|
|
||||||
public class J2KDecoderModule : IRegionModule, IJ2KDecoder
|
public class J2KDecoderModule : IRegionModule, IJ2KDecoder
|
||||||
{
|
{
|
||||||
#region IRegionModule Members
|
#region IRegionModule Members
|
||||||
|
@ -53,8 +57,12 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Dictionary<UUID, OpenJPEG.J2KLayerInfo[]> m_cacheddecode = new Dictionary<UUID, OpenJPEG.J2KLayerInfo[]>();
|
private readonly Dictionary<UUID, OpenJPEG.J2KLayerInfo[]> m_cacheddecode = new Dictionary<UUID, OpenJPEG.J2KLayerInfo[]>();
|
||||||
private bool OpenJpegFail = false;
|
private bool OpenJpegFail = false;
|
||||||
private readonly string CacheFolder = Util.dataDir() + "/j2kDecodeCache";
|
private string CacheFolder = Util.dataDir() + "/j2kDecodeCache";
|
||||||
private readonly J2KDecodeFileCache fCache;
|
private int CacheTimeout = 720;
|
||||||
|
private J2KDecodeFileCache fCache = null;
|
||||||
|
private Thread CleanerThread = null;
|
||||||
|
private IAssetService AssetService = null;
|
||||||
|
private Scene m_Scene = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of client methods to notify of results of decode
|
/// List of client methods to notify of results of decode
|
||||||
|
@ -63,17 +71,37 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
|
|
||||||
public J2KDecoderModule()
|
public J2KDecoderModule()
|
||||||
{
|
{
|
||||||
fCache = new J2KDecodeFileCache(CacheFolder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialise(Scene scene, IConfigSource source)
|
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);
|
scene.RegisterModuleInterface<IJ2KDecoder>(this);
|
||||||
|
|
||||||
|
if (CleanerThread == null && CacheTimeout != 0)
|
||||||
|
{
|
||||||
|
CleanerThread = new Thread(CleanCache);
|
||||||
|
CleanerThread.Name = "J2KCleanerThread";
|
||||||
|
CleanerThread.IsBackground = true;
|
||||||
|
CleanerThread.Start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
{
|
{
|
||||||
|
AssetService = m_Scene.AssetService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
|
@ -329,8 +357,9 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
// Cache Decoded layers
|
// Cache Decoded layers
|
||||||
lock (m_cacheddecode)
|
lock (m_cacheddecode)
|
||||||
{
|
{
|
||||||
if (!m_cacheddecode.ContainsKey(AssetId))
|
if (m_cacheddecode.ContainsKey(AssetId))
|
||||||
m_cacheddecode.Add(AssetId, layers);
|
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
|
public class J2KDecodeFileCache
|
||||||
{
|
{
|
||||||
private readonly string m_cacheDecodeFolder;
|
private readonly string m_cacheDecodeFolder;
|
||||||
|
private readonly int m_cacheTimeout;
|
||||||
private bool enabled = true;
|
private bool enabled = true;
|
||||||
|
|
||||||
private static readonly ILog m_log
|
private static readonly ILog m_log
|
||||||
|
@ -362,9 +414,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
/// Creates a new instance of a file cache
|
/// Creates a new instance of a file cache
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pFolder">base folder for the cache. Will be created if it doesn't exist</param>
|
/// <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_cacheDecodeFolder = pFolder;
|
||||||
|
m_cacheTimeout = timeout;
|
||||||
if (!Directory.Exists(pFolder))
|
if (!Directory.Exists(pFolder))
|
||||||
{
|
{
|
||||||
Createj2KCacheFolder(pFolder);
|
Createj2KCacheFolder(pFolder);
|
||||||
|
@ -555,6 +608,16 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
return String.Format("j2kCache_{0}.cache", AssetId);
|
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>
|
/// <summary>
|
||||||
/// Creates the Cache Folder
|
/// Creates the Cache Folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -619,5 +682,23 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender
|
||||||
enabled = false;
|
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/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* Neither the name of the Flotsam Project nor the
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
*/
|
||||||
|
|
||||||
// Uncomment to make asset Get requests for existing
|
// Uncomment to make asset Get requests for existing
|
||||||
// #define WAIT_ON_INPROGRESS_REQUESTS
|
// #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.CoreModules.World.Serialiser;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
using OpenSim.Tests.Common;
|
using OpenSim.Tests.Common;
|
||||||
using OpenSim.Tests.Common.Mock;
|
using OpenSim.Tests.Common.Mock;
|
||||||
using OpenSim.Tests.Common.Setup;
|
using OpenSim.Tests.Common.Setup;
|
||||||
|
@ -102,18 +103,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
Monitor.Wait(this, 60000);
|
Monitor.Wait(this, 60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
Console.WriteLine("here");
|
||||||
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)");
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Create asset
|
// Create asset
|
||||||
SceneObjectGroup object1;
|
SceneObjectGroup object1;
|
||||||
|
@ -148,7 +138,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests
|
||||||
item1.AssetID = asset1.FullID;
|
item1.AssetID = asset1.FullID;
|
||||||
item1.ID = item1Id;
|
item1.ID = item1Id;
|
||||||
//userInfo.RootFolder.FindFolderByPath("Objects").ID;
|
//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;
|
item1.Folder = objsFolder.ID;
|
||||||
scene.AddInventoryItem(userId, item1);
|
scene.AddInventoryItem(userId, item1);
|
||||||
|
|
||||||
|
|
|
@ -484,6 +484,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
GetParams(partsDelimiter, ref nextLine, 11, ref points);
|
GetParams(partsDelimiter, ref nextLine, 11, ref points);
|
||||||
graph.FillPolygon(myBrush, 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"))
|
else if (nextLine.StartsWith("Ellipse"))
|
||||||
{
|
{
|
||||||
float x = 0;
|
float x = 0;
|
||||||
|
|
|
@ -88,13 +88,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not, go get them and place them in the cache
|
// 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}",
|
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);
|
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)
|
void OnClientClosed(UUID clientID, Scene scene)
|
||||||
|
@ -113,26 +109,64 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop system folders
|
m_log.DebugFormat(
|
||||||
lock (m_InventoryCache)
|
"[INVENTORY CACHE]: OnClientClosed in {0}, user {1} out of sim. Dropping system folders",
|
||||||
if (m_InventoryCache.ContainsKey(clientID))
|
scene.RegionInfo.RegionName, clientID);
|
||||||
{
|
DropCachedSystemFolders(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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)
|
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
|
||||||
{
|
{
|
||||||
Dictionary<AssetType, InventoryFolderBase> folders = null;
|
Dictionary<AssetType, InventoryFolderBase> folders = null;
|
||||||
|
|
||||||
lock (m_InventoryCache)
|
lock (m_InventoryCache)
|
||||||
{
|
{
|
||||||
m_InventoryCache.TryGetValue(userID, out folders);
|
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))
|
if ((folders != null) && folders.ContainsKey(type))
|
||||||
{
|
{
|
||||||
return folders[type];
|
return folders[type];
|
||||||
|
|
|
@ -535,7 +535,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID newFolderId = UUID.Random();
|
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);
|
InventoryService.AddFolder(newFolder);
|
||||||
|
|
||||||
// Give all the subfolders
|
// Give all the subfolders
|
||||||
|
|
|
@ -472,8 +472,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="fetchItems"></param>
|
/// <param name="fetchItems"></param>
|
||||||
/// <param name="sortOrder"></param>
|
/// <param name="sortOrder"></param>
|
||||||
/// <returns>null if the inventory look up failed</returns>
|
/// <returns>null if the inventory look up failed</returns>
|
||||||
public List<InventoryItemBase> HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
public InventoryCollection HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
||||||
bool fetchFolders, bool fetchItems, int sortOrder)
|
bool fetchFolders, bool fetchItems, int sortOrder, out int version)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
// "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}",
|
||||||
|
@ -487,11 +487,31 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
InventoryFolderImpl fold;
|
InventoryFolderImpl fold;
|
||||||
if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null)
|
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);
|
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;
|
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)
|
public string osSetFontSize(string drawList, int fontSize)
|
||||||
{
|
{
|
||||||
CheckThreatLevel(ThreatLevel.None, "osSetFontSize");
|
CheckThreatLevel(ThreatLevel.None, "osSetFontSize");
|
||||||
|
|
|
@ -97,6 +97,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
|
||||||
string osDrawEllipse(string drawList, int width, int height);
|
string osDrawEllipse(string drawList, int width, int height);
|
||||||
string osDrawRectangle(string drawList, int width, int height);
|
string osDrawRectangle(string drawList, int width, int height);
|
||||||
string osDrawFilledRectangle(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 osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y);
|
||||||
string osSetFontSize(string drawList, int fontSize);
|
string osSetFontSize(string drawList, int fontSize);
|
||||||
string osSetPenSize(string drawList, int penSize);
|
string osSetPenSize(string drawList, int penSize);
|
||||||
|
|
|
@ -267,6 +267,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
|
||||||
return m_OSSL_Functions.osDrawFilledRectangle(drawList, width, height);
|
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)
|
public string osDrawFilledPolygon(string drawList, LSL_List x, LSL_List y)
|
||||||
{
|
{
|
||||||
return m_OSSL_Functions.osDrawFilledPolygon(drawList, x, y);
|
return m_OSSL_Functions.osDrawFilledPolygon(drawList, x, y);
|
||||||
|
|
|
@ -110,12 +110,13 @@ namespace OpenSim.Server.Handlers.Neighbour
|
||||||
httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
|
httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (!m_AuthenticationService.VerifyKey(regionID, authToken))
|
// 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;
|
// m_log.InfoFormat("[RegionPostHandler]: Authentication failed for neighbour message {0}", path);
|
||||||
return result;
|
// httpResponse.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
// return result;
|
||||||
|
//}
|
||||||
m_log.DebugFormat("[RegionPostHandler]: Authentication succeeded for {0}", regionID);
|
m_log.DebugFormat("[RegionPostHandler]: Authentication succeeded for {0}", regionID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,12 +109,13 @@ namespace OpenSim.Server.Handlers.Simulation
|
||||||
httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
|
httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (!m_AuthenticationService.VerifyKey(agentID, authToken))
|
// 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;
|
// m_log.InfoFormat("[AgentPostHandler]: Authentication failed for agent message {0}", path);
|
||||||
return result;
|
// httpResponse.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
// return result;
|
||||||
|
//}
|
||||||
m_log.DebugFormat("[AgentPostHandler]: Authentication succeeded for {0}", agentID);
|
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
|
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
|
string AuthenticateWebkey(UUID principalID, string webkey);
|
||||||
//
|
byte[] AuthenticateWebkeyEncrypted(byte[] cyphertext, byte[] key);
|
||||||
bool VerifyKey(UUID principalID, string 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,
|
// A token can be returned before the timeout. This
|
||||||
// or UUID.Zero if authentication failed. If there is no session,
|
// invalidates it and it can not subsequently be used
|
||||||
// they will create one.
|
// or refreshed.
|
||||||
// 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.
|
|
||||||
//
|
//
|
||||||
|
// Tokens created by encrypted authentication must
|
||||||
|
// be returned by encrypted release calls;
|
||||||
|
//
|
||||||
|
bool Release(UUID principalID, string token);
|
||||||
|
bool ReleaseEncrypted(byte[] cyphertext, byte[] key);
|
||||||
|
|
||||||
// Check the pricipal's password
|
//////////////////////////////////////////////////////
|
||||||
|
// Grid
|
||||||
//
|
//
|
||||||
UUID AuthenticatePassword(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.
|
||||||
|
|
||||||
// Check the principal's key
|
//////////////////////////////////////////////////////
|
||||||
|
// NOTE
|
||||||
//
|
//
|
||||||
UUID AuthenticateKey(UUID principalID, string password);
|
// Session IDs are not handled here. After obtaining
|
||||||
|
// a token, the session ID regions use can be
|
||||||
// Create a new session, invalidating the old ones
|
// obtained from the presence service.
|
||||||
//
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,8 @@ namespace OpenSim.Services.InventoryService
|
||||||
// See IInventoryServices
|
// See IInventoryServices
|
||||||
public virtual InventoryFolderBase GetRootFolder(UUID userID)
|
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.
|
// Retrieve the first root folder we get from the DB.
|
||||||
InventoryFolderBase rootFolder = m_Database.getUserRootFolder(userID);
|
InventoryFolderBase rootFolder = m_Database.getUserRootFolder(userID);
|
||||||
if (rootFolder != null)
|
if (rootFolder != null)
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Data;
|
using OpenSim.Data;
|
||||||
|
@ -40,6 +42,8 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TestInventoryDataPlugin : IInventoryDataPlugin
|
public class TestInventoryDataPlugin : IInventoryDataPlugin
|
||||||
{
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <value>
|
/// <value>
|
||||||
/// Inventory folders
|
/// Inventory folders
|
||||||
/// </value>
|
/// </value>
|
||||||
|
@ -87,6 +91,8 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
|
|
||||||
public InventoryFolderBase getUserRootFolder(UUID user)
|
public InventoryFolderBase getUserRootFolder(UUID user)
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("[MOCK INV DB]: Looking for root folder for {0}", user);
|
||||||
|
|
||||||
InventoryFolderBase folder = null;
|
InventoryFolderBase folder = null;
|
||||||
m_rootFolders.TryGetValue(user, out folder);
|
m_rootFolders.TryGetValue(user, out folder);
|
||||||
|
|
||||||
|
@ -124,7 +130,11 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
m_folders[folder.ID] = folder;
|
m_folders[folder.ID] = folder;
|
||||||
|
|
||||||
if (folder.ParentID == UUID.Zero)
|
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;
|
m_rootFolders[folder.Owner] = folder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateInventoryFolder(InventoryFolderBase 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
|
;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 are defaults that are overwritten below in [Architecture].
|
||||||
;; These defaults allow OpenSim to work out of the box with
|
;; These defaults allow OpenSim to work out of the box with
|
||||||
|
|
Loading…
Reference in New Issue