Merge branch 'master' into careminster-presence-refactor

avinationmerge
Melanie 2010-03-15 17:23:35 +00:00
commit d3f33acc1a
89 changed files with 13161 additions and 3963 deletions

View File

@ -164,6 +164,7 @@ 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/)
* NDesk.Options 0.2.1 (http://www.ndesk.org/Options) * NDesk.Options 0.2.1 (http://www.ndesk.org/Options)
* Json.NET 3.5 Release 6. The binary used is actually Newtonsoft.Json.Net20.dll for Mono 2.4 compatability (http://james.newtonking.com/projects/json-net.aspx)
Some plugins are based on Cable Beach Some plugins are based on Cable Beach
Cable Beach is Copyright (c) 2008 Intel Corporation Cable Beach is Copyright (c) 2008 Intel Corporation

View File

@ -1,4 +1,31 @@
using System; /*
* 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.Collections.Generic;
using System.Net; using System.Net;
using System.IO; using System.IO;

View File

@ -1,4 +1,31 @@
using System; /*
* 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.Collections.Generic;
using System.Reflection; using System.Reflection;
using log4net; using log4net;

View File

@ -203,7 +203,6 @@ namespace OpenSim.Framework.Servers.HttpServer
{ {
m_pollHandlers.Add(methodName,args); m_pollHandlers.Add(methodName,args);
pollHandlerResult = true; pollHandlerResult = true;
} }
} }
@ -211,7 +210,6 @@ namespace OpenSim.Framework.Servers.HttpServer
return AddHTTPHandler(methodName, handler); return AddHTTPHandler(methodName, handler);
return false; return false;
} }
// Note that the agent string is provided simply to differentiate // Note that the agent string is provided simply to differentiate

View File

@ -47,7 +47,7 @@ namespace OpenSim.Framework.Servers.HttpServer
bool AddAgentHandler(string agent, IHttpAgentHandler handler); bool AddAgentHandler(string agent, IHttpAgentHandler handler);
/// <summary> /// <summary>
/// Add a handler for an HTTP request /// Add a handler for an HTTP request.
/// </summary> /// </summary>
/// ///
/// This handler can actually be invoked either as /// This handler can actually be invoked either as
@ -67,6 +67,10 @@ namespace OpenSim.Framework.Servers.HttpServer
/// ///
/// http://localhost:9000/object/ /// http://localhost:9000/object/
/// ///
/// In addition, the handler invoked by the HTTP server for any request is the one when best matches the request
/// URI. So if a handler for "/myapp/" is registered and a request for "/myapp/page" is received, then
/// the "/myapp/" handler is invoked if no "/myapp/page" handler exists.
///
/// <param name="methodName"></param> /// <param name="methodName"></param>
/// <param name="handler"></param> /// <param name="handler"></param>
/// <returns> /// <returns>
@ -74,7 +78,6 @@ namespace OpenSim.Framework.Servers.HttpServer
/// </returns> /// </returns>
bool AddHTTPHandler(string methodName, GenericHTTPMethod handler); bool AddHTTPHandler(string methodName, GenericHTTPMethod handler);
bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args); bool AddPollServiceHTTPHandler(string methodName, GenericHTTPMethod handler, PollServiceEventArgs args);
/// <summary> /// <summary>

View File

@ -1,4 +1,31 @@
using System; /*
* 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.Collections.Generic;
using System.IO; using System.IO;
using System.Net; using System.Net;

View File

@ -1,4 +1,31 @@
using System; /*
* 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.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.IO; using System.IO;

View File

@ -67,6 +67,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
get { return false; } get { return false; }
} }
public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent)
{
m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject");
// If we can't take it, we can't attach it!
SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID);
if (part == null)
return;
if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
return;
// Calls attach with a Zero position
if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false))
{
m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
// Save avatar attachment information
ScenePresence presence;
if (m_scene.AvatarFactory != null && m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
{
m_log.Info(
"[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
+ ", AttachmentPoint: " + AttachmentPt);
m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
}
}
}
public bool AttachObject( public bool AttachObject(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
{ {
@ -139,11 +169,86 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
return true; return true;
} }
public UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name);
return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true);
}
public UUID RezSingleAttachmentFromInventory(
IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus)
{
SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(remoteClient, itemID, AttachmentPt);
if (updateInventoryStatus)
{
if (att == null)
{
ShowDetachInUserInventory(itemID, remoteClient);
}
SetAttachmentInventoryStatus(att, remoteClient, itemID, AttachmentPt);
}
if (null == att)
return UUID.Zero;
else
return att.UUID;
}
protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null)
{
SceneObjectGroup objatt = invAccess.RezObject(remoteClient,
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
false, false, remoteClient.AgentId, true);
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
// objatt.Name, remoteClient.Name, AttachmentPt);
if (objatt != null)
{
bool tainted = false;
if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
tainted = true;
AttachObject(
remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
//objatt.ScheduleGroupForFullUpdate();
if (tainted)
objatt.HasGroupChanged = true;
// Fire after attach, so we don't get messy perms dialogs
// 3 == AttachedRez
objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3);
// Do this last so that event listeners have access to all the effects of the attachment
m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
}
else
{
m_log.WarnFormat(
"[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
itemID, remoteClient.Name, AttachmentPt);
}
return objatt;
}
return null;
}
public UUID SetAttachmentInventoryStatus( public UUID SetAttachmentInventoryStatus(
SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{ {
m_log.DebugFormat( m_log.DebugFormat(
"[ATTACHMENTS MODULEY]: Updating inventory of {0} to show attachment of {1} (item ID {2})", "[ATTACHMENTS MODULE]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
remoteClient.Name, att.Name, itemID); remoteClient.Name, att.Name, itemID);
if (!att.IsDeleted) if (!att.IsDeleted)

View File

@ -481,7 +481,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_log.DebugFormat("[FRIENDS]: {0} offered friendship to {1}", principalID, friendID); m_log.DebugFormat("[FRIENDS]: {0} offered friendship to {1}", principalID, friendID);
// This user wants to be friends with the other user. // This user wants to be friends with the other user.
// Let's add both relations to the DB, but one of them is inactive (-1) // Let's add the relation backwards, in case the other is not online
FriendsService.StoreFriend(friendID, principalID.ToString(), 0); FriendsService.StoreFriend(friendID, principalID.ToString(), 0);
// Now let's ask the other user to be friends with this user // Now let's ask the other user to be friends with this user

View File

@ -56,6 +56,9 @@
<RegionModule id="RemotePresenceServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.RemotePresenceServicesConnector" /> <RegionModule id="RemotePresenceServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence.RemotePresenceServicesConnector" />
<RegionModule id="LocalUserAccountServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts.LocalUserAccountServicesConnector" /> <RegionModule id="LocalUserAccountServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts.LocalUserAccountServicesConnector" />
<RegionModule id="RemoteUserAccountServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts.RemoteUserAccountServicesConnector" /> <RegionModule id="RemoteUserAccountServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts.RemoteUserAccountServicesConnector" />
<RegionModule id="LocalGridUserServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.GridUser.LocalGridUserServicesConnector" />
<RegionModule id="LocalSimulationConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation.LocalSimulationConnectorModule" /> <RegionModule id="LocalSimulationConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation.LocalSimulationConnectorModule" />
<RegionModule id="RemoteSimulationConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation.RemoteSimulationConnectorModule" /> <RegionModule id="RemoteSimulationConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation.RemoteSimulationConnectorModule" />
<!-- Service connectors IN modules --> <!-- Service connectors IN modules -->

View File

@ -73,33 +73,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
IConfig userConfig = source.Configs["UserAccountService"]; IConfig userConfig = source.Configs["UserAccountService"];
if (userConfig == null) if (userConfig == null)
{ {
m_log.Error("[USER CONNECTOR]: UserAccountService missing from OpenSim.ini"); m_log.Error("[LOCAL USER ACCOUNT SERVICE CONNECTOR]: UserAccountService missing from OpenSim.ini");
return; return;
} }
string serviceDll = userConfig.GetString("LocalServiceModule", string serviceDll = userConfig.GetString("LocalServiceModule", String.Empty);
String.Empty);
if (serviceDll == String.Empty) if (serviceDll == String.Empty)
{ {
m_log.Error("[USER CONNECTOR]: No LocalServiceModule named in section UserService"); m_log.Error("[LOCAL USER ACCOUNT SERVICE CONNECTOR]: No LocalServiceModule named in section UserService");
return; return;
} }
Object[] args = new Object[] { source }; Object[] args = new Object[] { source };
m_UserService = m_UserService = ServerUtils.LoadPlugin<IUserAccountService>(serviceDll, args);
ServerUtils.LoadPlugin<IUserAccountService>(serviceDll,
args);
if (m_UserService == null) if (m_UserService == null)
{ {
m_log.Error("[USER CONNECTOR]: Can't load user account service"); m_log.ErrorFormat(
"[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll);
return; return;
} }
m_Enabled = true; m_Enabled = true;
m_Cache = new UserAccountCache(); m_Cache = new UserAccountCache();
m_log.Info("[USER CONNECTOR]: Local user connector enabled"); m_log.Info("[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Local user connector enabled");
} }
} }
} }
@ -134,6 +132,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
if (!m_Enabled) if (!m_Enabled)
return; return;
m_log.InfoFormat("[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Enabled local user accounts for region {0}", scene.RegionInfo.RegionName);
} }
#endregion #endregion
@ -142,26 +142,27 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
public UserAccount GetUserAccount(UUID scopeID, UUID userID) public UserAccount GetUserAccount(UUID scopeID, UUID userID)
{ {
UserAccount account = m_Cache.Get(userID); bool inCache = false;
if (account != null) UserAccount account = m_Cache.Get(userID, out inCache);
if (inCache)
return account; return account;
account = m_UserService.GetUserAccount(scopeID, userID); account = m_UserService.GetUserAccount(scopeID, userID);
if (account != null) m_Cache.Cache(userID, account);
m_Cache.Cache(account);
return account; return account;
} }
public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
{ {
UserAccount account = m_Cache.Get(firstName + " " + lastName); bool inCache = false;
if (account != null) UserAccount account = m_Cache.Get(firstName + " " + lastName, out inCache);
if (inCache)
return account; return account;
account = m_UserService.GetUserAccount(scopeID, firstName, lastName); account = m_UserService.GetUserAccount(scopeID, firstName, lastName);
if (account != null) if (account != null)
m_Cache.Cache(account); m_Cache.Cache(account.PrincipalID, account);
return account; return account;
} }

View File

@ -119,26 +119,27 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
public override UserAccount GetUserAccount(UUID scopeID, UUID userID) public override UserAccount GetUserAccount(UUID scopeID, UUID userID)
{ {
UserAccount account = m_Cache.Get(userID); bool inCache = false;
if (account != null) UserAccount account = m_Cache.Get(userID, out inCache);
if (inCache)
return account; return account;
account = base.GetUserAccount(scopeID, userID); account = base.GetUserAccount(scopeID, userID);
if (account != null) m_Cache.Cache(userID, account);
m_Cache.Cache(account);
return account; return account;
} }
public override UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) public override UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
{ {
UserAccount account = m_Cache.Get(firstName + " " + lastName); bool inCache = false;
if (account != null) UserAccount account = m_Cache.Get(firstName + " " + lastName, out inCache);
if (inCache)
return account; return account;
account = base.GetUserAccount(scopeID, firstName, lastName); account = base.GetUserAccount(scopeID, firstName, lastName);
if (account != null) if (account != null)
m_Cache.Cache(account); m_Cache.Cache(account.PrincipalID, account);
return account; return account;
} }

View File

@ -36,50 +36,58 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
{ {
public class UserAccountCache public class UserAccountCache
{ {
//private static readonly ILog m_log = private static readonly ILog m_log =
// LogManager.GetLogger( LogManager.GetLogger(
// MethodBase.GetCurrentMethod().DeclaringType); MethodBase.GetCurrentMethod().DeclaringType);
private ExpiringCache<UUID, UserAccount> m_UUIDCache;
private ICnmCache<UUID, UserAccount> m_UUIDCache; private ExpiringCache<string, UUID> m_NameCache;
private Dictionary<string, UUID> m_NameCache;
public UserAccountCache() public UserAccountCache()
{ {
// Warning: the size values are a bit fuzzy. What matters // Warning: the size values are a bit fuzzy. What matters
// most for this cache is the count value (128 entries). // most for this cache is the count value (128 entries).
m_UUIDCache = CnmSynchronizedCache<UUID, UserAccount>.Synchronized(new CnmMemoryCache<UUID, UserAccount>( m_UUIDCache = new ExpiringCache<UUID, UserAccount>();
128, 128*512, TimeSpan.FromMinutes(30.0))); m_NameCache = new ExpiringCache<string, UUID>(); // this one is unbound
m_NameCache = new Dictionary<string, UUID>(); // this one is unbound
} }
public void Cache(UserAccount account) public void Cache(UUID userID, UserAccount account)
{ {
m_UUIDCache.Set(account.PrincipalID, account, 512); // Cache even null accounts
m_NameCache[account.Name] = account.PrincipalID; m_UUIDCache.AddOrUpdate(userID, account, DateTime.Now + TimeSpan.FromMinutes(2.0d));
if (account != null)
m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, DateTime.Now + TimeSpan.FromMinutes(2.0d));
//m_log.DebugFormat("[USER CACHE]: cached user {0} {1}", account.FirstName, account.LastName); m_log.DebugFormat("[USER CACHE]: cached user {0}", userID);
} }
public UserAccount Get(UUID userID) public UserAccount Get(UUID userID, out bool inCache)
{ {
UserAccount account = null; UserAccount account = null;
inCache = false;
if (m_UUIDCache.TryGetValue(userID, out account)) if (m_UUIDCache.TryGetValue(userID, out account))
{ {
//m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName); //m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName);
inCache = true;
return account; return account;
} }
return null; return null;
} }
public UserAccount Get(string name) public UserAccount Get(string name, out bool inCache)
{ {
if (!m_NameCache.ContainsKey(name)) inCache = false;
if (!m_NameCache.Contains(name))
return null; return null;
UserAccount account = null; UserAccount account = null;
if (m_UUIDCache.TryGetValue(m_NameCache[name], out account)) UUID uuid = UUID.Zero;
if (m_NameCache.TryGetValue(name, out uuid))
if (m_UUIDCache.TryGetValue(uuid, out account))
{
inCache = true;
return account; return account;
}
return null; return null;
} }

View File

@ -618,7 +618,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return objectOwnerMask; return objectOwnerMask;
// Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
if (IsEstateManager(user) && m_RegionOwnerIsGod) if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
return objectOwnerMask; return objectOwnerMask;
// Admin should be able to edit anything in the sim (including admin objects) // Admin should be able to edit anything in the sim (including admin objects)

View File

@ -34,6 +34,17 @@ namespace OpenSim.Region.Framework.Interfaces
{ {
public interface IAttachmentsModule public interface IAttachmentsModule
{ {
/// <summary>
/// Attach an object to an avatar from the world.
/// </summary>
/// <param name="controllingClient"></param>
/// <param name="localID"></param>
/// <param name="attachPoint"></param>
/// <param name="rot"></param>
/// <param name="silent"></param>
void AttachObject(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent);
/// <summary> /// <summary>
/// Attach an object to an avatar. /// Attach an object to an avatar.
/// </summary> /// </summary>
@ -41,11 +52,34 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="localID"></param> /// <param name="localID"></param>
/// <param name="attachPoint"></param> /// <param name="attachPoint"></param>
/// <param name="rot"></param> /// <param name="rot"></param>
/// <param name="pos"></param> /// <param name="attachPos"></param>
/// <param name="silent"></param> /// <param name="silent"></param>
/// <returns>true if the object was successfully attached, false otherwise</returns> /// <returns>true if the object was successfully attached, false otherwise</returns>
bool AttachObject( bool AttachObject(
IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent); IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent);
/// <summary>
/// Rez an attachment from user inventory and change inventory status to match.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="AttachmentPt"></param>
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
UUID RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt);
/// <summary>
/// Rez an attachment from user inventory
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="AttachmentPt"></param>
/// <param name="updateinventoryStatus">
/// If true, we also update the user's inventory to show that the attachment is set. If false, we do not.
/// False is required so that we don't attempt to update information when a user enters a scene with the
/// attachment already correctly set up in inventory.
/// <returns>The uuid of the scene object that was attached. Null if the scene object could not be found</returns>
UUID RezSingleAttachmentFromInventory(
IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus);
/// <summary> /// <summary>
/// Update the user inventory to the attachment of an item /// Update the user inventory to the attachment of an item

View File

@ -1,4 +1,31 @@
using System; /*
* 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.Collections.Generic;
using OpenSim.Framework; using OpenSim.Framework;

View File

@ -1106,18 +1106,18 @@ namespace OpenSim.Region.Framework.Scenes
if (folder == null) if (folder == null)
return; return;
m_log.DebugFormat("[AGENT INVENTORY]: Send Inventory Folder {0} Update to {1} {2}", folder.Name, client.FirstName, client.LastName); // Fetch the folder contents
InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID); InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID);
InventoryFolderBase containingFolder = new InventoryFolderBase();
containingFolder.ID = folder.ID;
containingFolder.Owner = client.AgentId;
containingFolder = InventoryService.GetFolder(containingFolder);
if (containingFolder != null)
{
int version = containingFolder.Version;
client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, version, fetchFolders, fetchItems); // Fetch the folder itself to get its current version
} InventoryFolderBase containingFolder = new InventoryFolderBase(folder.ID, client.AgentId);
containingFolder = InventoryService.GetFolder(containingFolder);
//m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}",
// contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
if (containingFolder != null)
client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, containingFolder.Version, fetchFolders, fetchItems);
} }
/// <summary> /// <summary>
@ -1846,35 +1846,12 @@ namespace OpenSim.Region.Framework.Scenes
EventManager.TriggerOnAttach(localID, itemID, avatarID); EventManager.TriggerOnAttach(localID, itemID, avatarID);
} }
/// <summary>
/// Called when the client receives a request to rez a single attachment on to the avatar from inventory
/// (RezSingleAttachmentFromInv packet).
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="AttachmentPt"></param>
/// <returns></returns>
public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
m_log.DebugFormat("[USER INVENTORY]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name);
SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt);
if (att == null)
{
AttachmentsModule.ShowDetachInUserInventory(itemID, remoteClient);
return UUID.Zero;
}
return AttachmentsModule.SetAttachmentInventoryStatus(att, remoteClient, itemID, AttachmentPt);
}
public void RezMultipleAttachments(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, public void RezMultipleAttachments(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects)
{ {
foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
{ {
RezSingleAttachment(remoteClient, obj.ItemID, obj.AttachmentPt); AttachmentsModule.RezSingleAttachmentFromInventory(remoteClient, obj.ItemID, obj.AttachmentPt);
} }
} }

View File

@ -2365,10 +2365,10 @@ namespace OpenSim.Region.Framework.Scenes
//m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID); //m_log.DebugFormat(" >>> IncomingCreateObject(userID, itemID) <<< {0} {1}", userID, itemID);
ScenePresence sp = GetScenePresence(userID); ScenePresence sp = GetScenePresence(userID);
if (sp != null) if (sp != null && AttachmentsModule != null)
{ {
uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID); uint attPt = (uint)sp.Appearance.GetAttachpoint(itemID);
m_sceneGraph.RezSingleAttachment(sp.ControllingClient, itemID, attPt); AttachmentsModule.RezSingleAttachmentFromInventory(sp.ControllingClient, itemID, attPt);
} }
return false; return false;
@ -2670,14 +2670,16 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void SubscribeToClientAttachmentEvents(IClientAPI client) public virtual void SubscribeToClientAttachmentEvents(IClientAPI client)
{ {
client.OnRezSingleAttachmentFromInv += RezSingleAttachment;
client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments; client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachments;
client.OnObjectAttach += m_sceneGraph.AttachObject;
client.OnObjectDetach += m_sceneGraph.DetachObject; client.OnObjectDetach += m_sceneGraph.DetachObject;
if (AttachmentsModule != null) if (AttachmentsModule != null)
{
client.OnRezSingleAttachmentFromInv += AttachmentsModule.RezSingleAttachmentFromInventory;
client.OnObjectAttach += AttachmentsModule.AttachObject;
client.OnDetachAttachmentIntoInv += AttachmentsModule.ShowDetachInUserInventory; client.OnDetachAttachmentIntoInv += AttachmentsModule.ShowDetachInUserInventory;
} }
}
public virtual void SubscribeToClientTeleportEvents(IClientAPI client) public virtual void SubscribeToClientTeleportEvents(IClientAPI client)
{ {
@ -2801,7 +2803,6 @@ namespace OpenSim.Region.Framework.Scenes
client.OnRezObject -= RezObject; client.OnRezObject -= RezObject;
} }
public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client) public virtual void UnSubscribeToClientInventoryEvents(IClientAPI client)
{ {
client.OnCreateNewInventoryItem -= CreateNewInventoryItem; client.OnCreateNewInventoryItem -= CreateNewInventoryItem;
@ -2826,13 +2827,15 @@ namespace OpenSim.Region.Framework.Scenes
public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client) public virtual void UnSubscribeToClientAttachmentEvents(IClientAPI client)
{ {
client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments; client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachments;
client.OnRezSingleAttachmentFromInv -= RezSingleAttachment;
client.OnObjectAttach -= m_sceneGraph.AttachObject;
client.OnObjectDetach -= m_sceneGraph.DetachObject; client.OnObjectDetach -= m_sceneGraph.DetachObject;
if (AttachmentsModule != null) if (AttachmentsModule != null)
{
client.OnRezSingleAttachmentFromInv -= AttachmentsModule.RezSingleAttachmentFromInventory;
client.OnObjectAttach -= AttachmentsModule.AttachObject;
client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory; client.OnDetachAttachmentIntoInv -= AttachmentsModule.ShowDetachInUserInventory;
} }
}
public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client) public virtual void UnSubscribeToClientTeleportEvents(IClientAPI client)
{ {

View File

@ -510,94 +510,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Event Handling routine for Attach Object
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="objectLocalID"></param>
/// <param name="AttachmentPt"></param>
/// <param name="rot"></param>
protected internal void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent)
{
// If we can't take it, we can't attach it!
SceneObjectPart part = m_parentScene.GetSceneObjectPart(objectLocalID);
if (part == null)
return;
if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId))
return;
// Calls attach with a Zero position
if (m_parentScene.AttachmentsModule.AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false))
{
m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId);
// Save avatar attachment information
ScenePresence presence;
if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence))
{
m_log.Info(
"[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
+ ", AttachmentPoint: " + AttachmentPt);
m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
}
}
}
/// <summary>
/// Rez an attachment
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="itemID"></param>
/// <param name="AttachmentPt"></param>
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
{
IInventoryAccessModule invAccess = m_parentScene.RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null)
{
SceneObjectGroup objatt = invAccess.RezObject(remoteClient,
itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
false, false, remoteClient.AgentId, true);
// m_log.DebugFormat(
// "[SCENE GRAPH]: Retrieved single object {0} for attachment to {1} on point {2}",
// objatt.Name, remoteClient.Name, AttachmentPt);
if (objatt != null)
{
bool tainted = false;
if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint())
tainted = true;
m_parentScene.AttachmentsModule.AttachObject(
remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false);
//objatt.ScheduleGroupForFullUpdate();
if (tainted)
objatt.HasGroupChanged = true;
// Fire after attach, so we don't get messy perms dialogs
// 3 == AttachedRez
objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3);
// Do this last so that event listeners have access to all the effects of the attachment
m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId);
}
else
{
m_log.WarnFormat(
"[SCENE GRAPH]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
itemID, remoteClient.Name, AttachmentPt);
}
return objatt;
}
return null;
}
protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance)
{ {
ScenePresence newAvatar = null; ScenePresence newAvatar = null;

View File

@ -2060,6 +2060,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
m_lastColliders.Remove(localID); m_lastColliders.Remove(localID);
} }
if (m_parentGroup == null) if (m_parentGroup == null)
return; return;
if (m_parentGroup.IsDeleted) if (m_parentGroup.IsDeleted)

View File

@ -686,6 +686,7 @@ namespace OpenSim.Region.Framework.Scenes
UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid);
if (account != null)
m_userLevel = account.UserLevel; m_userLevel = account.UserLevel;
IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>(); IGroupsModule gm = m_scene.RequestModuleInterface<IGroupsModule>();
@ -3957,7 +3958,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (null == m_appearance) if (null == m_appearance)
{ {
m_log.WarnFormat("[ATTACHMENT] Appearance has not been initialized for agent {0}", UUID); m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID);
return; return;
} }
@ -3981,12 +3982,12 @@ namespace OpenSim.Region.Framework.Scenes
try try
{ {
// Rez from inventory // Rez from inventory
UUID asset = m_scene.RezSingleAttachment(ControllingClient, UUID asset
itemID, (uint)p); = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p);
m_log.InfoFormat("[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", m_log.InfoFormat(
"[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})",
p, itemID, assetID, asset); p, itemID, assetID, asset);
} }
catch (Exception e) catch (Exception e)
{ {

View File

@ -86,6 +86,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
public void TestDeleteSceneObjectAsync() public void TestDeleteSceneObjectAsync()
{ {
TestHelper.InMethod(); TestHelper.InMethod();
//log4net.Config.XmlConfigurator.Configure();
UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001"); UUID agentId = UUID.Parse("00000000-0000-0000-0000-000000000001");
@ -97,15 +98,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene);
try
{
IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId); IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId);
scene.DeRezObject(client, part.LocalId, UUID.Zero, DeRezAction.Delete, UUID.Zero); scene.DeRezObject(client, part.LocalId, UUID.Zero, DeRezAction.Delete, UUID.Zero);
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.StackTrace);
}
SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId);
Assert.That(retrievedPart, Is.Not.Null); Assert.That(retrievedPart, Is.Not.Null);

View File

@ -108,12 +108,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
private bool[] m_colliderarr = new bool[11]; private bool[] m_colliderarr = new bool[11];
private bool[] m_colliderGroundarr = new bool[11]; private bool[] m_colliderGroundarr = new bool[11];
private BulletDotNETScene m_parent_scene; private BulletDotNETScene m_parent_scene;
public int m_eventsubscription = 0; public int m_eventsubscription = 0;
// private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); private CollisionEventUpdate CollisionEventsThisFrame = null;
private int m_requestedUpdateFrequency = 0;
public BulletDotNETCharacter(string avName, BulletDotNETScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) public BulletDotNETCharacter(string avName, BulletDotNETScene parent_scene, Vector3 pos, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor)
{ {
@ -212,7 +211,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
m_mass = Mass; m_mass = Mass;
Body = new btRigidBody(m_mass, m_bodyMotionState, Shell); Body = new btRigidBody(m_mass, m_bodyMotionState, Shell);
Body.setUserPointer(new IntPtr((int)Body.Handle)); // this is used for self identification. User localID instead of body handle
Body.setUserPointer(new IntPtr((int)m_localID));
if (ClosestCastResult != null) if (ClosestCastResult != null)
ClosestCastResult.Dispose(); ClosestCastResult.Dispose();
@ -716,6 +716,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
public override void SubscribeEvents(int ms) public override void SubscribeEvents(int ms)
{ {
m_eventsubscription = ms; m_eventsubscription = ms;
m_requestedUpdateFrequency = ms;
m_parent_scene.addCollisionEventReporting(this); m_parent_scene.addCollisionEventReporting(this);
} }
@ -723,6 +724,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
{ {
m_parent_scene.remCollisionEventReporting(this); m_parent_scene.remCollisionEventReporting(this);
m_eventsubscription = 0; m_eventsubscription = 0;
m_requestedUpdateFrequency = 0;
} }
public override bool SubscribedEvents() public override bool SubscribedEvents()
@ -732,6 +734,29 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
return false; return false;
} }
public void AddCollision(uint collideWith, ContactPoint contact)
{
if (CollisionEventsThisFrame == null)
{
CollisionEventsThisFrame = new CollisionEventUpdate();
}
CollisionEventsThisFrame.addCollider(collideWith, contact);
}
public void SendCollisions()
{
if (m_eventsubscription >= m_requestedUpdateFrequency)
{
if (CollisionEventsThisFrame != null)
{
base.SendCollisionUpdate(CollisionEventsThisFrame);
}
CollisionEventsThisFrame = new CollisionEventUpdate();
m_eventsubscription = 0;
}
return;
}
internal void Dispose() internal void Dispose()
{ {
if (Body.isInWorld()) if (Body.isInWorld())

View File

@ -154,7 +154,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
private Vector3 _target_velocity; private Vector3 _target_velocity;
public int m_eventsubscription; public int m_eventsubscription;
// private CollisionEventUpdate CollisionEventsThisFrame = null; private int m_requestedUpdateFrequency = 0;
private CollisionEventUpdate CollisionEventsThisFrame = null;
public volatile bool childPrim; public volatile bool childPrim;
@ -595,6 +596,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
public override void SubscribeEvents(int ms) public override void SubscribeEvents(int ms)
{ {
m_eventsubscription = ms; m_eventsubscription = ms;
m_requestedUpdateFrequency = ms;
_parent_scene.addCollisionEventReporting(this); _parent_scene.addCollisionEventReporting(this);
} }
@ -602,6 +604,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
{ {
_parent_scene.remCollisionEventReporting(this); _parent_scene.remCollisionEventReporting(this);
m_eventsubscription = 0; m_eventsubscription = 0;
m_requestedUpdateFrequency = 0;
} }
public override bool SubscribedEvents() public override bool SubscribedEvents()
@ -611,7 +614,28 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
#endregion #endregion
public void AddCollision(uint collideWith, ContactPoint contact)
{
if (CollisionEventsThisFrame == null)
{
CollisionEventsThisFrame = new CollisionEventUpdate();
}
CollisionEventsThisFrame.addCollider(collideWith, contact);
}
public void SendCollisions()
{
if (m_eventsubscription >= m_requestedUpdateFrequency)
{
if (CollisionEventsThisFrame != null)
{
base.SendCollisionUpdate(CollisionEventsThisFrame);
}
CollisionEventsThisFrame = null;
// m_eventsubscription = 0;
}
return;
}
internal void Dispose() internal void Dispose()
{ {
@ -759,7 +783,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
{ {
if (m_taintadd) if (m_taintadd)
{ {
m_log.Debug("[PHYSICS]: TaintAdd"); // m_log.Debug("[PHYSICS]: TaintAdd");
changeadd(timestep); changeadd(timestep);
} }
@ -771,7 +795,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
SetBody(Mass); SetBody(Mass);
else else
SetBody(0); SetBody(0);
m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT"); // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT");
} }
if (prim_geom.Handle == IntPtr.Zero) if (prim_geom.Handle == IntPtr.Zero)
@ -782,31 +806,31 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
SetBody(Mass); SetBody(Mass);
else else
SetBody(0); SetBody(0);
m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT"); // m_log.Debug("[PHYSICS]: GEOM_DOESNT_EXSIT");
} }
if (!_position.ApproxEquals(m_taintposition, 0f)) if (!_position.ApproxEquals(m_taintposition, 0f))
{ {
m_log.Debug("[PHYSICS]: TaintMove"); // m_log.Debug("[PHYSICS]: TaintMove");
changemove(timestep); changemove(timestep);
} }
if (m_taintrot != _orientation) if (m_taintrot != _orientation)
{ {
m_log.Debug("[PHYSICS]: TaintRotate"); // m_log.Debug("[PHYSICS]: TaintRotate");
rotate(timestep); rotate(timestep);
} // } //
if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent))
{ {
m_log.Debug("[PHYSICS]: TaintPhysics"); // m_log.Debug("[PHYSICS]: TaintPhysics");
changePhysicsStatus(timestep); changePhysicsStatus(timestep);
} }
// //
if (!_size.ApproxEquals(m_taintsize, 0f)) if (!_size.ApproxEquals(m_taintsize, 0f))
{ {
m_log.Debug("[PHYSICS]: TaintSize"); // m_log.Debug("[PHYSICS]: TaintSize");
changesize(timestep); changesize(timestep);
} }
@ -814,43 +838,43 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
if (m_taintshape) if (m_taintshape)
{ {
m_log.Debug("[PHYSICS]: TaintShape"); // m_log.Debug("[PHYSICS]: TaintShape");
changeshape(timestep); changeshape(timestep);
} // } //
if (m_taintforce) if (m_taintforce)
{ {
m_log.Debug("[PHYSICS]: TaintForce"); // m_log.Debug("[PHYSICS]: TaintForce");
changeAddForce(timestep); changeAddForce(timestep);
} }
if (m_taintaddangularforce) if (m_taintaddangularforce)
{ {
m_log.Debug("[PHYSICS]: TaintAngularForce"); // m_log.Debug("[PHYSICS]: TaintAngularForce");
changeAddAngularForce(timestep); changeAddAngularForce(timestep);
} }
if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f)) if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f))
{ {
m_log.Debug("[PHYSICS]: TaintTorque"); // m_log.Debug("[PHYSICS]: TaintTorque");
changeSetTorque(timestep); changeSetTorque(timestep);
} }
if (m_taintdisable) if (m_taintdisable)
{ {
m_log.Debug("[PHYSICS]: TaintDisable"); // m_log.Debug("[PHYSICS]: TaintDisable");
changedisable(timestep); changedisable(timestep);
} }
if (m_taintselected != m_isSelected) if (m_taintselected != m_isSelected)
{ {
m_log.Debug("[PHYSICS]: TaintSelected"); // m_log.Debug("[PHYSICS]: TaintSelected");
changeSelectedStatus(timestep); changeSelectedStatus(timestep);
} }
if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f)) if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f))
{ {
m_log.Debug("[PHYSICS]: TaintVelocity"); // m_log.Debug("[PHYSICS]: TaintVelocity");
changevelocity(timestep); changevelocity(timestep);
} }
if (m_taintparent != _parent) if (m_taintparent != _parent)
{ {
m_log.Debug("[PHYSICS]: TaintLink"); // m_log.Debug("[PHYSICS]: TaintLink");
changelink(timestep); changelink(timestep);
} }
if (m_taintCollidesWater != m_collidesWater) if (m_taintCollidesWater != m_collidesWater)
@ -859,7 +883,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
} }
if (!m_angularlock.ApproxEquals(m_taintAngularLock, 0)) if (!m_angularlock.ApproxEquals(m_taintAngularLock, 0))
{ {
m_log.Debug("[PHYSICS]: TaintAngularLock"); // m_log.Debug("[PHYSICS]: TaintAngularLock");
changeAngularLock(timestep); changeAngularLock(timestep);
} }
if (m_taintremove) if (m_taintremove)
@ -917,7 +941,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
private void changemove(float timestep) private void changemove(float timestep)
{ {
m_log.Debug("[PHYSICS]: _________ChangeMove"); // m_log.Debug("[PHYSICS]: _________ChangeMove");
if (!m_isphysical) if (!m_isphysical)
{ {
tempTransform2 = Body.getWorldTransform(); tempTransform2 = Body.getWorldTransform();
@ -977,7 +1001,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
private void rotate(float timestep) private void rotate(float timestep)
{ {
m_log.Debug("[PHYSICS]: _________ChangeRotate"); // m_log.Debug("[PHYSICS]: _________ChangeRotate");
tempTransform2 = Body.getWorldTransform(); tempTransform2 = Body.getWorldTransform();
tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W); tempOrientation2 = new btQuaternion(_orientation.X, _orientation.Y, _orientation.Z, _orientation.W);
tempTransform2.setRotation(tempOrientation2); tempTransform2.setRotation(tempOrientation2);
@ -1000,7 +1024,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
//Body = null; //Body = null;
// TODO: dispose parts that make up body // TODO: dispose parts that make up body
} }
m_log.Debug("[PHYSICS]: _________ChangePhysics"); // m_log.Debug("[PHYSICS]: _________ChangePhysics");
ProcessGeomCreation(); ProcessGeomCreation();
@ -1092,7 +1116,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
// TODO: dispose parts that make up body // TODO: dispose parts that make up body
} }
m_log.Debug("[PHYSICS]: _________ChangeSize"); // m_log.Debug("[PHYSICS]: _________ChangeSize");
SetCollisionShape(null); SetCollisionShape(null);
// Construction of new prim // Construction of new prim
ProcessGeomCreation(); ProcessGeomCreation();
@ -1297,13 +1321,13 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
// TODO: throw new NotImplementedException(); // TODO: throw new NotImplementedException();
if (m_taintselected) if (m_taintselected)
{ {
Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE); // Body.setCollisionFlags((int)ContactFlags.CF_NO_CONTACT_RESPONSE);
disableBodySoft(); disableBodySoft();
} }
else else
{ {
Body.setCollisionFlags(0 | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK); // Body.setCollisionFlags(0 | (int)ContactFlags.CF_CUSTOM_MATERIAL_CALLBACK);
enableBodySoft(); enableBodySoft();
} }
m_isSelected = m_taintselected; m_isSelected = m_taintselected;
@ -1605,6 +1629,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
enableBodySoft(); enableBodySoft();
} }
*/ */
if (!Body.isActive())
{
Body.clearForces();
enableBodySoft();
}
// 35x10 = 350n times the mass per second applied maximum. // 35x10 = 350n times the mass per second applied maximum.
float nmax = 35f * m_mass; float nmax = 35f * m_mass;
@ -1632,6 +1661,12 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
Body.applyCentralImpulse(tempAddForce); Body.applyCentralImpulse(tempAddForce);
} }
} }
else
{
// if no forces on the prim, make sure everything is zero
Body.clearForces();
enableBodySoft();
}
} }
else else
{ {
@ -1985,7 +2020,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
public void CreateGeom(IntPtr m_targetSpace, IMesh p_mesh) public void CreateGeom(IntPtr m_targetSpace, IMesh p_mesh)
{ {
m_log.Debug("[PHYSICS]: _________CreateGeom"); // m_log.Debug("[PHYSICS]: _________CreateGeom");
if (p_mesh != null) if (p_mesh != null)
{ {
//_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); //_mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical);
@ -2042,7 +2077,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
// TODO: Set Collision Body Mesh // TODO: Set Collision Body Mesh
// This sleeper is there to moderate how long it takes between // This sleeper is there to moderate how long it takes between
// setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
m_log.Debug("_________SetMesh"); // m_log.Debug("_________SetMesh");
Thread.Sleep(10); Thread.Sleep(10);
//Kill Body so that mesh can re-make the geom //Kill Body so that mesh can re-make the geom
@ -2159,7 +2194,14 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
// Body = new btRigidBody(mass, tempMotionState1, prim_geom); // Body = new btRigidBody(mass, tempMotionState1, prim_geom);
//else //else
// Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
if (Body == null)
{
Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
// add localID so we can later map bullet object back to OpenSim object
Body.setUserPointer(new IntPtr((int)m_localID));
}
if (prim_geom is btGImpactMeshShape) if (prim_geom is btGImpactMeshShape)
{ {
@ -2250,7 +2292,13 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
// Body = new btRigidBody(mass, tempMotionState1, prim_geom); // Body = new btRigidBody(mass, tempMotionState1, prim_geom);
//else //else
// Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
if (Body == null)
{
Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1); Body = new btRigidBody(mass, tempMotionState1, prim_geom, tempInertia1);
// each body has the localID stored into it so we can identify collision objects
Body.setUserPointer(new IntPtr((int)m_localID));
}
if (prim_geom is btGImpactMeshShape) if (prim_geom is btGImpactMeshShape)
{ {

View File

@ -47,7 +47,9 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
// private string m_sceneIdentifier = string.Empty; // private string m_sceneIdentifier = string.Empty;
private List<BulletDotNETCharacter> m_characters = new List<BulletDotNETCharacter>(); private List<BulletDotNETCharacter> m_characters = new List<BulletDotNETCharacter>();
private Dictionary<uint, BulletDotNETCharacter> m_charactersLocalID = new Dictionary<uint, BulletDotNETCharacter>();
private List<BulletDotNETPrim> m_prims = new List<BulletDotNETPrim>(); private List<BulletDotNETPrim> m_prims = new List<BulletDotNETPrim>();
private Dictionary<uint, BulletDotNETPrim> m_primsLocalID = new Dictionary<uint, BulletDotNETPrim>();
private List<BulletDotNETPrim> m_activePrims = new List<BulletDotNETPrim>(); private List<BulletDotNETPrim> m_activePrims = new List<BulletDotNETPrim>();
private List<PhysicsActor> m_taintedActors = new List<PhysicsActor>(); private List<PhysicsActor> m_taintedActors = new List<PhysicsActor>();
private btDiscreteDynamicsWorld m_world; private btDiscreteDynamicsWorld m_world;
@ -134,7 +136,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); m_world = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_world.setGravity(m_gravity); m_world.setGravity(m_gravity);
//EnableCollisionInterface(); EnableCollisionInterface();
} }
@ -145,7 +147,16 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
avCapRadius, avStandupTensor, avDensity, avCapRadius, avStandupTensor, avDensity,
avHeightFudgeFactor, avMovementDivisorWalk, avHeightFudgeFactor, avMovementDivisorWalk,
avMovementDivisorRun); avMovementDivisorRun);
try
{
m_characters.Add(chr); m_characters.Add(chr);
m_charactersLocalID.Add(chr.m_localID, chr);
}
catch
{
// noop if it's already there
m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate avatar localID");
}
AddPhysicsActorTaint(chr); AddPhysicsActorTaint(chr);
return chr; return chr;
} }
@ -154,6 +165,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
{ {
BulletDotNETCharacter chr = (BulletDotNETCharacter) actor; BulletDotNETCharacter chr = (BulletDotNETCharacter) actor;
m_charactersLocalID.Remove(chr.m_localID);
m_characters.Remove(chr); m_characters.Remove(chr);
m_world.removeRigidBody(chr.Body); m_world.removeRigidBody(chr.Body);
m_world.removeCollisionObject(chr.Body); m_world.removeCollisionObject(chr.Body);
@ -279,7 +291,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
prim.Move(timeStep); prim.Move(timeStep);
} }
} }
float steps = m_world.stepSimulation(timeStep * 1000, 10, WorldTimeComp); float steps = m_world.stepSimulation(timeStep, 10, WorldTimeComp);
foreach (BulletDotNETCharacter chr in m_characters) foreach (BulletDotNETCharacter chr in m_characters)
{ {
@ -296,20 +308,67 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
} }
if (m_CollisionInterface != null) if (m_CollisionInterface != null)
{ {
List<int> collisions = m_CollisionInterface.GetContactList(); List<BulletDotNETPrim> primsWithCollisions = new List<BulletDotNETPrim>();
lock (collisions) List<BulletDotNETCharacter> charactersWithCollisions = new List<BulletDotNETCharacter>();
// get the collisions that happened this tick
List<BulletDotNET.ContactAddedCallbackHandler.ContactInfo> collisions = m_CollisionInterface.GetContactList();
// passed back the localID of the prim so we can associate the prim
foreach (BulletDotNET.ContactAddedCallbackHandler.ContactInfo ci in collisions)
{ {
foreach (int pvalue in collisions) // ContactPoint = { contactPoint, contactNormal, penetrationDepth }
{ ContactPoint contact = new ContactPoint(new Vector3(ci.pX, ci.pY, ci.pZ),
System.Console.Write(string.Format("{0} ", pvalue)); new Vector3(ci.nX, ci.nY, ci.nZ), ci.depth);
}
} ProcessContact(ci.contact, ci.contactWith, contact, ref primsWithCollisions, ref charactersWithCollisions);
m_CollisionInterface.Clear(); ProcessContact(ci.contactWith, ci.contact, contact, ref primsWithCollisions, ref charactersWithCollisions);
} }
m_CollisionInterface.Clear();
// for those prims and characters that had collisions cause collision events
foreach (BulletDotNETPrim bdnp in primsWithCollisions)
{
bdnp.SendCollisions();
}
foreach (BulletDotNETCharacter bdnc in charactersWithCollisions)
{
bdnc.SendCollisions();
}
}
return steps; return steps;
} }
private void ProcessContact(uint cont, uint contWith, ContactPoint contact,
ref List<BulletDotNETPrim> primsWithCollisions,
ref List<BulletDotNETCharacter> charactersWithCollisions)
{
BulletDotNETPrim bdnp;
// collisions with a normal prim?
if (m_primsLocalID.TryGetValue(cont, out bdnp))
{
// Added collision event to the prim. This creates a pile of events
// that will be sent to any subscribed listeners.
bdnp.AddCollision(contWith, contact);
if (!primsWithCollisions.Contains(bdnp))
{
primsWithCollisions.Add(bdnp);
}
}
else
{
BulletDotNETCharacter bdnc;
// if not a prim, maybe it's one of the characters
if (m_charactersLocalID.TryGetValue(cont, out bdnc))
{
bdnc.AddCollision(contWith, contact);
if (!charactersWithCollisions.Contains(bdnc))
{
charactersWithCollisions.Add(bdnc);
}
}
}
}
public override void GetResults() public override void GetResults()
{ {
@ -387,6 +446,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition); m_terrainTransform = new btTransform(QuatIdentity, m_terrainPosition);
m_terrainMotionState = new btDefaultMotionState(m_terrainTransform); m_terrainMotionState = new btDefaultMotionState(m_terrainTransform);
TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape); TerrainBody = new btRigidBody(0, m_terrainMotionState, m_terrainShape);
TerrainBody.setUserPointer((IntPtr)0);
m_world.addRigidBody(TerrainBody); m_world.addRigidBody(TerrainBody);
@ -459,6 +519,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
{ {
lock (m_prims) lock (m_prims)
{ {
m_primsLocalID.Clear();
foreach (BulletDotNETPrim prim in m_prims) foreach (BulletDotNETPrim prim in m_prims)
{ {
if (prim.Body != null) if (prim.Body != null)
@ -513,6 +574,7 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
m_world.removeRigidBody(body); m_world.removeRigidBody(body);
} }
remActivePrim(prm); remActivePrim(prm);
m_primsLocalID.Remove(prm.m_localID);
m_prims.Remove(prm); m_prims.Remove(prm);
} }
@ -685,10 +747,19 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
lock (m_prims) lock (m_prims)
{ {
if (!m_prims.Contains(pPrim)) if (!m_prims.Contains(pPrim))
{
try
{ {
m_prims.Add(pPrim); m_prims.Add(pPrim);
m_primsLocalID.Add(pPrim.m_localID, pPrim);
}
catch
{
// noop if it's already there
m_log.Debug("[PHYSICS] BulletDotNet: adding duplicate prim localID");
}
m_world.addRigidBody(pPrim.Body); m_world.addRigidBody(pPrim.Body);
m_log.Debug("ADDED"); // m_log.Debug("[PHYSICS] added prim to scene");
} }
} }
} }
@ -696,8 +767,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
{ {
if (m_CollisionInterface == null) if (m_CollisionInterface == null)
{ {
m_CollisionInterface = new ContactAddedCallbackHandler(); m_CollisionInterface = new ContactAddedCallbackHandler(m_world);
m_world.SetCollisionAddedCallback(m_CollisionInterface); // m_world.SetCollisionAddedCallback(m_CollisionInterface);
} }
} }

View File

@ -827,15 +827,16 @@ namespace PrimMesher
if (createFaces) if (createFaces)
{ {
int numOuterVerts = this.coords.Count; //int numOuterVerts = this.coords.Count;
int numHollowVerts = hollowCoords.Count; //numOuterVerts = this.coords.Count;
int numTotalVerts = numOuterVerts + numHollowVerts; //int numHollowVerts = hollowCoords.Count;
int numTotalVerts = this.numOuterVerts + this.numHollowVerts;
if (numOuterVerts == numHollowVerts) if (this.numOuterVerts == this.numHollowVerts)
{ {
Face newFace = new Face(); Face newFace = new Face();
for (int coordIndex = 0; coordIndex < numOuterVerts - 1; coordIndex++) for (int coordIndex = 0; coordIndex < this.numOuterVerts - 1; coordIndex++)
{ {
newFace.v1 = coordIndex; newFace.v1 = coordIndex;
newFace.v2 = coordIndex + 1; newFace.v2 = coordIndex + 1;
@ -850,12 +851,12 @@ namespace PrimMesher
} }
else else
{ {
if (numOuterVerts < numHollowVerts) if (this.numOuterVerts < this.numHollowVerts)
{ {
Face newFace = new Face(); Face newFace = new Face();
int j = 0; // j is the index for outer vertices int j = 0; // j is the index for outer vertices
int maxJ = numOuterVerts - 1; int maxJ = this.numOuterVerts - 1;
for (int i = 0; i < numHollowVerts; i++) // i is the index for inner vertices for (int i = 0; i < this.numHollowVerts; i++) // i is the index for inner vertices
{ {
if (j < maxJ) if (j < maxJ)
if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f) if (angles.angles[j + 1].angle - hollowAngles.angles[i].angle < hollowAngles.angles[i].angle - angles.angles[j].angle + 0.000001f)
@ -879,8 +880,8 @@ namespace PrimMesher
{ {
Face newFace = new Face(); Face newFace = new Face();
int j = 0; // j is the index for inner vertices int j = 0; // j is the index for inner vertices
int maxJ = numHollowVerts - 1; int maxJ = this.numHollowVerts - 1;
for (int i = 0; i < numOuterVerts; i++) for (int i = 0; i < this.numOuterVerts; i++)
{ {
if (j < maxJ) if (j < maxJ)
if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f) if (hollowAngles.angles[j + 1].angle - angles.angles[i].angle < angles.angles[i].angle - hollowAngles.angles[j].angle + 0.000001f)
@ -981,7 +982,7 @@ namespace PrimMesher
int startVert = hasProfileCut && !hasHollow ? 1 : 0; int startVert = hasProfileCut && !hasHollow ? 1 : 0;
if (startVert > 0) if (startVert > 0)
this.faceNumbers.Add(-1); this.faceNumbers.Add(-1);
for (int i = 0; i < numOuterVerts - 1; i++) for (int i = 0; i < this.numOuterVerts - 1; i++)
this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum); this.faceNumbers.Add(sides < 5 ? faceNum++ : faceNum);
//if (!hasHollow && !hasProfileCut) //if (!hasHollow && !hasProfileCut)
@ -994,7 +995,7 @@ namespace PrimMesher
if (hasHollow) if (hasHollow)
{ {
for (int i = 0; i < numHollowVerts; i++) for (int i = 0; i < this.numHollowVerts; i++)
this.faceNumbers.Add(faceNum); this.faceNumbers.Add(faceNum);
faceNum++; faceNum++;
@ -1019,7 +1020,7 @@ namespace PrimMesher
{ {
this.faceUVs = new List<UVCoord>(); this.faceUVs = new List<UVCoord>();
foreach (Coord c in this.coords) foreach (Coord c in this.coords)
this.faceUVs.Add(new UVCoord(1.0f - (0.5f + c.X), 1.0f - (0.5f - c.Y))); this.faceUVs.Add(new UVCoord(0.5f + c.X, 0.5f - c.Y));
} }
internal Profile Copy() internal Profile Copy()
@ -1348,7 +1349,6 @@ namespace PrimMesher
float stepSize = twoPi / this.stepsPerRevolution; float stepSize = twoPi / this.stepsPerRevolution;
int step = (int)(startAngle / stepSize); int step = (int)(startAngle / stepSize);
// int firstStep = step;
float angle = startAngle; float angle = startAngle;
bool done = false; bool done = false;
@ -1738,7 +1738,6 @@ namespace PrimMesher
// append this layer // append this layer
int coordsLen = this.coords.Count; int coordsLen = this.coords.Count;
// int lastCoordsLen = coordsLen;
newLayer.AddValue2FaceVertexIndices(coordsLen); newLayer.AddValue2FaceVertexIndices(coordsLen);
this.coords.AddRange(newLayer.coords); this.coords.AddRange(newLayer.coords);

View File

@ -53,42 +53,49 @@ namespace PrimMesher
public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 };
#if SYSTEM_DRAWING #if SYSTEM_DRAWING
// private Bitmap ScaleImage(Bitmap srcImage, float scale) private Bitmap ScaleImage(Bitmap srcImage, float scale, bool removeAlpha)
// { {
// int sourceWidth = srcImage.Width; int sourceWidth = srcImage.Width;
// int sourceHeight = srcImage.Height; int sourceHeight = srcImage.Height;
// int sourceX = 0; int sourceX = 0;
// int sourceY = 0; int sourceY = 0;
// int destX = 0; int destX = 0;
// int destY = 0; int destY = 0;
// int destWidth = (int)(srcImage.Width * scale); int destWidth = (int)(srcImage.Width * scale);
// int destHeight = (int)(srcImage.Height * scale); int destHeight = (int)(srcImage.Height * scale);
// if (srcImage.PixelFormat == PixelFormat.Format32bppArgb) Bitmap scaledImage;
// for (int y = 0; y < srcImage.Height; y++)
// for (int x = 0; x < srcImage.Width; x++)
// {
// Color c = srcImage.GetPixel(x, y);
// srcImage.SetPixel(x, y, Color.FromArgb(255, c.R, c.G, c.B));
// }
// Bitmap scaledImage = new Bitmap(destWidth, destHeight, if (removeAlpha)
// PixelFormat.Format24bppRgb); {
if (srcImage.PixelFormat == PixelFormat.Format32bppArgb)
for (int y = 0; y < srcImage.Height; y++)
for (int x = 0; x < srcImage.Width; x++)
{
Color c = srcImage.GetPixel(x, y);
srcImage.SetPixel(x, y, Color.FromArgb(255, c.R, c.G, c.B));
}
// scaledImage.SetResolution(96.0f, 96.0f); scaledImage = new Bitmap(destWidth, destHeight,
PixelFormat.Format24bppRgb);
}
else
scaledImage = new Bitmap(srcImage, destWidth, destHeight);
// Graphics grPhoto = Graphics.FromImage(scaledImage); scaledImage.SetResolution(96.0f, 96.0f);
// grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
// grPhoto.DrawImage(srcImage, Graphics grPhoto = Graphics.FromImage(scaledImage);
// new Rectangle(destX, destY, destWidth, destHeight), grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
// new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
// GraphicsUnit.Pixel);
// grPhoto.Dispose(); grPhoto.DrawImage(srcImage,
// return scaledImage; new Rectangle(destX, destY, destWidth, destHeight),
// } new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
GraphicsUnit.Pixel);
grPhoto.Dispose();
return scaledImage;
}
public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode) public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
@ -268,6 +275,11 @@ namespace PrimMesher
for (imageY = imageYStart; imageY < imageYEnd; imageY++) for (imageY = imageYStart; imageY < imageYEnd; imageY++)
{ {
Color c = bitmap.GetPixel(imageX, imageY); Color c = bitmap.GetPixel(imageX, imageY);
if (c.A != 255)
{
bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B));
c = bitmap.GetPixel(imageX, imageY);
}
rSum += c.R; rSum += c.R;
gSum += c.G; gSum += c.G;
bSum += c.B; bSum += c.B;
@ -298,12 +310,18 @@ namespace PrimMesher
if (sculptType == SculptType.plane) if (sculptType == SculptType.plane)
invert = !invert; invert = !invert;
float sourceScaleFactor = (float)(lod) / (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height); float sculptBitmapLod = (float)Math.Sqrt(sculptBitmap.Width * sculptBitmap.Height);
int scale = (int)(1.0f / sourceScaleFactor); float sourceScaleFactor = (float)(lod) / sculptBitmapLod;
if (scale < 1) scale = 1;
_SculptMesh(bitmap2Coords(sculptBitmap, scale, mirror), sculptType, viewerMode, mirror, invert); float fScale = 1.0f / sourceScaleFactor;
int iScale = (int)fScale;
if (iScale < 1) iScale = 1;
if (iScale > 2 && iScale % 2 == 0)
_SculptMesh(bitmap2Coords(ScaleImage(sculptBitmap, 64.0f / sculptBitmapLod, true), 64 / lod, mirror), sculptType, viewerMode, mirror, invert);
else
_SculptMesh(bitmap2Coords(sculptBitmap, iScale, mirror), sculptType, viewerMode, mirror, invert);
} }
#endif #endif

View File

@ -1575,11 +1575,11 @@ Console.WriteLine(" JointCreateFixed");
{ {
//Console.WriteLine("Move " + m_primName); //Console.WriteLine("Move " + m_primName);
if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 if (!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
/*
// NON-'VEHICLES' are dealt with here // NON-'VEHICLES' are dealt with here
if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
{ {
d.Vector3 avel2 = d.BodyGetAngularVel(Body); d.Vector3 avel2 = d.BodyGetAngularVel(Body);
/*
if (m_angularlock.X == 1) if (m_angularlock.X == 1)
avel2.X = 0; avel2.X = 0;
if (m_angularlock.Y == 1) if (m_angularlock.Y == 1)
@ -1587,8 +1587,8 @@ Console.WriteLine(" JointCreateFixed");
if (m_angularlock.Z == 1) if (m_angularlock.Z == 1)
avel2.Z = 0; avel2.Z = 0;
d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z);
}
*/ */
}
//float PID_P = 900.0f; //float PID_P = 900.0f;
float m_mass = CalculateMass(); float m_mass = CalculateMass();

View File

@ -57,6 +57,12 @@ namespace OpenSim.Server.Base
return ret; return ret;
} }
/// <summary>
/// Load a plugin from a dll with the given class or interface
/// </summary>
/// <param name="dllName"></param>
/// <param name="args">The arguments which control which constructor is invoked on the plugin</param>
/// <returns></returns>
public static T LoadPlugin<T>(string dllName, Object[] args) where T:class public static T LoadPlugin<T>(string dllName, Object[] args) where T:class
{ {
string[] parts = dllName.Split(new char[] {':'}); string[] parts = dllName.Split(new char[] {':'});
@ -71,6 +77,13 @@ namespace OpenSim.Server.Base
return LoadPlugin<T>(dllName, className, args); return LoadPlugin<T>(dllName, className, args);
} }
/// <summary>
/// Load a plugin from a dll with the given class or interface
/// </summary>
/// <param name="dllName"></param>
/// <param name="className"></param>
/// <param name="args">The arguments which control which constructor is invoked on the plugin</param>
/// <returns></returns>
public static T LoadPlugin<T>(string dllName, string className, Object[] args) where T:class public static T LoadPlugin<T>(string dllName, string className, Object[] args) where T:class
{ {
string interfaceName = typeof(T).ToString(); string interfaceName = typeof(T).ToString();
@ -83,28 +96,15 @@ namespace OpenSim.Server.Base
{ {
if (pluginType.IsPublic) if (pluginType.IsPublic)
{ {
if (className != String.Empty && if (className != String.Empty
pluginType.ToString() != && pluginType.ToString() != pluginType.Namespace + "." + className)
pluginType.Namespace + "." + className)
continue; continue;
Type typeInterface =
pluginType.GetInterface(interfaceName, true); Type typeInterface = pluginType.GetInterface(interfaceName, true);
if (typeInterface != null) if (typeInterface != null)
{ {
T plug = null; return (T)Activator.CreateInstance(pluginType, args);
try
{
plug = (T)Activator.CreateInstance(pluginType,
args);
}
catch (Exception e)
{
if (!(e is System.MissingMethodException))
m_log.ErrorFormat("Error loading plugin from {0}, exception {1}", dllName, e.InnerException);
return null;
}
return plug;
} }
} }
} }
@ -113,7 +113,7 @@ namespace OpenSim.Server.Base
} }
catch (Exception e) catch (Exception e)
{ {
m_log.ErrorFormat("Error loading plugin from {0}, exception {1}", dllName, e); m_log.Error(string.Format("Error loading plugin from {0}", dllName), e);
return null; return null;
} }
} }

View File

@ -1,4 +1,31 @@
using System; /*
* 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; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;

View File

@ -1,4 +1,31 @@
using System; /*
* 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; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;

View File

@ -1,4 +1,31 @@
using System; /*
* 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; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -334,7 +361,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
} }
catch (Exception e) catch (Exception e)
{ {
m_log.Debug("[HGrid]: Exception " + e.Message); m_log.Debug("[USER AGENT CONNECTOR]: Unable to contact remote server ");
reason = "Exception: " + e.Message; reason = "Exception: " + e.Message;
return false; return false;
} }

View File

@ -0,0 +1,410 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Connects to the SimianGrid asset service
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianAssetServiceConnector : IAssetService, ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private static string ZeroID = UUID.Zero.ToString();
private string m_serverUrl = String.Empty;
private IImprovedAssetCache m_cache;
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene)
{
if (m_cache == null)
{
IImprovedAssetCache cache = scene.RequestModuleInterface<IImprovedAssetCache>();
if (cache is ISharedRegionModule)
m_cache = cache;
}
}
public void PostInitialise() { }
public void Close() { }
public SimianAssetServiceConnector() { }
public string Name { get { return "SimianAssetServiceConnector"; } }
public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAssetService>(this); } }
public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAssetService>(this); } }
#endregion ISharedRegionModule
public SimianAssetServiceConnector(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "AssetServices"))
{
IConfig gridConfig = source.Configs["AssetService"];
if (gridConfig == null)
{
m_log.Error("[ASSET CONNECTOR]: AssetService missing from OpenSim.ini");
throw new Exception("Asset connector init error");
}
string serviceUrl = gridConfig.GetString("AssetServerURI");
if (String.IsNullOrEmpty(serviceUrl))
{
m_log.Error("[ASSET CONNECTOR]: No AssetServerURI in section AssetService");
throw new Exception("Asset connector init error");
}
if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("="))
serviceUrl = serviceUrl + '/';
m_serverUrl = serviceUrl;
}
}
#region IAssetService
public AssetBase Get(string id)
{
AssetBase asset = null;
// Cache fetch
if (m_cache != null)
{
asset = m_cache.Get(id);
if (asset != null)
return asset;
}
Uri url;
// Determine if id is an absolute URL or a grid-relative UUID
if (!Uri.TryCreate(id, UriKind.Absolute, out url))
url = new Uri(m_serverUrl + id);
try
{
HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
using (WebResponse response = request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
string creatorID = response.Headers.GetOne("X-Asset-Creator-Id") ?? String.Empty;
// Create the asset object
asset = new AssetBase(id, String.Empty, SLUtil.ContentTypeToSLAssetType(response.ContentType), creatorID);
UUID assetID;
if (UUID.TryParse(id, out assetID))
asset.FullID = assetID;
// Grab the asset data from the response stream
using (MemoryStream stream = new MemoryStream())
{
responseStream.CopyTo(stream, Int32.MaxValue);
asset.Data = stream.ToArray();
}
}
}
// Cache store
if (m_cache != null && asset != null)
m_cache.Cache(asset);
return asset;
}
catch (Exception ex)
{
m_log.Warn("[ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message);
return null;
}
}
/// <summary>
/// Get an asset's metadata
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public AssetMetadata GetMetadata(string id)
{
AssetMetadata metadata = null;
// Cache fetch
if (m_cache != null)
{
AssetBase asset = m_cache.Get(id);
if (asset != null)
return asset.Metadata;
}
Uri url;
// Determine if id is an absolute URL or a grid-relative UUID
if (!Uri.TryCreate(id, UriKind.Absolute, out url))
url = new Uri(m_serverUrl + id);
try
{
HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
request.Method = "HEAD";
using (WebResponse response = request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
// Create the metadata object
metadata = new AssetMetadata();
metadata.ContentType = response.ContentType;
metadata.ID = id;
UUID uuid;
if (UUID.TryParse(id, out uuid))
metadata.FullID = uuid;
string lastModifiedStr = response.Headers.Get("Last-Modified");
if (!String.IsNullOrEmpty(lastModifiedStr))
{
DateTime lastModified;
if (DateTime.TryParse(lastModifiedStr, out lastModified))
metadata.CreationDate = lastModified;
}
}
}
}
catch (Exception ex)
{
m_log.Warn("[ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message);
}
return metadata;
}
public byte[] GetData(string id)
{
AssetBase asset = Get(id);
if (asset != null)
return asset.Data;
return null;
}
/// <summary>
/// Get an asset asynchronously
/// </summary>
/// <param name="id">The asset id</param>
/// <param name="sender">Represents the requester. Passed back via the handler</param>
/// <param name="handler">The handler to call back once the asset has been retrieved</param>
/// <returns>True if the id was parseable, false otherwise</returns>
public bool Get(string id, Object sender, AssetRetrieved handler)
{
Util.FireAndForget(
delegate(object o)
{
AssetBase asset = Get(id);
handler(id, sender, asset);
}
);
return true;
}
/// <summary>
/// Creates a new asset
/// </summary>
/// Returns a random ID if none is passed into it
/// <param name="asset"></param>
/// <returns></returns>
public string Store(AssetBase asset)
{
bool storedInCache = false;
string errorMessage = null;
// AssetID handling
if (String.IsNullOrEmpty(asset.ID) || asset.ID == ZeroID)
{
asset.FullID = UUID.Random();
asset.ID = asset.FullID.ToString();
}
// Cache handling
if (m_cache != null)
{
m_cache.Cache(asset);
storedInCache = true;
}
// Local asset handling
if (asset.Local)
{
if (!storedInCache)
{
m_log.Error("Cannot store local " + asset.Metadata.ContentType + " asset without an asset cache");
asset.ID = null;
asset.FullID = UUID.Zero;
}
return asset.ID;
}
// Distinguish public and private assets
bool isPublic = true;
switch ((AssetType)asset.Type)
{
case AssetType.CallingCard:
case AssetType.Gesture:
case AssetType.LSLBytecode:
case AssetType.LSLText:
isPublic = false;
break;
}
// Make sure ContentType is set
if (String.IsNullOrEmpty(asset.Metadata.ContentType))
asset.Metadata.ContentType = SLUtil.SLAssetTypeToContentType(asset.Type);
// Build the remote storage request
List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
{
new MultipartForm.Parameter("AssetID", asset.FullID.ToString()),
new MultipartForm.Parameter("CreatorID", asset.Metadata.CreatorID),
new MultipartForm.Parameter("Temporary", asset.Temporary ? "1" : "0"),
new MultipartForm.Parameter("Public", isPublic ? "1" : "0"),
new MultipartForm.File("Asset", asset.Name, asset.Metadata.ContentType, asset.Data)
};
// Make the remote storage request
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
HttpWebResponse response = MultipartForm.Post(request, postParameters);
using (Stream responseStream = response.GetResponseStream())
{
try
{
string responseStr = responseStream.GetStreamString();
OSD responseOSD = OSDParser.Deserialize(responseStr);
if (responseOSD.Type == OSDType.Map)
{
OSDMap responseMap = (OSDMap)responseOSD;
if (responseMap["Success"].AsBoolean())
return asset.ID;
else
errorMessage = "Upload failed: " + responseMap["Message"].AsString();
}
else
{
errorMessage = "Response format was invalid.";
}
}
catch
{
errorMessage = "Failed to parse the response.";
}
}
}
catch (WebException ex)
{
errorMessage = ex.Message;
}
m_log.WarnFormat("[ASSET CONNECTOR]: Failed to store asset \"{0}\" ({1}, {2}): {3}",
asset.Name, asset.ID, asset.Metadata.ContentType, errorMessage);
return null;
}
/// <summary>
/// Update an asset's content
/// </summary>
/// Attachments and bare scripts need this!!
/// <param name="id"> </param>
/// <param name="data"></param>
/// <returns></returns>
public bool UpdateContent(string id, byte[] data)
{
AssetBase asset = Get(id);
if (asset == null)
{
m_log.Warn("[ASSET CONNECTOR]: Failed to fetch asset " + id + " for updating");
return false;
}
asset.Data = data;
string result = Store(asset);
return !String.IsNullOrEmpty(result);
}
/// <summary>
/// Delete an asset
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public bool Delete(string id)
{
if (m_cache != null)
m_cache.Expire(id);
string url = m_serverUrl + id;
OSDMap response = WebUtil.ServiceRequest(url, "DELETE");
if (response["Success"].AsBoolean())
return true;
else
m_log.Warn("[ASSET CONNECTOR]: Failed to delete asset " + id + " from the asset service");
return false;
}
#endregion IAssetService
}
}

View File

@ -0,0 +1,201 @@
/*
* 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.Specialized;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Connects authentication/authorization to the SimianGrid backend
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianAuthenticationServiceConnector : IAuthenticationService, ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_serverUrl = String.Empty;
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene) { }
public void PostInitialise() { }
public void Close() { }
public SimianAuthenticationServiceConnector() { }
public string Name { get { return "SimianAuthenticationServiceConnector"; } }
public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAuthenticationService>(this); } }
public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAuthenticationService>(this); } }
#endregion ISharedRegionModule
public SimianAuthenticationServiceConnector(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "AuthenticationServices"))
{
IConfig assetConfig = source.Configs["AuthenticationService"];
if (assetConfig == null)
{
m_log.Error("[AUTH CONNECTOR]: AuthenticationService missing from OpenSim.ini");
throw new Exception("Authentication connector init error");
}
string serviceURI = assetConfig.GetString("AuthenticationServerURI");
if (String.IsNullOrEmpty(serviceURI))
{
m_log.Error("[AUTH CONNECTOR]: No Server URI named in section AuthenticationService");
throw new Exception("Authentication connector init error");
}
m_serverUrl = serviceURI;
}
}
public string Authenticate(UUID principalID, string password, int lifetime)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetIdentities" },
{ "UserID", principalID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Identities"] is OSDArray)
{
OSDArray identities = (OSDArray)response["Identities"];
for (int i = 0; i < identities.Count; i++)
{
OSDMap identity = identities[i] as OSDMap;
if (identity != null)
{
if (identity["Type"].AsString() == "md5hash")
{
string credential = identity["Credential"].AsString();
if (password == credential || Utils.MD5String(password) == credential)
return Authorize(principalID);
}
}
}
m_log.Warn("[AUTH CONNECTOR]: Authentication failed for " + principalID);
}
else
{
m_log.Warn("[AUTH CONNECTOR]: Failed to retrieve identities for " + principalID + ": " +
response["Message"].AsString());
}
return String.Empty;
}
public bool Verify(UUID principalID, string token, int lifetime)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetSession" },
{ "SessionID", token }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
return true;
}
else
{
m_log.Warn("[AUTH CONNECTOR]: Could not verify session for " + principalID + ": " +
response["Message"].AsString());
}
return false;
}
public bool Release(UUID principalID, string token)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "RemoveSession" },
{ "UserID", principalID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
return true;
}
else
{
m_log.Warn("[AUTH CONNECTOR]: Failed to remove session for " + principalID + ": " +
response["Message"].AsString());
}
return false;
}
public bool SetPassword(UUID principalID, string passwd)
{
// TODO: Use GetIdentities to find the md5hash identity for principalID
// and then update it with AddIdentity
m_log.Error("[AUTH CONNECTOR]: Changing passwords is not implemented yet");
return false;
}
private string Authorize(UUID userID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddSession" },
{ "UserID", userID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
return response["SessionID"].AsUUID().ToString();
else
return String.Empty;
}
}
}

View File

@ -0,0 +1,262 @@
/*
* 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.Collections.Specialized;
using System.IO;
using System.Net;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Connects avatar appearance data to the SimianGrid backend
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianAvatarServiceConnector : IAvatarService, ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private static string ZeroID = UUID.Zero.ToString();
private string m_serverUrl = String.Empty;
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene) { }
public void PostInitialise() { }
public void Close() { }
public SimianAvatarServiceConnector() { }
public string Name { get { return "SimianAvatarServiceConnector"; } }
public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IAvatarService>(this); } }
public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IAvatarService>(this); } }
#endregion ISharedRegionModule
public SimianAvatarServiceConnector(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "AvatarServices"))
{
IConfig gridConfig = source.Configs["AvatarService"];
if (gridConfig == null)
{
m_log.Error("[AVATAR CONNECTOR]: AvatarService missing from OpenSim.ini");
throw new Exception("Avatar connector init error");
}
string serviceUrl = gridConfig.GetString("AvatarServerURI");
if (String.IsNullOrEmpty(serviceUrl))
{
m_log.Error("[AVATAR CONNECTOR]: No AvatarServerURI in section AvatarService");
throw new Exception("Avatar connector init error");
}
if (!serviceUrl.EndsWith("/"))
serviceUrl = serviceUrl + '/';
m_serverUrl = serviceUrl;
}
}
#region IAvatarService
public AvatarData GetAvatar(UUID userID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "UserID", userID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
OSDMap map = null;
try { map = OSDParser.DeserializeJson(response["LLAppearance"].AsString()) as OSDMap; }
catch { }
if (map != null)
{
AvatarWearable[] wearables = new AvatarWearable[13];
wearables[0] = new AvatarWearable(map["ShapeItem"].AsUUID(), map["ShapeAsset"].AsUUID());
wearables[1] = new AvatarWearable(map["SkinItem"].AsUUID(), map["SkinAsset"].AsUUID());
wearables[2] = new AvatarWearable(map["HairItem"].AsUUID(), map["HairAsset"].AsUUID());
wearables[3] = new AvatarWearable(map["EyesItem"].AsUUID(), map["EyesAsset"].AsUUID());
wearables[4] = new AvatarWearable(map["ShirtItem"].AsUUID(), map["ShirtAsset"].AsUUID());
wearables[5] = new AvatarWearable(map["PantsItem"].AsUUID(), map["PantsAsset"].AsUUID());
wearables[6] = new AvatarWearable(map["ShoesItem"].AsUUID(), map["ShoesAsset"].AsUUID());
wearables[7] = new AvatarWearable(map["SocksItem"].AsUUID(), map["SocksAsset"].AsUUID());
wearables[8] = new AvatarWearable(map["JacketItem"].AsUUID(), map["JacketAsset"].AsUUID());
wearables[9] = new AvatarWearable(map["GlovesItem"].AsUUID(), map["GlovesAsset"].AsUUID());
wearables[10] = new AvatarWearable(map["UndershirtItem"].AsUUID(), map["UndershirtAsset"].AsUUID());
wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID());
wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID());
AvatarAppearance appearance = new AvatarAppearance(userID);
appearance.Wearables = wearables;
appearance.AvatarHeight = (float)map["Height"].AsReal();
AvatarData avatar = new AvatarData(appearance);
// Get attachments
map = null;
try { map = OSDParser.DeserializeJson(response["LLAttachments"].AsString()) as OSDMap; }
catch { }
if (map != null)
{
foreach (KeyValuePair<string, OSD> kvp in map)
avatar.Data[kvp.Key] = kvp.Value.AsString();
}
return avatar;
}
else
{
m_log.Warn("[AVATAR CONNECTOR]: Failed to get user appearance for " + userID +
", LLAppearance is missing or invalid");
return null;
}
}
else
{
m_log.Warn("[AVATAR CONNECTOR]: Failed to get user appearance for " + userID + ": " +
response["Message"].AsString());
}
return null;
}
public bool SetAvatar(UUID userID, AvatarData avatar)
{
m_log.Debug("[AVATAR CONNECTOR]: SetAvatar called for " + userID);
if (avatar.AvatarType == 1) // LLAvatar
{
AvatarAppearance appearance = avatar.ToAvatarAppearance(userID);
OSDMap map = new OSDMap();
map["Height"] = OSD.FromReal(appearance.AvatarHeight);
map["ShapeItem"] = OSD.FromUUID(appearance.BodyItem);
map["ShapeAsset"] = OSD.FromUUID(appearance.BodyAsset);
map["SkinItem"] = OSD.FromUUID(appearance.SkinItem);
map["SkinAsset"] = OSD.FromUUID(appearance.SkinAsset);
map["HairItem"] = OSD.FromUUID(appearance.HairItem);
map["HairAsset"] = OSD.FromUUID(appearance.HairAsset);
map["EyesItem"] = OSD.FromUUID(appearance.EyesItem);
map["EyesAsset"] = OSD.FromUUID(appearance.EyesAsset);
map["ShirtItem"] = OSD.FromUUID(appearance.ShirtItem);
map["ShirtAsset"] = OSD.FromUUID(appearance.ShirtAsset);
map["PantsItem"] = OSD.FromUUID(appearance.PantsItem);
map["PantsAsset"] = OSD.FromUUID(appearance.PantsAsset);
map["ShoesItem"] = OSD.FromUUID(appearance.ShoesItem);
map["ShoesAsset"] = OSD.FromUUID(appearance.ShoesAsset);
map["SocksItem"] = OSD.FromUUID(appearance.SocksItem);
map["SocksAsset"] = OSD.FromUUID(appearance.SocksAsset);
map["JacketItem"] = OSD.FromUUID(appearance.JacketItem);
map["JacketAsset"] = OSD.FromUUID(appearance.JacketAsset);
map["GlovesItem"] = OSD.FromUUID(appearance.GlovesItem);
map["GlovesAsset"] = OSD.FromUUID(appearance.GlovesAsset);
map["UndershirtItem"] = OSD.FromUUID(appearance.UnderShirtItem);
map["UndershirtAsset"] = OSD.FromUUID(appearance.UnderShirtAsset);
map["UnderpantsItem"] = OSD.FromUUID(appearance.UnderPantsItem);
map["UnderpantsAsset"] = OSD.FromUUID(appearance.UnderPantsAsset);
map["SkirtItem"] = OSD.FromUUID(appearance.SkirtItem);
map["SkirtAsset"] = OSD.FromUUID(appearance.SkirtAsset);
OSDMap items = new OSDMap();
foreach (KeyValuePair<string, string> kvp in avatar.Data)
{
if (kvp.Key.StartsWith("_ap_"))
items.Add(kvp.Key, OSD.FromString(kvp.Value));
}
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddUserData" },
{ "UserID", userID.ToString() },
{ "LLAppearance", OSDParser.SerializeJsonString(map) },
{ "LLAttachments", OSDParser.SerializeJsonString(items) }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[AVATAR CONNECTOR]: Failed saving appearance for " + userID + ": " + response["Message"].AsString());
return success;
}
else
{
m_log.Error("[AVATAR CONNECTOR]: Can't save appearance for " + userID + ". Unhandled avatar type " + avatar.AvatarType);
return false;
}
}
public bool ResetAvatar(UUID userID)
{
m_log.Error("[AVATAR CONNECTOR]: ResetAvatar called for " + userID + ", implement this");
return false;
}
public bool SetItems(UUID userID, string[] names, string[] values)
{
m_log.Error("[AVATAR CONNECTOR]: SetItems called for " + userID + " with " + names.Length + " names and " + values.Length + " values, implement this");
return false;
}
public bool RemoveItems(UUID userID, string[] names)
{
m_log.Error("[AVATAR CONNECTOR]: RemoveItems called for " + userID + " with " + names.Length + " names, implement this");
return false;
}
#endregion IAvatarService
}
}

View File

@ -0,0 +1,232 @@
/*
* 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.Collections.Specialized;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Stores and retrieves friend lists from the SimianGrid backend
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianFriendsServiceConnector : IFriendsService, ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_serverUrl = String.Empty;
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene) { }
public void PostInitialise() { }
public void Close() { }
public SimianFriendsServiceConnector() { }
public string Name { get { return "SimianFriendsServiceConnector"; } }
public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IFriendsService>(this); } }
public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IFriendsService>(this); } }
#endregion ISharedRegionModule
public SimianFriendsServiceConnector(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "FriendsServices"))
{
IConfig assetConfig = source.Configs["FriendsService"];
if (assetConfig == null)
{
m_log.Error("[FRIENDS CONNECTOR]: FriendsService missing from OpenSim.ini");
throw new Exception("Friends connector init error");
}
string serviceURI = assetConfig.GetString("FriendsServerURI");
if (String.IsNullOrEmpty(serviceURI))
{
m_log.Error("[FRIENDS CONNECTOR]: No Server URI named in section FriendsService");
throw new Exception("Friends connector init error");
}
m_serverUrl = serviceURI;
}
}
#region IFriendsService
public FriendInfo[] GetFriends(UUID principalID)
{
Dictionary<UUID, FriendInfo> friends = new Dictionary<UUID, FriendInfo>();
OSDArray friendsArray = GetFriended(principalID);
OSDArray friendedMeArray = GetFriendedBy(principalID);
// Load the list of friends and their granted permissions
for (int i = 0; i < friendsArray.Count; i++)
{
OSDMap friendEntry = friendsArray[i] as OSDMap;
if (friendEntry != null)
{
UUID friendID = friendEntry["Key"].AsUUID();
FriendInfo friend = new FriendInfo();
friend.PrincipalID = principalID;
friend.Friend = friendID.ToString();
friend.MyFlags = friendEntry["Value"].AsInteger();
friend.TheirFlags = -1;
friends[friendID] = friend;
}
}
// Load the permissions those friends have granted to this user
for (int i = 0; i < friendedMeArray.Count; i++)
{
OSDMap friendedMeEntry = friendedMeArray[i] as OSDMap;
if (friendedMeEntry != null)
{
UUID friendID = friendedMeEntry["OwnerID"].AsUUID();
FriendInfo friend;
if (friends.TryGetValue(friendID, out friend))
friend.TheirFlags = friendedMeEntry["Value"].AsInteger();
}
}
// Convert the dictionary of friends to an array and return it
FriendInfo[] array = new FriendInfo[friends.Count];
int j = 0;
foreach (FriendInfo friend in friends.Values)
array[j++] = friend;
return array;
}
public bool StoreFriend(UUID principalID, string friend, int flags)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddGeneric" },
{ "OwnerID", principalID.ToString() },
{ "Type", "Friend" },
{ "Key", friend },
{ "Value", flags.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Error("[FRIENDS CONNECTOR]: Failed to store friend " + friend + " for user " + principalID + ": " + response["Message"].AsString());
return success;
}
public bool Delete(UUID principalID, string friend)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "RemoveGeneric" },
{ "OwnerID", principalID.ToString() },
{ "Type", "Friend" },
{ "Key", friend }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Error("[FRIENDS CONNECTOR]: Failed to remove friend " + friend + " for user " + principalID + ": " + response["Message"].AsString());
return success;
}
#endregion IFriendsService
private OSDArray GetFriended(UUID ownerID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetGenerics" },
{ "OwnerID", ownerID.ToString() },
{ "Type", "Friend" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
{
return (OSDArray)response["Entries"];
}
else
{
m_log.Warn("[FRIENDS CONNECTOR]: Failed to retrieve friends for user " + ownerID + ": " + response["Message"].AsString());
return new OSDArray(0);
}
}
private OSDArray GetFriendedBy(UUID ownerID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetGenerics" },
{ "Key", ownerID.ToString() },
{ "Type", "Friend" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
{
return (OSDArray)response["Entries"];
}
else
{
m_log.Warn("[FRIENDS CONNECTOR]: Failed to retrieve reverse friends for user " + ownerID + ": " + response["Message"].AsString());
return new OSDArray(0);
}
}
}
}

View File

@ -0,0 +1,47 @@
/*
* 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 Mono.Addins;
using Nini.Config;
[assembly: Addin("SimianGrid", "1.0")]
[assembly: AddinDependency("OpenSim", "0.5")]
public static class Simian
{
public static bool IsSimianEnabled(IConfigSource config, string moduleName)
{
if (config.Configs["Modules"] != null)
{
string module = config.Configs["Modules"].GetString("AuthenticationServices");
return !String.IsNullOrEmpty(module) && module.Contains("Simian");
}
return false;
}
}

View File

@ -0,0 +1,421 @@
/*
* 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.Collections.Specialized;
using System.Net;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Server.Base;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Connects region registration and neighbor lookups to the SimianGrid
/// backend
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianGridServiceConnector : IGridService, ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_serverUrl = String.Empty;
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene) { }
public void PostInitialise() { }
public void Close() { }
public SimianGridServiceConnector() { }
public string Name { get { return "SimianGridServiceConnector"; } }
public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IGridService>(this); } }
public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IGridService>(this); } }
#endregion ISharedRegionModule
public SimianGridServiceConnector(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "GridServices"))
{
IConfig gridConfig = source.Configs["GridService"];
if (gridConfig == null)
{
m_log.Error("[GRID CONNECTOR]: GridService missing from OpenSim.ini");
throw new Exception("Grid connector init error");
}
string serviceUrl = gridConfig.GetString("GridServerURI");
if (String.IsNullOrEmpty(serviceUrl))
{
m_log.Error("[GRID CONNECTOR]: No Server URI named in section GridService");
throw new Exception("Grid connector init error");
}
m_serverUrl = serviceUrl;
}
}
#region IGridService
public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
{
Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0);
Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, 4096.0);
string httpAddress = "http://" + regionInfo.ExternalHostName + ":" + regionInfo.HttpPort + "/";
OSDMap extraData = new OSDMap
{
{ "ServerURI", OSD.FromString(regionInfo.ServerURI) },
{ "InternalAddress", OSD.FromString(regionInfo.InternalEndPoint.Address.ToString()) },
{ "InternalPort", OSD.FromInteger(regionInfo.InternalEndPoint.Port) },
{ "ExternalAddress", OSD.FromString(regionInfo.ExternalEndPoint.Address.ToString()) },
{ "ExternalPort", OSD.FromInteger(regionInfo.ExternalEndPoint.Port) },
{ "MapTexture", OSD.FromUUID(regionInfo.TerrainImage) },
{ "Access", OSD.FromInteger(regionInfo.Access) },
{ "RegionSecret", OSD.FromString(regionInfo.RegionSecret) },
{ "EstateOwner", OSD.FromUUID(regionInfo.EstateOwner) },
{ "Token", OSD.FromString(regionInfo.Token) }
};
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddScene" },
{ "SceneID", regionInfo.RegionID.ToString() },
{ "Name", regionInfo.RegionName },
{ "MinPosition", minPosition.ToString() },
{ "MaxPosition", maxPosition.ToString() },
{ "Address", httpAddress },
{ "Enabled", "1" },
{ "ExtraData", OSDParser.SerializeJsonString(extraData) }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
return String.Empty;
else
return "Region registration for " + regionInfo.RegionName + " failed: " + response["Message"].AsString();
}
public bool DeregisterRegion(UUID regionID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddScene" },
{ "SceneID", regionID.ToString() },
{ "Enabled", "0" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[GRID CONNECTOR]: Region deregistration for " + regionID + " failed: " + response["Message"].AsString());
return success;
}
public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID)
{
const int NEIGHBOR_RADIUS = 128;
GridRegion region = GetRegionByUUID(scopeID, regionID);
if (region != null)
{
List<GridRegion> regions = GetRegionRange(scopeID,
region.RegionLocX - NEIGHBOR_RADIUS, region.RegionLocX + (int)Constants.RegionSize + NEIGHBOR_RADIUS,
region.RegionLocY - NEIGHBOR_RADIUS, region.RegionLocY + (int)Constants.RegionSize + NEIGHBOR_RADIUS);
for (int i = 0; i < regions.Count; i++)
{
if (regions[i].RegionID == regionID)
{
regions.RemoveAt(i);
break;
}
}
m_log.Debug("[GRID CONNECTOR]: Found " + regions.Count + " neighbors for region " + regionID);
return regions;
}
return new List<GridRegion>(0);
}
public GridRegion GetRegionByUUID(UUID scopeID, UUID regionID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetScene" },
{ "SceneID", regionID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
return ResponseToGridRegion(response);
}
else
{
m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region " + regionID);
return null;
}
}
public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
{
// Go one meter in from the requested x/y coords to avoid requesting a position
// that falls on the border of two sims
Vector3d position = new Vector3d(x + 1, y + 1, 0.0);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetScene" },
{ "Position", position.ToString() },
{ "Enabled", "1" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
return ResponseToGridRegion(response);
}
else
{
//m_log.InfoFormat("[GRID CONNECTOR]: Grid service did not find a match for region at {0},{1}",
// x / Constants.RegionSize, y / Constants.RegionSize);
return null;
}
}
public GridRegion GetRegionByName(UUID scopeID, string regionName)
{
List<GridRegion> regions = GetRegionsByName(scopeID, regionName, 1);
m_log.Debug("[GRID CONNECTOR]: Got " + regions.Count + " matches for region name " + regionName);
if (regions.Count > 0)
return regions[0];
return null;
}
public List<GridRegion> GetRegionsByName(UUID scopeID, string name, int maxNumber)
{
List<GridRegion> foundRegions = new List<GridRegion>();
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetScenes" },
{ "NameQuery", name },
{ "Enabled", "1" }
};
if (maxNumber > 0)
requestArgs["MaxNumber"] = maxNumber.ToString();
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
OSDArray array = response["Scenes"] as OSDArray;
if (array != null)
{
for (int i = 0; i < array.Count; i++)
{
GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
if (region != null)
foundRegions.Add(region);
}
}
}
return foundRegions;
}
public List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax)
{
List<GridRegion> foundRegions = new List<GridRegion>();
Vector3d minPosition = new Vector3d(xmin, ymin, 0.0);
Vector3d maxPosition = new Vector3d(xmax, ymax, 4096.0);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetScenes" },
{ "MinPosition", minPosition.ToString() },
{ "MaxPosition", maxPosition.ToString() },
{ "Enabled", "1" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
OSDArray array = response["Scenes"] as OSDArray;
if (array != null)
{
for (int i = 0; i < array.Count; i++)
{
GridRegion region = ResponseToGridRegion(array[i] as OSDMap);
if (region != null)
foundRegions.Add(region);
}
}
}
return foundRegions;
}
public List<GridRegion> GetDefaultRegions(UUID scopeID)
{
// TODO: Allow specifying the default grid location
const int DEFAULT_X = 1000 * 256;
const int DEFAULT_Y = 1000 * 256;
GridRegion defRegion = GetNearestRegion(new Vector3d(DEFAULT_X, DEFAULT_Y, 0.0), true);
if (defRegion != null)
return new List<GridRegion>(1) { defRegion };
else
return new List<GridRegion>(0);
}
public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
{
GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true);
if (defRegion != null)
return new List<GridRegion>(1) { defRegion };
else
return new List<GridRegion>(0);
}
public int GetRegionFlags(UUID scopeID, UUID regionID)
{
const int REGION_ONLINE = 4;
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetScene" },
{ "SceneID", regionID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
return response["Enabled"].AsBoolean() ? REGION_ONLINE : 0;
}
else
{
m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region " + regionID + " during region flags check");
return -1;
}
}
#endregion IGridService
private GridRegion GetNearestRegion(Vector3d position, bool onlyEnabled)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetScene" },
{ "Position", position.ToString() },
{ "FindClosest", "1" }
};
if (onlyEnabled)
requestArgs["Enabled"] = "1";
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
return ResponseToGridRegion(response);
}
else
{
m_log.Warn("[GRID CONNECTOR]: Grid service did not find a match for region at " + position);
return null;
}
}
private GridRegion ResponseToGridRegion(OSDMap response)
{
if (response == null)
return null;
OSDMap extraData = response["ExtraData"] as OSDMap;
if (extraData == null)
return null;
GridRegion region = new GridRegion();
region.RegionID = response["SceneID"].AsUUID();
region.RegionName = response["Name"].AsString();
Vector3d minPosition = response["MinPosition"].AsVector3d();
region.RegionLocX = (int)minPosition.X;
region.RegionLocY = (int)minPosition.Y;
Uri httpAddress = response["Address"].AsUri();
region.ExternalHostName = httpAddress.Host;
region.HttpPort = (uint)httpAddress.Port;
region.ServerURI = extraData["ServerURI"].AsString();
IPAddress internalAddress;
IPAddress.TryParse(extraData["InternalAddress"].AsString(), out internalAddress);
if (internalAddress == null)
internalAddress = IPAddress.Any;
region.InternalEndPoint = new IPEndPoint(internalAddress, extraData["InternalPort"].AsInteger());
region.TerrainImage = extraData["MapTexture"].AsUUID();
region.Access = (byte)extraData["Access"].AsInteger();
region.RegionSecret = extraData["RegionSecret"].AsString();
region.EstateOwner = extraData["EstateOwner"].AsUUID();
region.Token = extraData["Token"].AsString();
return region;
}
}
}

View File

@ -0,0 +1,895 @@
/*
* 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.Collections.Specialized;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Permissions bitflags
/// </summary>
[Flags]
public enum PermissionMask : uint
{
None = 0,
Transfer = 1 << 13,
Modify = 1 << 14,
Copy = 1 << 15,
Move = 1 << 19,
Damage = 1 << 20,
All = 0x7FFFFFFF
}
/// <summary>
/// Connects avatar inventories to the SimianGrid backend
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianInventoryServiceConnector : IInventoryService, ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_serverUrl = String.Empty;
private string m_userServerUrl = String.Empty;
private object m_gestureSyncRoot = new object();
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene) { }
public void PostInitialise() { }
public void Close() { }
public SimianInventoryServiceConnector() { }
public string Name { get { return "SimianInventoryServiceConnector"; } }
public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IInventoryService>(this); } }
public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IInventoryService>(this); } }
#endregion ISharedRegionModule
public SimianInventoryServiceConnector(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "InventoryServices"))
{
IConfig gridConfig = source.Configs["InventoryService"];
if (gridConfig == null)
{
m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
throw new Exception("Inventory connector init error");
}
string serviceUrl = gridConfig.GetString("InventoryServerURI");
if (String.IsNullOrEmpty(serviceUrl))
{
m_log.Error("[INVENTORY CONNECTOR]: No Server URI named in section InventoryService");
throw new Exception("Inventory connector init error");
}
m_serverUrl = serviceUrl;
gridConfig = source.Configs["UserAccountService"];
if (gridConfig != null)
{
serviceUrl = gridConfig.GetString("UserAccountServerURI");
if (!String.IsNullOrEmpty(serviceUrl))
m_userServerUrl = serviceUrl;
else
m_log.Info("[INVENTORY CONNECTOR]: No Server URI named in section UserAccountService");
}
else
{
m_log.Warn("[INVENTORY CONNECTOR]: UserAccountService missing from OpenSim.ini");
}
}
}
/// <summary>
/// Create the entire inventory for a given user
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public bool CreateUserInventory(UUID userID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddInventory" },
{ "OwnerID", userID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[INVENTORY CONNECTOR]: Inventory creation for " + userID + " failed: " + response["Message"].AsString());
return success;
}
/// <summary>
/// Gets the skeleton of the inventory -- folders only
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
public List<InventoryFolderBase> GetInventorySkeleton(UUID userID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetInventoryNode" },
{ "ItemID", userID.ToString() },
{ "OwnerID", userID.ToString() },
{ "IncludeFolders", "1" },
{ "IncludeItems", "0" },
{ "ChildrenOnly", "0" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
{
OSDArray items = (OSDArray)response["Items"];
return GetFoldersFromResponse(items, userID, true);
}
else
{
m_log.Warn("[INVENTORY CONNECTOR]: Failed to retrieve inventory skeleton for " + userID + ": " +
response["Message"].AsString());
return new List<InventoryFolderBase>(0);
}
}
/// <summary>
/// Synchronous inventory fetch.
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
[Obsolete]
public InventoryCollection GetUserInventory(UUID userID)
{
m_log.Error("[INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID);
InventoryCollection inventory = new InventoryCollection();
inventory.UserID = userID;
inventory.Folders = new List<InventoryFolderBase>();
inventory.Items = new List<InventoryItemBase>();
return inventory;
}
/// <summary>
/// Request the inventory for a user. This is an asynchronous operation that will call the callback when the
/// inventory has been received
/// </summary>
/// <param name="userID"></param>
/// <param name="callback"></param>
[Obsolete]
public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
{
m_log.Error("[INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID);
callback(new List<InventoryFolderImpl>(0), new List<InventoryItemBase>(0));
}
/// <summary>
/// Retrieve the root inventory folder for the given user.
/// </summary>
/// <param name="userID"></param>
/// <returns>null if no root folder was found</returns>
public InventoryFolderBase GetRootFolder(UUID userID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetInventoryNode" },
{ "ItemID", userID.ToString() },
{ "OwnerID", userID.ToString() },
{ "IncludeFolders", "1" },
{ "IncludeItems", "0" },
{ "ChildrenOnly", "1" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
{
OSDArray items = (OSDArray)response["Items"];
List<InventoryFolderBase> folders = GetFoldersFromResponse(items, userID, true);
if (folders.Count > 0)
return folders[0];
}
return null;
}
/// <summary>
/// Gets the user folder for the given folder-type
/// </summary>
/// <param name="userID"></param>
/// <param name="type"></param>
/// <returns></returns>
public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
{
string contentType = SLUtil.SLAssetTypeToContentType((int)type);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetFolderForType" },
{ "ContentType", contentType },
{ "OwnerID", userID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Folder"] is OSDMap)
{
OSDMap folder = (OSDMap)response["Folder"];
return new InventoryFolderBase(
folder["ID"].AsUUID(),
folder["Name"].AsString(),
folder["OwnerID"].AsUUID(),
(short)SLUtil.ContentTypeToSLAssetType(folder["ContentType"].AsString()),
folder["ParentID"].AsUUID(),
(ushort)folder["Version"].AsInteger()
);
}
else
{
m_log.Warn("[INVENTORY CONNECTOR]: Default folder not found for content type " + contentType);
return GetRootFolder(userID);
}
}
/// <summary>
/// Get an item, given by its UUID
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public InventoryItemBase GetItem(InventoryItemBase item)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetInventoryNode" },
{ "ItemID", item.ID.ToString() },
{ "OwnerID", item.Owner.ToString() },
{ "IncludeFolders", "1" },
{ "IncludeItems", "1" },
{ "ChildrenOnly", "1" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
{
List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]);
if (items.Count > 0)
{
// The requested item should be the first in this list, but loop through
// and sanity check just in case
for (int i = 0; i < items.Count; i++)
{
if (items[i].ID == item.ID)
return items[i];
}
}
}
m_log.Warn("[INVENTORY CONNECTOR]: Item " + item.ID + " owned by " + item.Owner + " not found");
return null;
}
/// <summary>
/// Get a folder, given by its UUID
/// </summary>
/// <param name="folder"></param>
/// <returns></returns>
public InventoryFolderBase GetFolder(InventoryFolderBase folder)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetInventoryNode" },
{ "ItemID", folder.ID.ToString() },
{ "OwnerID", folder.Owner.ToString() },
{ "IncludeFolders", "1" },
{ "IncludeItems", "0" },
{ "ChildrenOnly", "1" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
{
OSDArray items = (OSDArray)response["Items"];
List<InventoryFolderBase> folders = GetFoldersFromResponse(items, folder.ID, true);
if (folders.Count > 0)
return folders[0];
}
return null;
}
/// <summary>
/// Gets everything (folders and items) inside a folder
/// </summary>
/// <param name="userID"></param>
/// <param name="folderID"></param>
/// <returns></returns>
public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
{
InventoryCollection inventory = new InventoryCollection();
inventory.UserID = userID;
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetInventoryNode" },
{ "ItemID", folderID.ToString() },
{ "OwnerID", userID.ToString() },
{ "IncludeFolders", "1" },
{ "IncludeItems", "1" },
{ "ChildrenOnly", "1" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
{
OSDArray items = (OSDArray)response["Items"];
inventory.Folders = GetFoldersFromResponse(items, folderID, false);
inventory.Items = GetItemsFromResponse(items);
}
else
{
m_log.Warn("[INVENTORY CONNECTOR]: Error fetching folder " + folderID + " content for " + userID + ": " +
response["Message"].AsString());
inventory.Folders = new List<InventoryFolderBase>(0);
inventory.Items = new List<InventoryItemBase>(0);
}
return inventory;
}
/// <summary>
/// Gets the items inside a folder
/// </summary>
/// <param name="userID"></param>
/// <param name="folderID"></param>
/// <returns></returns>
public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
{
InventoryCollection inventory = new InventoryCollection();
inventory.UserID = userID;
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetInventoryNode" },
{ "ItemID", folderID.ToString() },
{ "OwnerID", userID.ToString() },
{ "IncludeFolders", "0" },
{ "IncludeItems", "1" },
{ "ChildrenOnly", "1" }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
{
OSDArray items = (OSDArray)response["Items"];
return GetItemsFromResponse(items);
}
else
{
m_log.Warn("[INVENTORY CONNECTOR]: Error fetching folder " + folderID + " for " + userID + ": " +
response["Message"].AsString());
return new List<InventoryItemBase>(0);
}
}
/// <summary>
/// Add a new folder to the user's inventory
/// </summary>
/// <param name="folder"></param>
/// <returns>true if the folder was successfully added</returns>
public bool AddFolder(InventoryFolderBase folder)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddInventoryFolder" },
{ "FolderID", folder.ID.ToString() },
{ "ParentID", folder.ParentID.ToString() },
{ "OwnerID", folder.Owner.ToString() },
{ "Name", folder.Name },
{ "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
{
m_log.Warn("[INVENTORY CONNECTOR]: Error creating folder " + folder.Name + " for " + folder.Owner + ": " +
response["Message"].AsString());
}
return success;
}
/// <summary>
/// Update a folder in the user's inventory
/// </summary>
/// <param name="folder"></param>
/// <returns>true if the folder was successfully updated</returns>
public bool UpdateFolder(InventoryFolderBase folder)
{
return AddFolder(folder);
}
/// <summary>
/// Move an inventory folder to a new location
/// </summary>
/// <param name="folder">A folder containing the details of the new location</param>
/// <returns>true if the folder was successfully moved</returns>
public bool MoveFolder(InventoryFolderBase folder)
{
return AddFolder(folder);
}
/// <summary>
/// Delete an item from the user's inventory
/// </summary>
/// <param name="item"></param>
/// <returns>true if the item was successfully deleted</returns>
//bool DeleteItem(InventoryItemBase item);
public bool DeleteFolders(UUID userID, List<UUID> folderIDs)
{
return DeleteItems(userID, folderIDs);
}
/// <summary>
/// Delete an item from the user's inventory
/// </summary>
/// <param name="item"></param>
/// <returns>true if the item was successfully deleted</returns>
public bool DeleteItems(UUID userID, List<UUID> itemIDs)
{
// TODO: RemoveInventoryNode should be replaced with RemoveInventoryNodes
bool allSuccess = true;
for (int i = 0; i < itemIDs.Count; i++)
{
UUID itemID = itemIDs[i];
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "RemoveInventoryNode" },
{ "OwnerID", userID.ToString() },
{ "ItemID", itemID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
{
m_log.Warn("[INVENTORY CONNECTOR]: Error removing item " + itemID + " for " + userID + ": " +
response["Message"].AsString());
allSuccess = false;
}
}
return allSuccess;
}
/// <summary>
/// Purge an inventory folder of all its items and subfolders.
/// </summary>
/// <param name="folder"></param>
/// <returns>true if the folder was successfully purged</returns>
public bool PurgeFolder(InventoryFolderBase folder)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "PurgeInventoryFolder" },
{ "OwnerID", folder.Owner.ToString() },
{ "FolderID", folder.ID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
{
m_log.Warn("[INVENTORY CONNECTOR]: Error purging folder " + folder.ID + " for " + folder.Owner + ": " +
response["Message"].AsString());
}
return success;
}
/// <summary>
/// Add a new item to the user's inventory
/// </summary>
/// <param name="item"></param>
/// <returns>true if the item was successfully added</returns>
public bool AddItem(InventoryItemBase item)
{
// A folder of UUID.Zero means we need to find the most appropriate home for this item
if (item.Folder == UUID.Zero)
{
InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType);
if (folder != null && folder.ID != UUID.Zero)
item.Folder = folder.ID;
else
item.Folder = item.Owner; // Root folder
}
if ((AssetType)item.AssetType == AssetType.Gesture)
UpdateGesture(item.Owner, item.ID, item.Flags == 1);
if (item.BasePermissions == 0)
m_log.WarnFormat("[INVENTORY CONNECTOR]: Adding inventory item {0} ({1}) with no base permissions", item.Name, item.ID);
OSDMap permissions = new OSDMap
{
{ "BaseMask", OSD.FromInteger(item.BasePermissions) },
{ "EveryoneMask", OSD.FromInteger(item.EveryOnePermissions) },
{ "GroupMask", OSD.FromInteger(item.GroupPermissions) },
{ "NextOwnerMask", OSD.FromInteger(item.NextPermissions) },
{ "OwnerMask", OSD.FromInteger(item.CurrentPermissions) }
};
OSDMap extraData = new OSDMap()
{
{ "Flags", OSD.FromInteger(item.Flags) },
{ "GroupID", OSD.FromUUID(item.GroupID) },
{ "GroupOwned", OSD.FromBoolean(item.GroupOwned) },
{ "SalePrice", OSD.FromInteger(item.SalePrice) },
{ "SaleType", OSD.FromInteger(item.SaleType) },
{ "Permissions", permissions }
};
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddInventoryItem" },
{ "ItemID", item.ID.ToString() },
{ "AssetID", item.AssetID.ToString() },
{ "ParentID", item.Folder.ToString() },
{ "OwnerID", item.Owner.ToString() },
{ "Name", item.Name },
{ "Description", item.Description },
{ "CreatorID", item.CreatorId },
{ "ExtraData", OSDParser.SerializeJsonString(extraData) }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
{
m_log.Warn("[INVENTORY CONNECTOR]: Error creating item " + item.Name + " for " + item.Owner + ": " +
response["Message"].AsString());
}
return success;
}
/// <summary>
/// Update an item in the user's inventory
/// </summary>
/// <param name="item"></param>
/// <returns>true if the item was successfully updated</returns>
public bool UpdateItem(InventoryItemBase item)
{
if (item.AssetID != UUID.Zero)
{
return AddItem(item);
}
else
{
// This is actually a folder update
InventoryFolderBase folder = new InventoryFolderBase(item.ID, item.Name, item.Owner, (short)item.AssetType, item.Folder, 0);
return UpdateFolder(folder);
}
}
public bool MoveItems(UUID ownerID, List<InventoryItemBase> items)
{
bool success = true;
while (items.Count > 0)
{
List<InventoryItemBase> currentItems = new List<InventoryItemBase>();
UUID destFolderID = items[0].Folder;
// Find all of the items being moved to the current destination folder
for (int i = 0; i < items.Count; i++)
{
InventoryItemBase item = items[i];
if (item.Folder == destFolderID)
currentItems.Add(item);
}
// Do the inventory move for the current items
success &= MoveItems(ownerID, items, destFolderID);
// Remove the processed items from the list
for (int i = 0; i < currentItems.Count; i++)
items.Remove(currentItems[i]);
}
return success;
}
/// <summary>
/// Does the given user have an inventory structure?
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
public bool HasInventoryForUser(UUID userID)
{
return GetRootFolder(userID) != null;
}
/// <summary>
/// Get the active gestures of the agent.
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
public List<InventoryItemBase> GetActiveGestures(UUID userID)
{
OSDArray items = FetchGestures(userID);
string[] itemIDs = new string[items.Count];
for (int i = 0; i < items.Count; i++)
itemIDs[i] = items[i].AsUUID().ToString();
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetInventoryNodes" },
{ "OwnerID", userID.ToString() },
{ "Items", String.Join(",", itemIDs) }
};
// FIXME: Implement this in SimianGrid
return new List<InventoryItemBase>(0);
}
/// <summary>
/// Get the union of permissions of all inventory items
/// that hold the given assetID.
/// </summary>
/// <param name="userID"></param>
/// <param name="assetID"></param>
/// <returns>The permissions or 0 if no such asset is found in
/// the user's inventory</returns>
public int GetAssetPermissions(UUID userID, UUID assetID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetInventoryNodes" },
{ "OwnerID", userID.ToString() },
{ "AssetID", assetID.ToString() }
};
// FIXME: Implement this in SimianGrid
return (int)PermissionMask.All;
}
private List<InventoryFolderBase> GetFoldersFromResponse(OSDArray items, UUID baseFolder, bool includeBaseFolder)
{
List<InventoryFolderBase> invFolders = new List<InventoryFolderBase>(items.Count);
for (int i = 0; i < items.Count; i++)
{
OSDMap item = items[i] as OSDMap;
if (item != null && item["Type"].AsString() == "Folder")
{
UUID folderID = item["ID"].AsUUID();
if (folderID == baseFolder && !includeBaseFolder)
continue;
invFolders.Add(new InventoryFolderBase(
folderID,
item["Name"].AsString(),
item["OwnerID"].AsUUID(),
(short)SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString()),
item["ParentID"].AsUUID(),
(ushort)item["Version"].AsInteger()
));
}
}
return invFolders;
}
private List<InventoryItemBase> GetItemsFromResponse(OSDArray items)
{
List<InventoryItemBase> invItems = new List<InventoryItemBase>(items.Count);
for (int i = 0; i < items.Count; i++)
{
OSDMap item = items[i] as OSDMap;
if (item != null && item["Type"].AsString() == "Item")
{
InventoryItemBase invItem = new InventoryItemBase();
invItem.AssetID = item["AssetID"].AsUUID();
invItem.AssetType = SLUtil.ContentTypeToSLAssetType(item["ContentType"].AsString());
invItem.CreationDate = item["CreationDate"].AsInteger();
invItem.CreatorId = item["CreatorID"].AsString();
invItem.CreatorIdAsUuid = item["CreatorID"].AsUUID();
invItem.Description = item["Description"].AsString();
invItem.Folder = item["ParentID"].AsUUID();
invItem.ID = item["ID"].AsUUID();
invItem.InvType = SLUtil.ContentTypeToSLInvType(item["ContentType"].AsString());
invItem.Name = item["Name"].AsString();
invItem.Owner = item["OwnerID"].AsUUID();
OSDMap extraData = item["ExtraData"] as OSDMap;
if (extraData != null && extraData.Count > 0)
{
invItem.Flags = extraData["Flags"].AsUInteger();
invItem.GroupID = extraData["GroupID"].AsUUID();
invItem.GroupOwned = extraData["GroupOwned"].AsBoolean();
invItem.SalePrice = extraData["SalePrice"].AsInteger();
invItem.SaleType = (byte)extraData["SaleType"].AsInteger();
OSDMap perms = extraData["Permissions"] as OSDMap;
if (perms != null)
{
invItem.BasePermissions = perms["BaseMask"].AsUInteger();
invItem.CurrentPermissions = perms["OwnerMask"].AsUInteger();
invItem.EveryOnePermissions = perms["EveryoneMask"].AsUInteger();
invItem.GroupPermissions = perms["GroupMask"].AsUInteger();
invItem.NextPermissions = perms["NextOwnerMask"].AsUInteger();
}
}
if (invItem.BasePermissions == 0)
{
m_log.InfoFormat("[INVENTORY CONNECTOR]: Forcing item permissions to full for item {0} ({1})",
invItem.Name, invItem.ID);
invItem.BasePermissions = (uint)PermissionMask.All;
invItem.CurrentPermissions = (uint)PermissionMask.All;
invItem.EveryOnePermissions = (uint)PermissionMask.All;
invItem.GroupPermissions = (uint)PermissionMask.All;
invItem.NextPermissions = (uint)PermissionMask.All;
}
invItems.Add(invItem);
}
}
return invItems;
}
private bool MoveItems(UUID ownerID, List<InventoryItemBase> items, UUID destFolderID)
{
string[] itemIDs = new string[items.Count];
for (int i = 0; i < items.Count; i++)
itemIDs[i] = items[i].ID.ToString();
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "MoveInventoryNodes" },
{ "OwnerID", ownerID.ToString() },
{ "FolderID", destFolderID.ToString() },
{ "Items", String.Join(",", itemIDs) }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
{
m_log.Warn("[INVENTORY CONNECTOR]: Failed to move " + items.Count + " items to " +
destFolderID + ": " + response["Message"].AsString());
}
return success;
}
private void UpdateGesture(UUID userID, UUID itemID, bool enabled)
{
OSDArray gestures = FetchGestures(userID);
OSDArray newGestures = new OSDArray();
for (int i = 0; i < gestures.Count; i++)
{
UUID gesture = gestures[i].AsUUID();
if (gesture != itemID)
newGestures.Add(OSD.FromUUID(gesture));
}
if (enabled)
newGestures.Add(OSD.FromUUID(itemID));
SaveGestures(userID, newGestures);
}
private OSDArray FetchGestures(UUID userID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "UserID", userID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs);
if (response["Success"].AsBoolean())
{
OSDMap user = response["User"] as OSDMap;
if (user != null && response.ContainsKey("Gestures"))
{
OSD gestures = OSDParser.DeserializeJson(response["Gestures"].AsString());
if (gestures != null && gestures is OSDArray)
return (OSDArray)gestures;
else
m_log.Error("[INVENTORY CONNECTOR]: Unrecognized active gestures data for " + userID);
}
}
else
{
m_log.Warn("[INVENTORY CONNECTOR]: Failed to fetch active gestures for " + userID + ": " +
response["Message"].AsString());
}
return new OSDArray();
}
private void SaveGestures(UUID userID, OSDArray gestures)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddUserData" },
{ "UserID", userID.ToString() },
{ "Gestures", OSDParser.SerializeJsonString(gestures) }
};
OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs);
if (!response["Success"].AsBoolean())
{
m_log.Warn("[INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " +
response["Message"].AsString());
}
}
}
}

View File

@ -0,0 +1,511 @@
/*
* 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.Collections.Specialized;
using System.Net;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Server.Base;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Connects avatar presence information (for tracking current location and
/// message routing) to the SimianGrid backend
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianPresenceServiceConnector : IPresenceService, ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_serverUrl = String.Empty;
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene) { }
public void PostInitialise() { }
public void Close() { }
public SimianPresenceServiceConnector() { }
public string Name { get { return "SimianPresenceServiceConnector"; } }
public void AddRegion(Scene scene)
{
if (!String.IsNullOrEmpty(m_serverUrl))
{
scene.RegisterModuleInterface<IPresenceService>(this);
scene.EventManager.OnMakeRootAgent += MakeRootAgentHandler;
scene.EventManager.OnNewClient += NewClientHandler;
scene.EventManager.OnSignificantClientMovement += SignificantClientMovementHandler;
LogoutRegionAgents(scene.RegionInfo.RegionID);
}
}
public void RemoveRegion(Scene scene)
{
if (!String.IsNullOrEmpty(m_serverUrl))
{
scene.UnregisterModuleInterface<IPresenceService>(this);
scene.EventManager.OnMakeRootAgent -= MakeRootAgentHandler;
scene.EventManager.OnNewClient -= NewClientHandler;
scene.EventManager.OnSignificantClientMovement -= SignificantClientMovementHandler;
LogoutRegionAgents(scene.RegionInfo.RegionID);
}
}
#endregion ISharedRegionModule
public SimianPresenceServiceConnector(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "PresenceServices"))
{
IConfig gridConfig = source.Configs["PresenceService"];
if (gridConfig == null)
{
m_log.Error("[PRESENCE CONNECTOR]: PresenceService missing from OpenSim.ini");
throw new Exception("Presence connector init error");
}
string serviceUrl = gridConfig.GetString("PresenceServerURI");
if (String.IsNullOrEmpty(serviceUrl))
{
m_log.Error("[PRESENCE CONNECTOR]: No PresenceServerURI in section PresenceService");
throw new Exception("Presence connector init error");
}
m_serverUrl = serviceUrl;
}
}
#region IPresenceService
public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
{
m_log.ErrorFormat("[PRESENCE CONNECTOR]: Login requested, UserID={0}, SessionID={1}, SecureSessionID={2}",
userID, sessionID, secureSessionID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddSession" },
{ "UserID", userID.ToString() }
};
if (sessionID != UUID.Zero)
{
requestArgs["SessionID"] = sessionID.ToString();
requestArgs["SecureSessionID"] = secureSessionID.ToString();
}
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[PRESENCE CONNECTOR]: Failed to login agent " + userID + ": " + response["Message"].AsString());
return success;
}
public bool LogoutAgent(UUID sessionID, Vector3 position, Vector3 lookAt)
{
m_log.InfoFormat("[PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "RemoveSession" },
{ "SessionID", sessionID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[PRESENCE CONNECTOR]: Failed to logout agent with sessionID " + sessionID + ": " + response["Message"].AsString());
return success;
}
public bool LogoutRegionAgents(UUID regionID)
{
m_log.InfoFormat("[PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "RemoveSessions" },
{ "SceneID", regionID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[PRESENCE CONNECTOR]: Failed to logout agents from region " + regionID + ": " + response["Message"].AsString());
return success;
}
public bool ReportAgent(UUID sessionID, UUID regionID, Vector3 position, Vector3 lookAt)
{
//m_log.DebugFormat("[PRESENCE CONNECTOR]: Updating session data for agent with sessionID " + sessionID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "UpdateSession" },
{ "SessionID", sessionID.ToString() },
{ "SceneID", regionID.ToString() },
{ "ScenePosition", position.ToString() },
{ "SceneLookAt", lookAt.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[PRESENCE CONNECTOR]: Failed to update agent session " + sessionID + ": " + response["Message"].AsString());
return success;
}
public PresenceInfo GetAgent(UUID sessionID)
{
m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting session data for agent with sessionID " + sessionID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetSession" },
{ "SessionID", sessionID.ToString() }
};
OSDMap sessionResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
if (sessionResponse["Success"].AsBoolean())
{
UUID userID = sessionResponse["UserID"].AsUUID();
m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting user data for " + userID);
requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "UserID", userID.ToString() }
};
OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
if (userResponse["Success"].AsBoolean())
return ResponseToPresenceInfo(sessionResponse, userResponse);
else
m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
}
else
{
m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve session " + sessionID + ": " + sessionResponse["Message"].AsString());
}
return null;
}
public PresenceInfo[] GetAgents(string[] userIDs)
{
List<PresenceInfo> presences = new List<PresenceInfo>(userIDs.Length);
for (int i = 0; i < userIDs.Length; i++)
{
UUID userID;
if (UUID.TryParse(userIDs[i], out userID) && userID != UUID.Zero)
presences.AddRange(GetSessions(userID));
}
return presences.ToArray();
}
public bool SetHomeLocation(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
{
m_log.DebugFormat("[PRESENCE CONNECTOR]: Setting home location for user " + userID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddUserData" },
{ "UserID", userID.ToString() },
{ "HomeLocation", SerializeLocation(regionID, position, lookAt) }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[PRESENCE CONNECTOR]: Failed to set home location for " + userID + ": " + response["Message"].AsString());
return success;
}
#endregion IPresenceService
#region Presence Detection
private void MakeRootAgentHandler(ScenePresence sp)
{
m_log.DebugFormat("[PRESENCE DETECTOR]: Detected root presence {0} in {1}", sp.UUID, sp.Scene.RegionInfo.RegionName);
ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
SetLastLocation(sp.UUID, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
}
private void NewClientHandler(IClientAPI client)
{
client.OnConnectionClosed += LogoutHandler;
}
private void SignificantClientMovementHandler(IClientAPI client)
{
ScenePresence sp;
if (client.Scene is Scene && ((Scene)client.Scene).TryGetAvatar(client.AgentId, out sp))
ReportAgent(sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
}
private void LogoutHandler(IClientAPI client)
{
if (client.IsLoggingOut)
{
client.OnConnectionClosed -= LogoutHandler;
object obj;
if (client.Scene.TryGetAvatar(client.AgentId, out obj) && obj is ScenePresence)
{
// The avatar is still in the scene, we can get the exact logout position
ScenePresence sp = (ScenePresence)obj;
SetLastLocation(client.AgentId, client.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
}
else
{
// The avatar was already removed from the scene, store LastLocation using the most recent session data
m_log.Warn("[PRESENCE]: " + client.Name + " has already been removed from the scene, storing approximate LastLocation");
SetLastLocation(client.SessionId);
}
LogoutAgent(client.SessionId, Vector3.Zero, Vector3.UnitX);
}
}
#endregion Presence Detection
#region Helpers
private OSDMap GetUserData(UUID userID)
{
m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting user data for " + userID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "UserID", userID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["User"] is OSDMap)
return response;
else
m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + response["Message"].AsString());
return null;
}
private OSDMap GetSessionData(UUID sessionID)
{
m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting session data for session " + sessionID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetSession" },
{ "SessionID", sessionID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
return response;
else
m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve session data for session " + sessionID);
return null;
}
private List<PresenceInfo> GetSessions(UUID userID)
{
List<PresenceInfo> presences = new List<PresenceInfo>(1);
OSDMap userResponse = GetUserData(userID);
if (userResponse != null)
{
m_log.DebugFormat("[PRESENCE CONNECTOR]: Requesting sessions for " + userID);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetSession" },
{ "UserID", userID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
PresenceInfo presence = ResponseToPresenceInfo(response, userResponse);
if (presence != null)
presences.Add(presence);
}
else
{
m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve sessions for " + userID + ": " + response["Message"].AsString());
}
}
return presences;
}
/// <summary>
/// Fetch the last known avatar location with GetSession and persist it
/// as user data with AddUserData
/// </summary>
private bool SetLastLocation(UUID sessionID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetSession" },
{ "SessionID", sessionID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (success)
{
UUID userID = response["UserID"].AsUUID();
UUID sceneID = response["SceneID"].AsUUID();
Vector3 position = response["ScenePosition"].AsVector3();
Vector3 lookAt = response["SceneLookAt"].AsVector3();
return SetLastLocation(userID, sceneID, position, lookAt);
}
else
{
m_log.Warn("[PRESENCE CONNECTOR]: Failed to retrieve presence information for session " + sessionID +
" while saving last location: " + response["Message"].AsString());
}
return success;
}
private bool SetLastLocation(UUID userID, UUID sceneID, Vector3 position, Vector3 lookAt)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddUserData" },
{ "UserID", userID.ToString() },
{ "LastLocation", SerializeLocation(sceneID, position, lookAt) }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.Warn("[PRESENCE CONNECTOR]: Failed to set last location for " + userID + ": " + response["Message"].AsString());
return success;
}
private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse)
{
if (sessionResponse == null)
return null;
PresenceInfo info = new PresenceInfo();
info.Online = true;
info.UserID = sessionResponse["UserID"].AsUUID().ToString();
info.RegionID = sessionResponse["SceneID"].AsUUID();
info.Position = sessionResponse["ScenePosition"].AsVector3();
info.LookAt = sessionResponse["SceneLookAt"].AsVector3();
if (userResponse != null && userResponse["User"] is OSDMap)
{
OSDMap user = (OSDMap)userResponse["User"];
info.Login = user["LastLoginDate"].AsDate();
info.Logout = user["LastLogoutDate"].AsDate();
DeserializeLocation(user["HomeLocation"].AsString(), out info.HomeRegionID, out info.HomePosition, out info.HomeLookAt);
}
return info;
}
private string SerializeLocation(UUID regionID, Vector3 position, Vector3 lookAt)
{
return "{" + String.Format("\"SceneID\":\"{0}\",\"Position\":\"{1}\",\"LookAt\":\"{2}\"", regionID, position, lookAt) + "}";
}
private bool DeserializeLocation(string location, out UUID regionID, out Vector3 position, out Vector3 lookAt)
{
OSDMap map = null;
try { map = OSDParser.DeserializeJson(location) as OSDMap; }
catch { }
if (map != null)
{
regionID = map["SceneID"].AsUUID();
if (Vector3.TryParse(map["Position"].AsString(), out position) &&
Vector3.TryParse(map["LookAt"].AsString(), out lookAt))
{
return true;
}
}
regionID = UUID.Zero;
position = Vector3.Zero;
lookAt = Vector3.Zero;
return false;
}
#endregion Helpers
}
}

View File

@ -0,0 +1,435 @@
/*
* 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.Collections.Specialized;
using System.Reflection;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using OpenSim.Framework;
using OpenSim.Framework.Client;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Avatar profile flags
/// </summary>
[Flags]
public enum ProfileFlags : uint
{
AllowPublish = 1,
MaturePublish = 2,
Identified = 4,
Transacted = 8,
Online = 16
}
/// <summary>
/// Connects avatar profile and classified queries to the SimianGrid
/// backend
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianProfiles : INonSharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_serverUrl = String.Empty;
#region INonSharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene) { }
public void Close() { }
public SimianProfiles() { }
public string Name { get { return "SimianProfiles"; } }
public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { CheckEstateManager(scene); scene.EventManager.OnClientConnect += ClientConnectHandler; } }
public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.EventManager.OnClientConnect -= ClientConnectHandler; } }
#endregion INonSharedRegionModule
public SimianProfiles(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "UserAccountServices"))
{
IConfig gridConfig = source.Configs["UserAccountService"];
if (gridConfig == null)
{
m_log.Error("[PROFILES]: UserAccountService missing from OpenSim.ini");
throw new Exception("Profiles init error");
}
string serviceUrl = gridConfig.GetString("UserAccountServerURI");
if (String.IsNullOrEmpty(serviceUrl))
{
m_log.Error("[PROFILES]: No UserAccountServerURI in section UserAccountService");
throw new Exception("Profiles init error");
}
if (!serviceUrl.EndsWith("/"))
serviceUrl = serviceUrl + '/';
m_serverUrl = serviceUrl;
}
}
private void ClientConnectHandler(IClientCore clientCore)
{
if (clientCore is IClientAPI)
{
IClientAPI client = (IClientAPI)clientCore;
// Classifieds
client.AddGenericPacketHandler("avatarclassifiedsrequest", AvatarClassifiedsRequestHandler);
client.OnClassifiedInfoRequest += ClassifiedInfoRequestHandler;
client.OnClassifiedInfoUpdate += ClassifiedInfoUpdateHandler;
client.OnClassifiedDelete += ClassifiedDeleteHandler;
// Picks
client.AddGenericPacketHandler("avatarpicksrequest", HandleAvatarPicksRequest);
client.AddGenericPacketHandler("pickinforequest", HandlePickInfoRequest);
client.OnPickInfoUpdate += PickInfoUpdateHandler;
client.OnPickDelete += PickDeleteHandler;
// Notes
client.AddGenericPacketHandler("avatarnotesrequest", HandleAvatarNotesRequest);
client.OnAvatarNotesUpdate += AvatarNotesUpdateHandler;
// Profiles
client.OnRequestAvatarProperties += RequestAvatarPropertiesHandler;
client.OnUpdateAvatarProperties += UpdateAvatarPropertiesHandler;
client.OnAvatarInterestUpdate += AvatarInterestUpdateHandler;
client.OnUserInfoRequest += UserInfoRequestHandler;
client.OnUpdateUserInfo += UpdateUserInfoHandler;
}
}
#region Classifieds
private void AvatarClassifiedsRequestHandler(Object sender, string method, List<String> args)
{
if (!(sender is IClientAPI))
return;
IClientAPI client = (IClientAPI)sender;
UUID targetAvatarID;
if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
{
m_log.Error("[PROFILES]: Unrecognized arguments for " + method);
return;
}
// FIXME: Query the generic key/value store for classifieds
client.SendAvatarClassifiedReply(targetAvatarID, new Dictionary<UUID, string>(0));
}
private void ClassifiedInfoRequestHandler(UUID classifiedID, IClientAPI client)
{
// FIXME: Fetch this info
client.SendClassifiedInfoReply(classifiedID, UUID.Zero, 0, Utils.DateTimeToUnixTime(DateTime.UtcNow + TimeSpan.FromDays(1)),
0, String.Empty, String.Empty, UUID.Zero, 0, UUID.Zero, String.Empty, Vector3.Zero, String.Empty, 0, 0);
}
private void ClassifiedInfoUpdateHandler(UUID classifiedID, uint category, string name, string description,
UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags, int price,
IClientAPI client)
{
// FIXME: Save this info
}
private void ClassifiedDeleteHandler(UUID classifiedID, IClientAPI client)
{
// FIXME: Delete the specified classified ad
}
#endregion Classifieds
#region Picks
private void HandleAvatarPicksRequest(Object sender, string method, List<String> args)
{
if (!(sender is IClientAPI))
return;
IClientAPI client = (IClientAPI)sender;
UUID targetAvatarID;
if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
{
m_log.Error("[PROFILES]: Unrecognized arguments for " + method);
return;
}
// FIXME: Fetch these
client.SendAvatarPicksReply(targetAvatarID, new Dictionary<UUID, string>(0));
}
private void HandlePickInfoRequest(Object sender, string method, List<String> args)
{
if (!(sender is IClientAPI))
return;
IClientAPI client = (IClientAPI)sender;
UUID avatarID;
UUID pickID;
if (args.Count < 2 || !UUID.TryParse(args[0], out avatarID) || !UUID.TryParse(args[1], out pickID))
{
m_log.Error("[PROFILES]: Unrecognized arguments for " + method);
return;
}
// FIXME: Fetch this
client.SendPickInfoReply(pickID, avatarID, false, UUID.Zero, String.Empty, String.Empty, UUID.Zero, String.Empty,
String.Empty, String.Empty, Vector3.Zero, 0, false);
}
private void PickInfoUpdateHandler(IClientAPI client, UUID pickID, UUID creatorID, bool topPick, string name,
string desc, UUID snapshotID, int sortOrder, bool enabled)
{
// FIXME: Save this
}
private void PickDeleteHandler(IClientAPI client, UUID pickID)
{
// FIXME: Delete
}
#endregion Picks
#region Notes
private void HandleAvatarNotesRequest(Object sender, string method, List<String> args)
{
if (!(sender is IClientAPI))
return;
IClientAPI client = (IClientAPI)sender;
UUID targetAvatarID;
if (args.Count < 1 || !UUID.TryParse(args[0], out targetAvatarID))
{
m_log.Error("[PROFILES]: Unrecognized arguments for " + method);
return;
}
// FIXME: Fetch this
client.SendAvatarNotesReply(targetAvatarID, String.Empty);
}
private void AvatarNotesUpdateHandler(IClientAPI client, UUID targetID, string notes)
{
// FIXME: Save this
}
#endregion Notes
#region Profiles
private void RequestAvatarPropertiesHandler(IClientAPI client, UUID avatarID)
{
OSDMap user = FetchUserData(avatarID);
ProfileFlags flags = ProfileFlags.AllowPublish | ProfileFlags.MaturePublish;
if (user != null)
{
OSDMap about = null;
if (user.ContainsKey("LLAbout"))
{
try { about = OSDParser.DeserializeJson(user["LLAbout"].AsString()) as OSDMap; }
catch { }
}
if (about == null)
about = new OSDMap(0);
// Check if this user is a grid operator
byte[] charterMember;
if (user["AccessLevel"].AsInteger() >= 200)
charterMember = Utils.StringToBytes("Operator");
else
charterMember = Utils.EmptyBytes;
// Check if the user is online
if (client.Scene is Scene)
{
OpenSim.Services.Interfaces.PresenceInfo[] presences = ((Scene)client.Scene).PresenceService.GetAgents(new string[] { avatarID.ToString() });
if (presences != null && presences.Length > 0)
flags |= ProfileFlags.Online;
}
// Check if the user is identified
if (user["Identified"].AsBoolean())
flags |= ProfileFlags.Identified;
client.SendAvatarProperties(avatarID, about["About"].AsString(), user["CreationDate"].AsDate().ToString("M/d/yyyy",
System.Globalization.CultureInfo.InvariantCulture), charterMember, about["FLAbout"].AsString(), (uint)flags,
about["FLImage"].AsUUID(), about["Image"].AsUUID(), about["URL"].AsString(), user["Partner"].AsUUID());
}
else
{
m_log.Warn("[PROFILES]: Failed to fetch profile information for " + client.Name + ", returning default values");
client.SendAvatarProperties(avatarID, String.Empty, "1/1/1970", Utils.EmptyBytes,
String.Empty, (uint)flags, UUID.Zero, UUID.Zero, String.Empty, UUID.Zero);
}
}
private void UpdateAvatarPropertiesHandler(IClientAPI client, UserProfileData profileData)
{
OSDMap map = new OSDMap
{
{ "About", OSD.FromString(profileData.AboutText) },
{ "Image", OSD.FromUUID(profileData.Image) },
{ "FLAbout", OSD.FromString(profileData.FirstLifeAboutText) },
{ "FLImage", OSD.FromUUID(profileData.FirstLifeImage) },
{ "URL", OSD.FromString(profileData.ProfileUrl) }
};
AddUserData(client.AgentId, "LLAbout", map);
}
private void AvatarInterestUpdateHandler(IClientAPI client, uint wantmask, string wanttext, uint skillsmask,
string skillstext, string languages)
{
OSDMap map = new OSDMap
{
{ "WantMask", OSD.FromInteger(wantmask) },
{ "WantText", OSD.FromString(wanttext) },
{ "SkillsMask", OSD.FromInteger(skillsmask) },
{ "SkillsText", OSD.FromString(skillstext) },
{ "Languages", OSD.FromString(languages) }
};
AddUserData(client.AgentId, "LLInterests", map);
}
private void UserInfoRequestHandler(IClientAPI client)
{
m_log.Error("[PROFILES]: UserInfoRequestHandler");
// Fetch this user's e-mail address
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "UserID", client.AgentId.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
string email = response["Email"].AsString();
if (!response["Success"].AsBoolean())
m_log.Warn("[PROFILES]: GetUser failed during a user info request for " + client.Name);
client.SendUserInfoReply(false, true, email);
}
private void UpdateUserInfoHandler(bool imViaEmail, bool visible, IClientAPI client)
{
m_log.Info("[PROFILES]: Ignoring user info update from " + client.Name);
}
#endregion Profiles
/// <summary>
/// Sanity checks regions for a valid estate owner at startup
/// </summary>
private void CheckEstateManager(Scene scene)
{
EstateSettings estate = scene.RegionInfo.EstateSettings;
if (estate.EstateOwner == UUID.Zero)
{
// Attempt to lookup the grid admin
UserAccount admin = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, UUID.Zero);
if (admin != null)
{
m_log.InfoFormat("[PROFILES]: Setting estate {0} (ID: {1}) owner to {2}", estate.EstateName,
estate.EstateID, admin.Name);
estate.EstateOwner = admin.PrincipalID;
estate.Save();
}
else
{
m_log.WarnFormat("[PROFILES]: Estate {0} (ID: {1}) does not have an owner", estate.EstateName, estate.EstateID);
}
}
}
private bool AddUserData(UUID userID, string key, OSDMap value)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddUserData" },
{ "UserID", userID.ToString() },
{ key, OSDParser.SerializeJsonString(value) }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (!success)
m_log.WarnFormat("[PROFILES]: Failed to add user data with key {0} for {1}: {2}", key, userID, response["Message"].AsString());
return success;
}
private OSDMap FetchUserData(UUID userID)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "UserID", userID.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean() && response["User"] is OSDMap)
{
return (OSDMap)response["User"];
}
else
{
m_log.Error("[PROFILES]: Failed to fetch user data for " + userID + ": " + response["Message"].AsString());
}
return null;
}
}
}

View File

@ -0,0 +1,311 @@
/*
* 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.Collections.Specialized;
using System.IO;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using log4net;
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
namespace OpenSim.Services.Connectors.SimianGrid
{
/// <summary>
/// Connects user account data (creating new users, looking up existing
/// users) to the SimianGrid backend
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class SimianUserAccountServiceConnector : IUserAccountService, ISharedRegionModule
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private string m_serverUrl = String.Empty;
private ExpiringCache<UUID, UserAccount> m_accountCache;
#region ISharedRegionModule
public Type ReplaceableInterface { get { return null; } }
public void RegionLoaded(Scene scene) { }
public void PostInitialise() { }
public void Close() { }
public SimianUserAccountServiceConnector() { }
public string Name { get { return "SimianUserAccountServiceConnector"; } }
public void AddRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.RegisterModuleInterface<IUserAccountService>(this); } }
public void RemoveRegion(Scene scene) { if (!String.IsNullOrEmpty(m_serverUrl)) { scene.UnregisterModuleInterface<IUserAccountService>(this); } }
#endregion ISharedRegionModule
public SimianUserAccountServiceConnector(IConfigSource source)
{
Initialise(source);
}
public void Initialise(IConfigSource source)
{
if (Simian.IsSimianEnabled(source, "UserAccountServices"))
{
IConfig assetConfig = source.Configs["UserAccountService"];
if (assetConfig == null)
{
m_log.Error("[ACCOUNT CONNECTOR]: UserAccountService missing from OpenSim.ini");
throw new Exception("User account connector init error");
}
string serviceURI = assetConfig.GetString("UserAccountServerURI");
if (String.IsNullOrEmpty(serviceURI))
{
m_log.Error("[ACCOUNT CONNECTOR]: No UserAccountServerURI in section UserAccountService, skipping SimianUserAccountServiceConnector");
throw new Exception("User account connector init error");
}
m_accountCache = new ExpiringCache<UUID, UserAccount>();
m_serverUrl = serviceURI;
}
}
public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "Name", firstName + ' ' + lastName }
};
return GetUser(requestArgs);
}
public UserAccount GetUserAccount(UUID scopeID, string email)
{
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "Email", email }
};
return GetUser(requestArgs);
}
public UserAccount GetUserAccount(UUID scopeID, UUID userID)
{
// Cache check
UserAccount account;
if (m_accountCache.TryGetValue(userID, out account))
return account;
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUser" },
{ "UserID", userID.ToString() }
};
return GetUser(requestArgs);
}
public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
{
List<UserAccount> accounts = new List<UserAccount>();
m_log.DebugFormat("[ACCOUNT CONNECTOR]: Searching for user accounts with name query " + query);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "GetUsers" },
{ "NameQuery", query }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
OSDArray array = response["Users"] as OSDArray;
if (array != null && array.Count > 0)
{
for (int i = 0; i < array.Count; i++)
{
UserAccount account = ResponseToUserAccount(array[i] as OSDMap);
if (account != null)
accounts.Add(account);
}
}
else
{
m_log.Warn("[ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format");
}
}
else
{
m_log.Warn("[ACCOUNT CONNECTOR]: Failed to search for account data by name " + query);
}
return accounts;
}
public bool StoreUserAccount(UserAccount data)
{
m_log.InfoFormat("[ACCOUNT CONNECTOR]: Storing user account for " + data.Name);
NameValueCollection requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddUser" },
{ "UserID", data.PrincipalID.ToString() },
{ "Name", data.Name },
{ "Email", data.Email },
{ "AccessLevel", data.UserLevel.ToString() }
};
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
m_log.InfoFormat("[ACCOUNT CONNECTOR]: Storing user account data for " + data.Name);
requestArgs = new NameValueCollection
{
{ "RequestMethod", "AddUserData" },
{ "UserID", data.PrincipalID.ToString() },
{ "CreationDate", data.Created.ToString() },
{ "UserFlags", data.UserFlags.ToString() },
{ "UserTitle", data.UserTitle }
};
response = WebUtil.PostToService(m_serverUrl, requestArgs);
bool success = response["Success"].AsBoolean();
if (success)
{
// Cache the user account info
m_accountCache.AddOrUpdate(data.PrincipalID, data, DateTime.Now + TimeSpan.FromMinutes(2.0d));
}
else
{
m_log.Warn("[ACCOUNT CONNECTOR]: Failed to store user account data for " + data.Name + ": " + response["Message"].AsString());
}
return success;
}
else
{
m_log.Warn("[ACCOUNT CONNECTOR]: Failed to store user account for " + data.Name + ": " + response["Message"].AsString());
}
return false;
}
/// <summary>
/// Helper method for the various ways of retrieving a user account
/// </summary>
/// <param name="requestArgs">Service query parameters</param>
/// <returns>A UserAccount object on success, null on failure</returns>
private UserAccount GetUser(NameValueCollection requestArgs)
{
string lookupValue = (requestArgs.Count > 1) ? requestArgs[1] : "(Unknown)";
m_log.DebugFormat("[ACCOUNT CONNECTOR]: Looking up user account with query: " + lookupValue);
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
if (response["Success"].AsBoolean())
{
OSDMap user = response["User"] as OSDMap;
if (user != null)
return ResponseToUserAccount(user);
else
m_log.Warn("[ACCOUNT CONNECTOR]: Account search failed, response data was in an invalid format");
}
else
{
m_log.Warn("[ACCOUNT CONNECTOR]: Failed to lookup user account with query: " + lookupValue);
}
return null;
}
/// <summary>
/// Convert a User object in LLSD format to a UserAccount
/// </summary>
/// <param name="response">LLSD containing user account data</param>
/// <returns>A UserAccount object on success, null on failure</returns>
private UserAccount ResponseToUserAccount(OSDMap response)
{
if (response == null)
return null;
UserAccount account = new UserAccount();
account.PrincipalID = response["UserID"].AsUUID();
account.Created = response["CreationDate"].AsInteger();
account.Email = response["Email"].AsString();
account.ServiceURLs = new Dictionary<string, object>(0);
account.UserFlags = response["UserFlags"].AsInteger();
account.UserLevel = response["AccessLevel"].AsInteger();
account.UserTitle = response["UserTitle"].AsString();
GetFirstLastName(response["Name"].AsString(), out account.FirstName, out account.LastName);
// Cache the user account info
m_accountCache.AddOrUpdate(account.PrincipalID, account, DateTime.Now + TimeSpan.FromMinutes(2.0d));
return account;
}
/// <summary>
/// Convert a name with a single space in it to a first and last name
/// </summary>
/// <param name="name">A full name such as "John Doe"</param>
/// <param name="firstName">First name</param>
/// <param name="lastName">Last name (surname)</param>
private static void GetFirstLastName(string name, out string firstName, out string lastName)
{
if (String.IsNullOrEmpty(name))
{
firstName = String.Empty;
lastName = String.Empty;
}
else
{
string[] names = name.Split(' ');
if (names.Length == 2)
{
firstName = names[0];
lastName = names[1];
}
else
{
firstName = String.Empty;
lastName = name;
}
}
}
}
}

View File

@ -113,6 +113,7 @@ namespace OpenSim.Services.Connectors
public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID) public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID)
{ {
m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUSerAccount {0}", userID);
Dictionary<string, object> sendData = new Dictionary<string, object>(); Dictionary<string, object> sendData = new Dictionary<string, object>();
//sendData["SCOPEID"] = scopeID.ToString(); //sendData["SCOPEID"] = scopeID.ToString();
sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();

View File

@ -123,8 +123,7 @@ namespace OpenSim.Services.GridService
if ((rflags & OpenSim.Data.RegionFlags.Reservation) != 0) if ((rflags & OpenSim.Data.RegionFlags.Reservation) != 0)
{ {
// Regions reserved for the null key cannot be taken. // Regions reserved for the null key cannot be taken.
// if ((string)region.Data["PrincipalID"] == UUID.Zero.ToString())
if (region.Data["PrincipalID"] == UUID.Zero.ToString())
return "Region location us reserved"; return "Region location us reserved";
// Treat it as an auth request // Treat it as an auth request
@ -132,7 +131,6 @@ namespace OpenSim.Services.GridService
// NOTE: Fudging the flags value here, so these flags // NOTE: Fudging the flags value here, so these flags
// should not be used elsewhere. Don't optimize // should not be used elsewhere. Don't optimize
// this with the later retrieval of the same flags! // this with the later retrieval of the same flags!
//
rflags |= OpenSim.Data.RegionFlags.Authenticate; rflags |= OpenSim.Data.RegionFlags.Authenticate;
} }
@ -489,7 +487,7 @@ namespace OpenSim.Services.GridService
f |= (OpenSim.Data.RegionFlags)val; f |= (OpenSim.Data.RegionFlags)val;
} }
} }
catch (Exception e) catch (Exception)
{ {
MainConsole.Instance.Output("Error in flag specification: " + p); MainConsole.Instance.Output("Error in flag specification: " + p);
} }

View File

@ -168,10 +168,11 @@ namespace OpenSim.Services.GridService
} }
// Sanity check. // Sanity check.
IPAddress ipaddr = null; //IPAddress ipaddr = null;
try try
{ {
ipaddr = Util.GetHostFromDNS(host); //ipaddr = Util.GetHostFromDNS(host);
Util.GetHostFromDNS(host);
} }
catch catch
{ {

View File

@ -1,4 +1,31 @@
using System; /*
* 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.Collections.Generic;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;

View File

@ -140,14 +140,20 @@ namespace OpenSim.Services.Interfaces
UserAccount GetUserAccount(UUID scopeID, UUID userID); UserAccount GetUserAccount(UUID scopeID, UUID userID);
UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName); UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName);
UserAccount GetUserAccount(UUID scopeID, string Email); UserAccount GetUserAccount(UUID scopeID, string Email);
// Returns the list of avatars that matches both the search
// criterion and the scope ID passed /// <summary>
// /// Returns the list of avatars that matches both the search criterion and the scope ID passed
/// </summary>
/// <param name="scopeID"></param>
/// <param name="query"></param>
/// <returns></returns>
List<UserAccount> GetUserAccounts(UUID scopeID, string query); List<UserAccount> GetUserAccounts(UUID scopeID, string query);
// Store the data given, wich replaces the sotred data, therefore /// <summary>
// must be complete. /// Store the data given, wich replaces the sotred data, therefore must be complete.
// /// </summary>
/// <param name="data"></param>
/// <returns></returns>
bool StoreUserAccount(UserAccount data); bool StoreUserAccount(UserAccount data);
} }
} }

View File

@ -47,9 +47,9 @@ namespace OpenSim.Services.LLLoginService
{ {
public class LLFailedLoginResponse : OpenSim.Services.Interfaces.FailedLoginResponse public class LLFailedLoginResponse : OpenSim.Services.Interfaces.FailedLoginResponse
{ {
string m_key; protected string m_key;
string m_value; protected string m_value;
string m_login; protected string m_login;
public static LLFailedLoginResponse UserProblem; public static LLFailedLoginResponse UserProblem;
public static LLFailedLoginResponse AuthorizationProblem; public static LLFailedLoginResponse AuthorizationProblem;

View File

@ -1,4 +1,31 @@
using System; /*
* 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.Collections.Generic;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
@ -24,24 +51,24 @@ namespace OpenSim.Services.LLLoginService
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static bool Initialized = false; private static bool Initialized = false;
private IUserAccountService m_UserAccountService; protected IUserAccountService m_UserAccountService;
private IAuthenticationService m_AuthenticationService; protected IAuthenticationService m_AuthenticationService;
private IInventoryService m_InventoryService; protected IInventoryService m_InventoryService;
private IGridService m_GridService; protected IGridService m_GridService;
private IPresenceService m_PresenceService; protected IPresenceService m_PresenceService;
private ISimulationService m_LocalSimulationService; private ISimulationService m_LocalSimulationService;
private ISimulationService m_RemoteSimulationService; private ISimulationService m_RemoteSimulationService;
private ILibraryService m_LibraryService; protected ILibraryService m_LibraryService;
private IFriendsService m_FriendsService; protected IFriendsService m_FriendsService;
private IAvatarService m_AvatarService; protected IAvatarService m_AvatarService;
private IUserAgentService m_UserAgentService; private IUserAgentService m_UserAgentService;
private GatekeeperServiceConnector m_GatekeeperConnector; private GatekeeperServiceConnector m_GatekeeperConnector;
private string m_DefaultRegionName; private string m_DefaultRegionName;
private string m_WelcomeMessage; protected string m_WelcomeMessage;
private bool m_RequireInventory; private bool m_RequireInventory;
private int m_MinLoginLevel; protected int m_MinLoginLevel;
private string m_GatekeeperURL; private string m_GatekeeperURL;
IConfig m_LoginServerConfig; IConfig m_LoginServerConfig;
@ -259,7 +286,7 @@ namespace OpenSim.Services.LLLoginService
} }
} }
private GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt) protected GridRegion FindDestination(UserAccount account, PresenceInfo pinfo, UUID sessionID, string startLocation, out GridRegion gatekeeper, out string where, out Vector3 position, out Vector3 lookAt)
{ {
m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation); m_log.DebugFormat("[LLOGIN SERVICE]: FindDestination for start location {0}", startLocation);
@ -470,7 +497,7 @@ namespace OpenSim.Services.LLLoginService
} }
} }
private AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar, protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar,
UUID session, UUID secureSession, Vector3 position, string currentWhere, out string where, out string reason) UUID session, UUID secureSession, Vector3 position, string currentWhere, out string where, out string reason)
{ {
where = currentWhere; where = currentWhere;

View File

@ -72,6 +72,10 @@ namespace OpenSim.Services.PresenceService
data.Data["HomeRegionID"] = d[0].Data["HomeRegionID"]; data.Data["HomeRegionID"] = d[0].Data["HomeRegionID"];
data.Data["HomePosition"] = d[0].Data["HomePosition"]; data.Data["HomePosition"] = d[0].Data["HomePosition"];
data.Data["HomeLookAt"] = d[0].Data["HomeLookAt"]; data.Data["HomeLookAt"] = d[0].Data["HomeLookAt"];
data.Data["Position"] = d[0].Data["Position"];
data.Data["LookAt"] = d[0].Data["LookAt"];
data.RegionID = d[0].RegionID;
} }
else else
{ {

View File

@ -200,7 +200,9 @@ namespace OpenSim.Services.UserAccountService
} }
if (d.Length < 1) if (d.Length < 1)
{
return null; return null;
}
return MakeUserAccount(d[0]); return MakeUserAccount(d[0]);
} }

View File

@ -0,0 +1,46 @@
/*
* 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.Collections.Generic;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Services.Interfaces;
namespace OpenSim.Tests.Common.Mock
{
public class MockUserAccountService : IUserAccountService
{
public MockUserAccountService(IConfigSource config) {}
public UserAccount GetUserAccount(UUID scopeID, UUID userID) { return new UserAccount(); }
public UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName) { return new UserAccount(); }
public UserAccount GetUserAccount(UUID scopeID, string Email) { return new UserAccount(); }
public List<UserAccount> GetUserAccounts(UUID scopeID, string query) { return new List<UserAccount>(); }
public bool StoreUserAccount(UserAccount data) { return true; }
}
}

View File

@ -179,15 +179,16 @@ namespace OpenSim.Tests.Common.Setup
StartAssetService(testScene, true); StartAssetService(testScene, true);
else else
StartAssetService(testScene, false); StartAssetService(testScene, false);
if (realServices.Contains("inventory")) if (realServices.Contains("inventory"))
StartInventoryService(testScene, true); StartInventoryService(testScene, true);
else else
StartInventoryService(testScene, false); StartInventoryService(testScene, false);
if (realServices.Contains("grid")) if (realServices.Contains("grid"))
StartGridService(testScene, true); StartGridService(testScene, true);
if (realServices.Contains("useraccounts"))
StartUserAccountService(testScene, true);
StartUserAccountService(testScene, realServices.Contains("useraccounts"));
} }
// If not, make sure the shared module gets references to this new scene // If not, make sure the shared module gets references to this new scene
else else
@ -196,9 +197,13 @@ namespace OpenSim.Tests.Common.Setup
m_assetService.RegionLoaded(testScene); m_assetService.RegionLoaded(testScene);
m_inventoryService.AddRegion(testScene); m_inventoryService.AddRegion(testScene);
m_inventoryService.RegionLoaded(testScene); m_inventoryService.RegionLoaded(testScene);
m_userAccountService.AddRegion(testScene);
m_userAccountService.RegionLoaded(testScene);
} }
m_inventoryService.PostInitialise(); m_inventoryService.PostInitialise();
m_assetService.PostInitialise(); m_assetService.PostInitialise();
m_userAccountService.PostInitialise();
testScene.SetModuleInterfaces(); testScene.SetModuleInterfaces();
@ -210,6 +215,14 @@ namespace OpenSim.Tests.Common.Setup
testScene.PhysicsScene testScene.PhysicsScene
= physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test"); = physicsPluginManager.GetPhysicsScene("basicphysics", "ZeroMesher", new IniConfigSource(), "test");
// It's really not a good idea to use static variables as they carry over between tests, leading to
// problems that are extremely hard to debug. Really, these static fields need to be eliminated -
// tests using multiple regions that need to share modules need to find another solution.
m_assetService = null;
m_inventoryService = null;
m_gridService = null;
m_userAccountService = null;
return testScene; return testScene;
} }
@ -273,6 +286,11 @@ namespace OpenSim.Tests.Common.Setup
//testScene.AddRegionModule(m_gridService.Name, m_gridService); //testScene.AddRegionModule(m_gridService.Name, m_gridService);
} }
/// <summary>
/// Start a user account service, whether real or mock
/// </summary>
/// <param name="testScene"></param>
/// <param name="real">Starts a real service if true, a mock service if not</param>
private static void StartUserAccountService(Scene testScene, bool real) private static void StartUserAccountService(Scene testScene, bool real)
{ {
IConfigSource config = new IniConfigSource(); IConfigSource config = new IniConfigSource();
@ -280,8 +298,14 @@ namespace OpenSim.Tests.Common.Setup
config.AddConfig("UserAccountService"); config.AddConfig("UserAccountService");
config.Configs["Modules"].Set("UserAccountServices", "LocalUserAccountServicesConnector"); config.Configs["Modules"].Set("UserAccountServices", "LocalUserAccountServicesConnector");
config.Configs["UserAccountService"].Set("StorageProvider", "OpenSim.Data.Null.dll"); config.Configs["UserAccountService"].Set("StorageProvider", "OpenSim.Data.Null.dll");
if (real) if (real)
config.Configs["UserAccountService"].Set("LocalServiceModule", "OpenSim.Services.UserAccountService.dll:UserAccountService"); config.Configs["UserAccountService"].Set(
"LocalServiceModule", "OpenSim.Services.UserAccountService.dll:UserAccountService");
else
config.Configs["UserAccountService"].Set(
"LocalServiceModule", "OpenSim.Tests.Common.dll:MockUserAccountService");
if (m_userAccountService == null) if (m_userAccountService == null)
{ {
ISharedRegionModule userAccountService = new LocalUserAccountServicesConnector(); ISharedRegionModule userAccountService = new LocalUserAccountServicesConnector();
@ -292,10 +316,9 @@ namespace OpenSim.Tests.Common.Setup
// config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:TestGridService"); // config.Configs["GridService"].Set("LocalServiceModule", "OpenSim.Tests.Common.dll:TestGridService");
m_userAccountService.AddRegion(testScene); m_userAccountService.AddRegion(testScene);
m_userAccountService.RegionLoaded(testScene); m_userAccountService.RegionLoaded(testScene);
//testScene.AddRegionModule(m_gridService.Name, m_gridService); testScene.AddRegionModule(m_userAccountService.Name, m_userAccountService);
} }
/// <summary> /// <summary>
/// Setup modules for a scene using their default settings. /// Setup modules for a scene using their default settings.
/// </summary> /// </summary>

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -1263,6 +1263,7 @@
;Include-HGStandalone = "config-include/StandaloneHypergrid.ini" ;Include-HGStandalone = "config-include/StandaloneHypergrid.ini"
;Include-Grid = "config-include/Grid.ini" ;Include-Grid = "config-include/Grid.ini"
;Include-HGGrid = "config-include/GridHypergrid.ini" ;Include-HGGrid = "config-include/GridHypergrid.ini"
;Include-SimianGrid = "config-include/SimianGrid.ini"
; Then choose ; Then choose
; config-include/StandaloneCommon.ini.example (if you're in standlone) OR ; config-include/StandaloneCommon.ini.example (if you're in standlone) OR

View File

@ -0,0 +1,57 @@
;;
;; Please don't change this file.
;; All optional settings are in GridCommon.ini.example,
;; which you can copy and change.
;;
;;
;; In GridCommon.ini, these are the URLs you would use if SimianGrid is
;; installed at http://www.mygrid.com/Grid/
;;
; AssetServerURI = "http://www.mygrid.com/Grid/?id="
; InventoryServerURI = "http://www.mygrid.com/Grid/"
; AvatarServerURI = "http://www.mygrid.com/Grid/"
; PresenceServerURI = "http://www.mygrid.com/Grid/"
; UserAccountServerURI = "http://www.mygrid.com/Grid/"
; AuthenticationServerURI = "http://www.mygrid.com/Grid/"
; FriendsServerURI = "http://www.mygrid.com/Grid/"
[Includes]
Include-Common = "config-include/GridCommon.ini"
[Modules]
GridServices = "OpenSim.Services.Connectors.dll:SimianGridServiceConnector"
PresenceServices = "OpenSim.Services.Connectors.dll:SimianPresenceServiceConnector"
UserAccountServices = "OpenSim.Services.Connectors.dll:SimianGridUserAccountServiceConnector"
AuthenticationServices = "OpenSim.Services.Connectors.dll:SimianAuthenticationServiceConnector"
AssetServices = "OpenSim.Services.Connectors.dll:SimianAssetServiceConnector"
InventoryServices = "OpenSim.Services.Connectors.dll:SimianInventoryServiceConnector"
AvatarServices = "OpenSim.Services.Connectors.dll:SimianAvatarServiceConnector"
NeighbourServices = "RemoteNeighbourServicesConnector"
SimulationServices = "RemoteSimulationConnectorModule"
EntityTransferModule = "BasicEntityTransferModule"
InventoryAccessModule = "BasicInventoryAccessModule"
LandServiceInConnector = true
NeighbourServiceInConnector = true
SimulationServiceInConnector = true
LibraryModule = false
AssetCaching = "FlotsamAssetCache"
[Friends]
Connector = "OpenSim.Services.Connectors.dll:SimianFriendsServiceConnector"
[GridService]
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
StorageProvider = "OpenSim.Data.Null.dll:NullRegionData"
[LibraryService]
LocalServiceModule = "OpenSim.Services.InventoryService.dll:LibraryService"
LibraryName = "OpenSim Library"
DefaultLibrary = "./inventory/Libraries.xml"
[AssetService]
DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll"
AssetLoaderArgs = "assets/AssetSets.xml"

View File

@ -12,6 +12,7 @@
GridServices = "LocalGridServicesConnector" GridServices = "LocalGridServicesConnector"
PresenceServices = "LocalPresenceServicesConnector" PresenceServices = "LocalPresenceServicesConnector"
UserAccountServices = "LocalUserAccountServicesConnector" UserAccountServices = "LocalUserAccountServicesConnector"
GridUserServices = "LocalGridUserServicesConnector"
SimulationServices = "LocalSimulationConnectorModule" SimulationServices = "LocalSimulationConnectorModule"
AvatarServices = "LocalAvatarServicesConnector" AvatarServices = "LocalAvatarServicesConnector"
EntityTransferModule = "BasicEntityTransferModule" EntityTransferModule = "BasicEntityTransferModule"
@ -32,14 +33,12 @@
[AvatarService] [AvatarService]
LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService" LocalServiceModule = "OpenSim.Services.AvatarService.dll:AvatarService"
ConnectionString = "URI=file:avatars.db,version=3"
[AuthorizationService] [AuthorizationService]
LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService" LocalServiceModule = "OpenSim.Services.AuthorizationService.dll:AuthorizationService"
[AuthenticationService] [AuthenticationService]
LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" LocalServiceModule = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
ConnectionString = "URI=file:auth.db,version=3"
[GridService] [GridService]
LocalServiceModule = "OpenSim.Services.GridService.dll:GridService" LocalServiceModule = "OpenSim.Services.GridService.dll:GridService"
@ -52,7 +51,6 @@
[UserAccountService] [UserAccountService]
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService"
ConnectionString = "URI=file:userprofiles.db,version=3"
;; These are for creating new accounts ;; These are for creating new accounts
AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService" AuthenticationService = "OpenSim.Services.AuthenticationService.dll:PasswordAuthenticationService"
@ -60,9 +58,11 @@
GridService = "OpenSim.Services.GridService.dll:GridService" GridService = "OpenSim.Services.GridService.dll:GridService"
InventoryService = "OpenSim.Services.InventoryService.dll:InventoryService" InventoryService = "OpenSim.Services.InventoryService.dll:InventoryService"
[GridUserService]
LocalServiceModule = "OpenSim.Services.UserAccountService.dll:GridUserService"
[FriendsService] [FriendsService]
LocalServiceModule = "OpenSim.Services.FriendsService.dll" LocalServiceModule = "OpenSim.Services.FriendsService.dll"
ConnectionString = "URI=file:friends.db,version=3"
[Friends] [Friends]
Connector = "OpenSim.Services.FriendsService.dll" Connector = "OpenSim.Services.FriendsService.dll"

View File

@ -1,19 +1,24 @@
; This is the main configuration file for standalone OpenSim instances
[DatabaseService] [DatabaseService]
; ;
; ### Choose the DB ; ### Choose the DB
; ;
;--- For SQLite
StorageProvider = "OpenSim.Data.SQLite.dll" ; SQLite
;--- For MySql ; Uncomment this line if you want to use sqlite storage
Include-Storage = "config-include/storage/SQLiteStandalone.ini";
; For MySql.
; Uncomment these lines if you want to use mysql storage
; Change the connection string to your db details
;StorageProvider = "OpenSim.Data.MySQL.dll" ;StorageProvider = "OpenSim.Data.MySQL.dll"
;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;" ;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;"
[AssetService] [AssetService]
DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll"
AssetLoaderArgs = "assets/AssetSets.xml" AssetLoaderArgs = "assets/AssetSets.xml"
[Modules] [Modules]
;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists. ;; Choose 0 or 1 cache modules, and the corresponding config file, if it exists.
;; Copy the config .example file into your own .ini file and change configs there ;; Copy the config .example file into your own .ini file and change configs there
@ -38,7 +43,7 @@
StorageProvider = "OpenSim.Data.Null.dll:NullRegionData" StorageProvider = "OpenSim.Data.Null.dll:NullRegionData"
;;--- For MySql region storage (alternative) ;;--- For MySql region storage (alternative)
;StorageProvider = "OpenSim.Data.MySQL.dll:MySqlRegionData" ;StorageProvider = "OpenSim.Data.MySQL.dll:MySqlRegionData"
;ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=***;"
;; Next, we can specify properties of regions, including default and fallback regions ;; Next, we can specify properties of regions, including default and fallback regions
;; The syntax is: Region_<RegioName> = "<flags>" ;; The syntax is: Region_<RegioName> = "<flags>"
;; where <flags> can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut ;; where <flags> can be DefaultRegion, FallbackRegion, NoDirectLogin, Persistent, LockedOut

View File

@ -0,0 +1,16 @@
; These are the initialization settings for running OpenSim Standalone with an SQLite database
[DatabaseService]
StorageProvider = "OpenSim.Data.SQLite.dll"
[AvatarService]
ConnectionString = "URI=file:avatars.db,version=3"
[AuthenticationService]
ConnectionString = "URI=file:auth.db,version=3"
[UserAccountService]
ConnectionString = "URI=file:userprofiles.db,version=3"
[FriendsService]
ConnectionString = "URI=file:friends.db,version=3"

Binary file not shown.

View File

@ -959,7 +959,9 @@
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/> <Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/> <Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Server.Base"/> <Reference name="OpenSim.Server.Base"/>
<Reference name="Mono.Addins" />
<Reference name="Nini.dll" /> <Reference name="Nini.dll" />
<Reference name="log4net.dll"/> <Reference name="log4net.dll"/>
<Reference name="XMLRPC.dll" /> <Reference name="XMLRPC.dll" />