Merge branch 'master' into careminster

Conflicts:
	OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
	OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
	OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
	OpenSim/Tests/Common/Mock/TestClient.cs
avinationmerge
Melanie 2012-03-31 02:18:02 +01:00
commit f3132c45d9
34 changed files with 943 additions and 424 deletions

View File

@ -71,6 +71,7 @@ what it is today.
* CharlieO * CharlieO
* ChrisDown * ChrisDown
* Chris Yeoh (IBM) * Chris Yeoh (IBM)
* controlbreak
* coyled * coyled
* Daedius * Daedius
* Dong Jun Lan (IBM) * Dong Jun Lan (IBM)

View File

@ -104,6 +104,11 @@ namespace OpenSim.Data.MSSQL
{ {
return SqlDbType.BigInt; return SqlDbType.BigInt;
} }
if (type == typeof(DateTime))
{
return SqlDbType.DateTime;
}
return SqlDbType.VarChar; return SqlDbType.VarChar;
} }

View File

@ -28,6 +28,9 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using log4net;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Data; using OpenSim.Data;
@ -36,12 +39,26 @@ namespace OpenSim.Data.Null
{ {
public class NullFriendsData : IFriendsData public class NullFriendsData : IFriendsData
{ {
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static List<FriendsData> m_Data = new List<FriendsData>(); private static List<FriendsData> m_Data = new List<FriendsData>();
public NullFriendsData(string connectionString, string realm) public NullFriendsData(string connectionString, string realm)
{ {
} }
/// <summary>
/// Clear all friends data
/// </summary>
/// <remarks>
/// This is required by unit tests to clear the static data between test runs.
/// </remarks>
public static void Clear()
{
lock (m_Data)
m_Data.Clear();
}
public FriendsData[] GetFriends(UUID principalID) public FriendsData[] GetFriends(UUID principalID)
{ {
return GetFriends(principalID.ToString()); return GetFriends(principalID.ToString());
@ -55,6 +72,8 @@ namespace OpenSim.Data.Null
/// <param name="values"></param> /// <param name="values"></param>
/// <returns></returns> /// <returns></returns>
public FriendsData[] GetFriends(string userID) public FriendsData[] GetFriends(string userID)
{
lock (m_Data)
{ {
List<FriendsData> lst = m_Data.FindAll(fdata => List<FriendsData> lst = m_Data.FindAll(fdata =>
{ {
@ -66,11 +85,19 @@ namespace OpenSim.Data.Null
lst.ForEach(f => lst.ForEach(f =>
{ {
FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID); FriendsData f2 = m_Data.Find(candidateF2 => f.Friend == candidateF2.PrincipalID);
if (f2 != null) { f.Data["TheirFlags"] = f2.Data["Flags"]; } if (f2 != null)
f.Data["TheirFlags"] = f2.Data["Flags"];
// m_log.DebugFormat(
// "[NULL FRIENDS DATA]: Got {0} {1} {2} for {3}",
// f.Friend, f.Data["Flags"], f2 != null ? f.Data["TheirFlags"] : "not found!", f.PrincipalID);
}); });
// m_log.DebugFormat("[NULL FRIENDS DATA]: Got {0} friends for {1}", lst.Count, userID);
return lst.ToArray(); return lst.ToArray();
} }
}
return new FriendsData[0]; return new FriendsData[0];
} }
@ -80,6 +107,10 @@ namespace OpenSim.Data.Null
if (data == null) if (data == null)
return false; return false;
// m_log.DebugFormat(
// "[NULL FRIENDS DATA]: Storing {0} {1} {2}", data.PrincipalID, data.Friend, data.Data["Flags"]);
lock (m_Data)
m_Data.Add(data); m_Data.Add(data);
return true; return true;
@ -91,6 +122,8 @@ namespace OpenSim.Data.Null
} }
public bool Delete(string userID, string friendID) public bool Delete(string userID, string friendID)
{
lock (m_Data)
{ {
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); }); List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
if (lst != null) if (lst != null)
@ -98,10 +131,15 @@ namespace OpenSim.Data.Null
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; }); FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
if (friendID != null) if (friendID != null)
{ {
// m_log.DebugFormat(
// "[NULL FRIENDS DATA]: Deleting friend {0} {1} for {2}",
// friend.Friend, friend.Data["Flags"], friend.PrincipalID);
m_Data.Remove(friend); m_Data.Remove(friend);
return true; return true;
} }
} }
}
return false; return false;
} }

View File

@ -110,7 +110,6 @@ namespace OpenSim.Data.Null
return false; return false;
} }
public PresenceData[] Get(string field, string data) public PresenceData[] Get(string field, string data)
{ {
if (Instance != this) if (Instance != this)

View File

@ -244,10 +244,10 @@ namespace OpenSim.Data.Tests
SceneObjectPart[] newparts = newsog.Parts; SceneObjectPart[] newparts = newsog.Parts;
Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))"); Assert.That(newparts.Length,Is.EqualTo(4), "Assert.That(newparts.Length,Is.EqualTo(4))");
Assert.That(newsog.HasChildPrim(tmp0), "Assert.That(newsog.HasChildPrim(tmp0))"); Assert.That(newsog.ContainsPart(tmp0), "Assert.That(newsog.ContainsPart(tmp0))");
Assert.That(newsog.HasChildPrim(tmp1), "Assert.That(newsog.HasChildPrim(tmp1))"); Assert.That(newsog.ContainsPart(tmp1), "Assert.That(newsog.ContainsPart(tmp1))");
Assert.That(newsog.HasChildPrim(tmp2), "Assert.That(newsog.HasChildPrim(tmp2))"); Assert.That(newsog.ContainsPart(tmp2), "Assert.That(newsog.ContainsPart(tmp2))");
Assert.That(newsog.HasChildPrim(tmp3), "Assert.That(newsog.HasChildPrim(tmp3))"); Assert.That(newsog.ContainsPart(tmp3), "Assert.That(newsog.ContainsPart(tmp3))");
} }
[Test] [Test]

View File

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Framework
{
public interface ICallingCardModule
{
UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID);
}
}

View File

@ -301,9 +301,9 @@ namespace OpenSim.Framework
public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID); public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);
public delegate void FriendActionDelegate( public delegate void FriendActionDelegate(
IClientAPI remoteClient, UUID agentID, UUID transactionID, List<UUID> callingCardFolders); IClientAPI remoteClient, UUID transactionID, List<UUID> callingCardFolders);
public delegate void FriendshipTermination(IClientAPI remoteClient, UUID agentID, UUID ExID); public delegate void FriendshipTermination(IClientAPI remoteClient, UUID ExID);
public delegate void MoneyTransferRequest( public delegate void MoneyTransferRequest(
UUID sourceID, UUID destID, int amount, int transactionType, string description); UUID sourceID, UUID destID, int amount, int transactionType, string description);
@ -464,7 +464,7 @@ namespace OpenSim.Framework
public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes); public delegate void AvatarNotesUpdate(IClientAPI client, UUID targetID, string notes);
public delegate void MuteListRequest(IClientAPI client, uint muteCRC); public delegate void MuteListRequest(IClientAPI client, uint muteCRC);
public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages); public delegate void AvatarInterestUpdate(IClientAPI client, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages);
public delegate void GrantUserFriendRights(IClientAPI client, UUID requester, UUID target, int rights); public delegate void GrantUserFriendRights(IClientAPI client, UUID target, int rights);
public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client); public delegate void PlacesQuery(UUID QueryID, UUID TransactionID, string QueryText, uint QueryFlags, byte Category, string SimName, IClientAPI client);
public delegate void AgentFOV(IClientAPI client, float verticalAngle); public delegate void AgentFOV(IClientAPI client, float verticalAngle);

View File

@ -39,7 +39,8 @@ namespace OpenSim
RC1, RC1,
RC2, RC2,
Release, Release,
Post_Fixes Post_Fixes,
Extended
} }
public static string Version public static string Version

View File

@ -5913,7 +5913,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// My guess is this is the folder to stick the calling card into // My guess is this is the folder to stick the calling card into
List<UUID> callingCardFolders = new List<UUID>(); List<UUID> callingCardFolders = new List<UUID>();
UUID agentID = afriendpack.AgentData.AgentID;
UUID transactionID = afriendpack.TransactionBlock.TransactionID; UUID transactionID = afriendpack.TransactionBlock.TransactionID;
for (int fi = 0; fi < afriendpack.FolderData.Length; fi++) for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
@ -5924,10 +5923,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest; FriendActionDelegate handlerApproveFriendRequest = OnApproveFriendRequest;
if (handlerApproveFriendRequest != null) if (handlerApproveFriendRequest != null)
{ {
handlerApproveFriendRequest(this, agentID, transactionID, callingCardFolders); handlerApproveFriendRequest(this, transactionID, callingCardFolders);
} }
return true;
return true;
} }
private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack) private bool HandlerDeclineFriendship(IClientAPI sender, Packet Pack)
@ -5946,7 +5945,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (OnDenyFriendRequest != null) if (OnDenyFriendRequest != null)
{ {
OnDenyFriendRequest(this, OnDenyFriendRequest(this,
dfriendpack.AgentData.AgentID,
dfriendpack.TransactionBlock.TransactionID, dfriendpack.TransactionBlock.TransactionID,
null); null);
} }
@ -5966,14 +5964,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
#endregion #endregion
UUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
UUID exFriendID = tfriendpack.ExBlock.OtherID; UUID exFriendID = tfriendpack.ExBlock.OtherID;
FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship; FriendshipTermination TerminateFriendshipHandler = OnTerminateFriendship;
if (TerminateFriendshipHandler != null) if (TerminateFriendshipHandler != null)
{ {
TerminateFriendshipHandler(this, listOwnerAgentID, exFriendID); TerminateFriendshipHandler(this, exFriendID);
return true; return true;
} }
return false; return false;
} }
@ -11378,12 +11376,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
} }
#endregion #endregion
GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights; GrantUserFriendRights GrantUserRightsHandler = OnGrantUserRights;
if (GrantUserRightsHandler != null) if (GrantUserRightsHandler != null)
GrantUserRightsHandler(this, GrantUserRightsHandler(this,
GrantUserRights.AgentData.AgentID,
GrantUserRights.Rights[0].AgentRelated, GrantUserRights.Rights[0].AgentRelated,
GrantUserRights.Rights[0].RelatedRights); GrantUserRights.Rights[0].RelatedRights);
return true; return true;
} }

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;
@ -10,7 +37,7 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using Mono.Addins; using Mono.Addins;
namespace Careminster.XCallingCard.Modules namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")]
public class CallingCardModule : ISharedRegionModule, ICallingCardModule public class CallingCardModule : ISharedRegionModule, ICallingCardModule

View File

@ -51,12 +51,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
public class FriendsModule : ISharedRegionModule, IFriendsModule public class FriendsModule : ISharedRegionModule, IFriendsModule
{ {
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected bool m_Enabled = false; protected bool m_Enabled = false;
protected class UserFriendData protected class UserFriendData
{ {
public UUID PrincipalID; public UUID PrincipalID;
public FriendInfo[] Friends; public FriendInfo[] Friends;
public int Refcount;
public bool IsFriend(string friend) public bool IsFriend(string friend)
{ {
@ -71,7 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected List<Scene> m_Scenes = new List<Scene>(); protected List<Scene> m_Scenes = new List<Scene>();
@ -108,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
protected IFriendsService FriendsService public IFriendsService FriendsService
{ {
get get
{ {
@ -155,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
InitModule(config); InitModule(config);
m_Enabled = true; m_Enabled = true;
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name); m_log.DebugFormat("[FRIENDS MODULE]: {0} enabled.", Name);
} }
} }
} }
@ -200,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (!m_Enabled) if (!m_Enabled)
return; return;
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); // m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
m_Scenes.Add(scene); m_Scenes.Add(scene);
scene.RegisterModuleInterface<IFriendsModule>(this); scene.RegisterModuleInterface<IFriendsModule>(this);
@ -211,14 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
scene.EventManager.OnClientLogin += OnClientLogin; scene.EventManager.OnClientLogin += OnClientLogin;
} }
public virtual void RegionLoaded(Scene scene) public virtual void RegionLoaded(Scene scene) {}
{
scene.AddCommand(
"Friends", this, "friends show cache",
"friends show cache [<first-name> <last-name>]",
"Show the friends cache for the given user",
HandleFriendsShowCacheCommand);
}
public void RemoveRegion(Scene scene) public void RemoveRegion(Scene scene)
{ {
@ -240,13 +235,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion #endregion
public virtual uint GetFriendPerms(UUID principalID, UUID friendID) public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID)
{ {
FriendInfo[] friends = GetFriends(principalID); FriendInfo[] friends = GetFriendsFromCache(principalID);
FriendInfo finfo = GetFriend(friends, friendID); FriendInfo finfo = GetFriend(friends, friendID);
if (finfo != null) if (finfo != null)
{ {
return (uint)finfo.TheirFlags; return finfo.TheirFlags;
} }
return 0; return 0;
@ -254,15 +249,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnNewClient(IClientAPI client) private void OnNewClient(IClientAPI client)
{ {
if (client.SceneAgent.IsChildAgent)
return;
client.OnInstantMessage += OnInstantMessage; client.OnInstantMessage += OnInstantMessage;
client.OnApproveFriendRequest += OnApproveFriendRequest; client.OnApproveFriendRequest += OnApproveFriendRequest;
client.OnDenyFriendRequest += OnDenyFriendRequest; client.OnDenyFriendRequest += OnDenyFriendRequest;
client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID); client.OnTerminateFriendship += RemoveFriendship;
client.OnGrantUserRights += OnGrantUserRights; client.OnGrantUserRights += GrantRights;
// We need to cache information for child agents as well as root agents so that friend edit/move/delete
// permissions will work across borders where both regions are on different simulators.
//
// Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and // Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and
// return misleading results from the still empty friends cache. // return misleading results from the still empty friends cache.
// If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls // If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls
@ -283,15 +278,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
UUID agentID = client.AgentId; UUID agentID = client.AgentId;
lock (m_Friends) lock (m_Friends)
{ {
UserFriendData friendsData = new UserFriendData(); UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData))
{
friendsData.Refcount++;
return false;
}
else
{
friendsData = new UserFriendData();
friendsData.PrincipalID = agentID; friendsData.PrincipalID = agentID;
friendsData.Friends = GetFriendsFromService(client); friendsData.Friends = GetFriendsFromService(client);
friendsData.Refcount = 1;
m_Friends[agentID] = friendsData; m_Friends[agentID] = friendsData;
}
return true; return true;
} }
}
}
private void OnClientClosed(UUID agentID, Scene scene) private void OnClientClosed(UUID agentID, Scene scene)
{ {
@ -300,17 +304,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
// do this for root agents closing out // do this for root agents closing out
StatusChange(agentID, false); StatusChange(agentID, false);
}
lock (m_Friends) lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData))
{
friendsData.Refcount--;
if (friendsData.Refcount <= 0)
m_Friends.Remove(agentID); m_Friends.Remove(agentID);
} }
} }
}
private void OnMakeRootAgent(ScenePresence sp) private void OnMakeRootAgent(ScenePresence sp)
{ {
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event RecacheFriends(sp.ControllingClient);
// is on the critical path for transferring an avatar from one region to another.
CacheFriends(sp.ControllingClient);
} }
private void OnClientLogin(IClientAPI client) private void OnClientLogin(IClientAPI client)
@ -339,18 +349,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Send the friends online // Send the friends online
List<UUID> online = GetOnlineFriends(agentID); List<UUID> online = GetOnlineFriends(agentID);
if (online.Count > 0)
{
m_log.DebugFormat(
"[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
client.Name, client.Scene.RegionInfo.RegionName, online.Count);
if (online.Count > 0)
client.SendAgentOnline(online.ToArray()); client.SendAgentOnline(online.ToArray());
}
// Send outstanding friendship offers // Send outstanding friendship offers
List<string> outstanding = new List<string>(); List<string> outstanding = new List<string>();
FriendInfo[] friends = GetFriends(agentID); FriendInfo[] friends = GetFriendsFromCache(agentID);
foreach (FriendInfo fi in friends) foreach (FriendInfo fi in friends)
{ {
if (fi.TheirFlags == -1) if (fi.TheirFlags == -1)
@ -406,23 +411,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
List<UUID> GetOnlineFriends(UUID userID) List<UUID> GetOnlineFriends(UUID userID)
{ {
List<string> friendList = new List<string>(); List<string> friendList = new List<string>();
List<UUID> online = new List<UUID>();
FriendInfo[] friends = GetFriends(userID); FriendInfo[] friends = GetFriendsFromCache(userID);
foreach (FriendInfo fi in friends) foreach (FriendInfo fi in friends)
{ {
if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
friendList.Add(fi.Friend); friendList.Add(fi.Friend);
} }
List<UUID> online = new List<UUID>();
if (friendList.Count > 0) if (friendList.Count > 0)
GetOnlineFriends(userID, friendList, online); GetOnlineFriends(userID, friendList, online);
// m_log.DebugFormat(
// "[FRIENDS MODULE]: User {0} has {1} friends online", userID, online.Count);
return online; return online;
} }
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online) protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
{ {
// m_log.DebugFormat(
// "[FRIENDS MODULE]: Looking for online presence of {0} users for {1}", friendList.Count, userID);
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
foreach (PresenceInfo pi in presence) foreach (PresenceInfo pi in presence)
{ {
@ -473,13 +485,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
/// <param name="online"></param> /// <param name="online"></param>
private void StatusChange(UUID agentID, bool online) private void StatusChange(UUID agentID, bool online)
{ {
FriendInfo[] friends = GetFriends(agentID); FriendInfo[] friends = GetFriendsFromCache(agentID);
if (friends.Length > 0) if (friends.Length > 0)
{ {
List<FriendInfo> friendList = new List<FriendInfo>(); List<FriendInfo> friendList = new List<FriendInfo>();
foreach (FriendInfo fi in friends) foreach (FriendInfo fi in friends)
{ {
if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1)) if (((fi.MyFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
friendList.Add(fi); friendList.Add(fi);
} }
@ -545,7 +557,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName); m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName);
// Check that the friendship doesn't exist yet // Check that the friendship doesn't exist yet
FriendInfo[] finfos = GetFriends(principalID); FriendInfo[] finfos = GetFriendsFromCache(principalID);
if (finfos != null) if (finfos != null)
{ {
FriendInfo f = GetFriend(finfos, friendID); FriendInfo f = GetFriend(finfos, friendID);
@ -598,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
} }
protected virtual void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) protected virtual void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
{ {
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
@ -616,7 +628,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
// Update the local cache. // Update the local cache.
CacheFriends(client); RecacheFriends(client);
// //
// Notify the friend // Notify the friend
@ -643,18 +655,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) private void OnDenyFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
{ {
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", client.AgentId, friendID);
DeleteFriendship(agentID, friendID); DeleteFriendship(client.AgentId, friendID);
// //
// Notify the friend // Notify the friend
// //
// Try local // Try local
if (LocalFriendshipDenied(agentID, client.Name, friendID)) if (LocalFriendshipDenied(client.AgentId, client.Name, friendID))
return; return;
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@ -665,7 +677,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
if (region != null) if (region != null)
m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID); m_FriendsSimConnector.FriendshipDenied(region, client.AgentId, client.Name, friendID);
else else
m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID); m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID);
} }
@ -678,7 +690,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.SendAlertMessage("Unable to terminate friendship on this sim."); client.SendAlertMessage("Unable to terminate friendship on this sim.");
// Update local cache // Update local cache
CacheFriends(client); RecacheFriends(client);
client.SendTerminateFriend(exfriendID); client.SendTerminateFriend(exfriendID);
@ -702,23 +714,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) public void GrantRights(IClientAPI remoteClient, UUID friendID, int rights)
{ {
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); UUID requester = remoteClient.AgentId;
FriendInfo[] friends = GetFriends(remoteClient.AgentId); m_log.DebugFormat(
"[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}",
requester, rights, friendID);
FriendInfo[] friends = GetFriendsFromCache(requester);
if (friends.Length == 0) if (friends.Length == 0)
{ {
return; return;
} }
// Let's find the friend in this user's friend list // Let's find the friend in this user's friend list
FriendInfo friend = GetFriend(friends, target); FriendInfo friend = GetFriend(friends, friendID);
if (friend != null) // Found it if (friend != null) // Found it
{ {
// Store it on the DB // Store it on the DB
if (!StoreRights(requester, target, rights)) if (!StoreRights(requester, friendID, rights))
{ {
remoteClient.SendAlertMessage("Unable to grant rights."); remoteClient.SendAlertMessage("Unable to grant rights.");
return; return;
@ -729,17 +745,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friend.MyFlags = rights; friend.MyFlags = rights;
// Always send this back to the original client // Always send this back to the original client
remoteClient.SendChangeUserRights(requester, target, rights); remoteClient.SendChangeUserRights(requester, friendID, rights);
// //
// Notify the friend // Notify the friend
// //
// Try local // Try local
if (LocalGrantRights(requester, target, myFlags, rights)) if (LocalGrantRights(requester, friendID, myFlags, rights))
return; return;
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0) if (friendSessions != null && friendSessions.Length > 0)
{ {
PresenceInfo friendSession = friendSessions[0]; PresenceInfo friendSession = friendSessions[0];
@ -748,12 +764,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
// TODO: You might want to send the delta to save the lookup // TODO: You might want to send the delta to save the lookup
// on the other end!! // on the other end!!
m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights); m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights);
} }
} }
} }
else else
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester); {
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", friendID, requester);
}
} }
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
@ -797,9 +815,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
ccm.CreateCallingCard(friendID, userID, UUID.Zero); ccm.CreateCallingCard(friendID, userID, UUID.Zero);
} }
// Update the local cache // Update the local cache
CacheFriends(friendClient); RecacheFriends(friendClient);
// we're done // we're done
return true; return true;
@ -832,7 +849,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// the friend in this sim as root agent // the friend in this sim as root agent
friendClient.SendTerminateFriend(exfriendID); friendClient.SendTerminateFriend(exfriendID);
// update local cache // update local cache
CacheFriends(friendClient); RecacheFriends(friendClient);
// we're done // we're done
return true; return true;
} }
@ -891,20 +908,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion #endregion
#region Get / Set friends in several flavours #region Get / Set friends in several flavours
/// <summary>
/// Get friends from local cache only public FriendInfo[] GetFriendsFromCache(UUID userID)
/// </summary>
/// <param name="agentID"></param>
/// <returns>
/// An empty array if the user has no friends or friends have not been cached.
/// </returns>
protected FriendInfo[] GetFriends(UUID agentID)
{ {
UserFriendData friendsData; UserFriendData friendsData;
lock (m_Friends) lock (m_Friends)
{ {
if (m_Friends.TryGetValue(agentID, out friendsData)) if (m_Friends.TryGetValue(userID, out friendsData))
return friendsData.Friends; return friendsData.Friends;
} }
@ -922,23 +933,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Update local cache // Update local cache
lock (m_Friends) lock (m_Friends)
{ {
FriendInfo[] friends = GetFriends(friendID); FriendInfo[] friends = GetFriendsFromCache(friendID);
FriendInfo finfo = GetFriend(friends, userID); FriendInfo finfo = GetFriend(friends, userID);
finfo.TheirFlags = rights; finfo.TheirFlags = rights;
} }
} }
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client) public virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
{ {
return FriendsService.GetFriends(client.AgentId); return FriendsService.GetFriends(client.AgentId);
} }
/// <summary> protected void RecacheFriends(IClientAPI client)
/// Are friends cached on this simulator for a particular user? {
/// </summary> // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
/// <param name="userID"></param> // is on the critical path for transferring an avatar from one region to another.
/// <returns></returns> UUID agentID = client.AgentId;
protected bool AreFriendsCached(UUID userID) lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData))
friendsData.Friends = GetFriendsFromService(client);
}
}
public bool AreFriendsCached(UUID userID)
{ {
lock (m_Friends) lock (m_Friends)
return m_Friends.ContainsKey(userID); return m_Friends.ContainsKey(userID);
@ -957,8 +976,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected virtual void StoreFriendships(UUID agentID, UUID friendID) protected virtual void StoreFriendships(UUID agentID, UUID friendID)
{ {
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1); FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), (int)FriendRights.CanSeeOnline);
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1); FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), (int)FriendRights.CanSeeOnline);
} }
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID) protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
@ -969,61 +988,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
#endregion #endregion
protected void HandleFriendsShowCacheCommand(string module, string[] cmd)
{
if (cmd.Length != 5)
{
MainConsole.Instance.OutputFormat("Usage: friends show cache [<first-name> <last-name>]");
return;
}
string firstName = cmd[3];
string lastName = cmd[4];
IUserManagement umModule = m_Scenes[0].RequestModuleInterface<IUserManagement>();
UUID userId = umModule.GetUserIdByName(firstName, lastName);
// UserAccount ua
// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName);
if (userId == UUID.Zero)
{
MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName);
return;
}
if (!AreFriendsCached(userId))
{
MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName);
return;
}
MainConsole.Instance.OutputFormat("Cached friends for {0} {1}:", firstName, lastName);
MainConsole.Instance.OutputFormat("UUID\n");
FriendInfo[] friends = GetFriends(userId);
foreach (FriendInfo friend in friends)
{
// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString());
// string friendFirstName, friendLastName;
//
// UserAccount friendUa
// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID);
UUID friendId;
string friendName;
if (UUID.TryParse(friend.Friend, out friendId))
friendName = umModule.GetUserName(friendId);
else
friendName = friend.Friend;
MainConsole.Instance.OutputFormat("{0} {1} {2}", friendName, friend.MyFlags, friend.TheirFlags);
}
}
} }
} }

View File

@ -105,12 +105,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion #endregion
protected override void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) protected override void OnApproveFriendRequest(IClientAPI client, UUID friendID, List<UUID> callingCardFolders)
{ {
// Update the local cache. Yes, we need to do it right here // Update the local cache. Yes, we need to do it right here
// because the HGFriendsService placed something on the DB // because the HGFriendsService placed something on the DB
// from under the sim // from under the sim
base.OnApproveFriendRequest(client, agentID, friendID, callingCardFolders); base.OnApproveFriendRequest(client, friendID, callingCardFolders);
} }
protected override bool CacheFriends(IClientAPI client) protected override bool CacheFriends(IClientAPI client)
@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
UUID agentID = client.AgentId; UUID agentID = client.AgentId;
// we do this only for the root agent // we do this only for the root agent
if (!client.SceneAgent.IsChildAgent) if (m_Friends[agentID].Refcount == 1)
{ {
// We need to preload the user management cache with the names // We need to preload the user management cache with the names
// of foreign friends, just like we do with SOPs' creators // of foreign friends, just like we do with SOPs' creators
@ -163,7 +163,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId); UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
if (account == null) // foreign if (account == null) // foreign
{ {
FriendInfo[] friends = GetFriends(client.AgentId); FriendInfo[] friends = GetFriendsFromCache(client.AgentId);
foreach (FriendInfo f in friends) foreach (FriendInfo f in friends)
{ {
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags); client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
@ -300,8 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return null; return null;
} }
public override FriendInfo[] GetFriendsFromService(IClientAPI client)
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
{ {
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name); // m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
Boolean agentIsLocal = true; Boolean agentIsLocal = true;
@ -346,7 +345,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (agentIsLocal) // agent is local, friend is foreigner if (agentIsLocal) // agent is local, friend is foreigner
{ {
FriendInfo[] finfos = GetFriends(agentID); FriendInfo[] finfos = GetFriendsFromCache(agentID);
FriendInfo finfo = GetFriend(finfos, friendID); FriendInfo finfo = GetFriend(finfos, friendID);
if (finfo != null) if (finfo != null)
{ {
@ -426,14 +425,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
CacheFriends(agentClient); RecacheFriends(agentClient);
} }
if (friendClient != null) if (friendClient != null)
{ {
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
CacheFriends(friendClient); RecacheFriends(friendClient);
} }
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
@ -453,7 +452,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
bool confirming = false; bool confirming = false;
if (friendUUI == string.Empty) if (friendUUI == string.Empty)
{ {
finfos = GetFriends(agentID); finfos = GetFriendsFromCache(agentID);
foreach (FriendInfo finfo in finfos) foreach (FriendInfo finfo in finfos)
{ {
if (finfo.TheirFlags == -1) if (finfo.TheirFlags == -1)
@ -546,7 +545,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Delete any previous friendship relations // Delete any previous friendship relations
FriendInfo[] finfos = null; FriendInfo[] finfos = null;
FriendInfo f = null; FriendInfo f = null;
finfos = GetFriends(a1); finfos = GetFriendsFromCache(a1);
if (finfos != null) if (finfos != null)
{ {
f = GetFriend(finfos, a2); f = GetFriend(finfos, a2);
@ -558,7 +557,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
finfos = GetFriends(a2); finfos = GetFriendsFromCache(a2);
if (finfos != null) if (finfos != null)
{ {
f = GetFriend(finfos, a1); f = GetFriend(finfos, a1);
@ -595,7 +594,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (agentIsLocal) // agent is local, 'friend' is foreigner if (agentIsLocal) // agent is local, 'friend' is foreigner
{ {
// We need to look for its information in the friends list itself // We need to look for its information in the friends list itself
FriendInfo[] finfos = GetFriends(agentID); FriendInfo[] finfos = GetFriendsFromCache(agentID);
FriendInfo finfo = GetFriend(finfos, exfriendID); FriendInfo finfo = GetFriend(finfos, exfriendID);
if (finfo != null) if (finfo != null)
{ {
@ -639,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private string GetUUI(UUID localUser, UUID foreignUser) private string GetUUI(UUID localUser, UUID foreignUser)
{ {
// Let's see if the user is here by any chance // Let's see if the user is here by any chance
FriendInfo[] finfos = GetFriends(localUser); FriendInfo[] finfos = GetFriendsFromCache(localUser);
if (finfos != EMPTY_FRIENDS) // friend is here, cool if (finfos != EMPTY_FRIENDS) // friend is here, cool
{ {
FriendInfo finfo = GetFriend(finfos, foreignUser); FriendInfo finfo = GetFriend(finfos, foreignUser);

View File

@ -30,6 +30,7 @@ using System.Collections.Generic;
using Nini.Config; using Nini.Config;
using NUnit.Framework; using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Data.Null;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.CoreModules.Avatar.Friends; using OpenSim.Region.CoreModules.Avatar.Friends;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
@ -44,9 +45,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
private FriendsModule m_fm; private FriendsModule m_fm;
private TestScene m_scene; private TestScene m_scene;
[TestFixtureSetUp]
public void FixtureInit()
{
// Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
}
[TestFixtureTearDown]
public void TearDown()
{
// We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
// threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
// tests really shouldn't).
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
}
[SetUp] [SetUp]
public void Init() public void Init()
{ {
// We must clear friends data between tests since Data.Null holds it in static properties. This is necessary
// so that different services and simulator can share the data in standalone mode. This is pretty horrible
// effectively the statics are global variables.
NullFriendsData.Clear();
IConfigSource config = new IniConfigSource(); IConfigSource config = new IniConfigSource();
config.AddConfig("Modules"); config.AddConfig("Modules");
// Not strictly necessary since FriendsModule assumes it is the default (!) // Not strictly necessary since FriendsModule assumes it is the default (!)
@ -62,7 +84,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
} }
[Test] [Test]
public void TestNoFriends() public void TestLoginWithNoFriends()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
@ -75,6 +97,76 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0)); Assert.That(((TestClient)sp.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
} }
[Test]
public void TestLoginWithOfflineFriends()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UUID user1Id = TestHelpers.ParseTail(0x1);
UUID user2Id = TestHelpers.ParseTail(0x2);
// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
//
// m_fm.AddFriendship(user1Id, user2Id);
ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
m_fm.AddFriendship(sp1.ControllingClient, user2Id);
// Not necessary for this test. CanSeeOnline is automatically granted.
// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
// We must logout from the client end so that the presence service is correctly updated by the presence
// detector. This is listening to the OnConnectionClosed event on the client.
((TestClient)sp1.ControllingClient).Logout();
((TestClient)sp2.ControllingClient).Logout();
// m_scene.RemoveClient(sp1.UUID, true);
// m_scene.RemoveClient(sp2.UUID, true);
ScenePresence sp1Redux = SceneHelpers.AddScenePresence(m_scene, user1Id);
// We don't expect to receive notifications of offline friends on login, just online.
Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
}
[Test]
public void TestLoginWithOnlineFriends()
{
TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
UUID user1Id = TestHelpers.ParseTail(0x1);
UUID user2Id = TestHelpers.ParseTail(0x2);
// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
//
// m_fm.AddFriendship(user1Id, user2Id);
ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
m_fm.AddFriendship(sp1.ControllingClient, user2Id);
// Not necessary for this test. CanSeeOnline is automatically granted.
// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
// We must logout from the client end so that the presence service is correctly updated by the presence
// detector. This is listening to the OnConnectionClosed event on the client.
// ((TestClient)sp1.ControllingClient).Logout();
((TestClient)sp2.ControllingClient).Logout();
// m_scene.RemoveClient(user2Id, true);
ScenePresence sp2Redux = SceneHelpers.AddScenePresence(m_scene, user2Id);
Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1));
}
[Test] [Test]
public void TestAddFriendshipWhileOnline() public void TestAddFriendshipWhileOnline()
{ {

View File

@ -966,6 +966,30 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
} }
} }
int primcount = 0;
foreach (SceneObjectGroup g in objlist)
primcount += g.PrimCount;
if (!m_Scene.Permissions.CanRezObject(
primcount, remoteClient.AgentId, pos)
&& !isAttachment)
{
// The client operates in no fail mode. It will
// have already removed the item from the folder
// if it's no copy.
// Put it back if it's not an attachment
//
if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment))
remoteClient.SendBulkUpdateInventory(item);
ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
remoteClient.SendAlertMessage(string.Format(
"Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName));
return false;
}
for (int i = 0; i < objlist.Count; i++) for (int i = 0; i < objlist.Count; i++)
{ {
SceneObjectGroup so = objlist[i]; SceneObjectGroup so = objlist[i];

View File

@ -319,7 +319,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
// Send message to avatar // Send message to avatar
if (channel == 0) if (channel == 0)
{ {
m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Owner, 0, pos, name, id, false); m_scene.SimChatBroadcast(Utils.StringToBytes(msg), ChatTypeEnum.Broadcast, 0, pos, name, id, false);
} }
List<SceneObjectGroup> attachments = sp.GetAttachments(); List<SceneObjectGroup> attachments = sp.GetAttachments();

View File

@ -27,14 +27,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using log4net;
using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenMetaverse;
using log4net;
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
{ {
public class PresenceDetector public class PresenceDetector
@ -97,7 +95,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
m_PresenceService.LogoutAgent(client.SessionId); m_PresenceService.LogoutAgent(client.SessionId);
} }
} }
} }
} }

View File

@ -495,11 +495,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_friendsModule == null) if (m_friendsModule == null)
return false; return false;
uint friendPerms = m_friendsModule.GetFriendPerms(user, objectOwner); int friendPerms = m_friendsModule.GetRightsGrantedByFriend(user, objectOwner);
if ((friendPerms & (uint)FriendRights.CanModifyObjects) != 0) return (friendPerms & (int)FriendRights.CanModifyObjects) != 0;
return true;
return false;
} }
protected bool IsEstateManager(UUID user) protected bool IsEstateManager(UUID user)
@ -508,6 +505,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return m_scene.RegionInfo.EstateSettings.IsEstateManager(user); return m_scene.RegionInfo.EstateSettings.IsEstateManager(user);
} }
#endregion #endregion
public bool PropagatePermissions() public bool PropagatePermissions()

View File

@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation
} }
SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
SceneObjectPart rootPart = sceneObject.GetChildPart(sceneObject.UUID); SceneObjectPart rootPart = sceneObject.GetPart(sceneObject.UUID);
// if grass or tree, make phantom // if grass or tree, make phantom
//rootPart.TrimPermissions(); //rootPart.TrimPermissions();

View File

@ -0,0 +1,40 @@
/*
* 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.Text;
using OpenMetaverse;
using OpenSim.Framework;
namespace OpenSim.Framework
{
public interface ICallingCardModule
{
UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID);
}
}

View File

@ -25,14 +25,31 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System.Collections.Generic;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using System.Collections.Generic; using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
{ {
public interface IFriendsModule public interface IFriendsModule
{ {
/// <summary>
/// Are friends cached on this simulator for a particular user?
/// </summary>
/// <param name="userID"></param>
/// <returns></returns>
bool AreFriendsCached(UUID userID);
/// <summary>
/// Get friends from local cache only
/// </summary>
/// <param name="userID"></param>
/// <returns>
/// An empty array if the user has no friends or friends have not been cached.
/// </returns>
FriendInfo[] GetFriendsFromCache(UUID userID);
/// <summary> /// <summary>
/// Add a friendship between two users. /// Add a friendship between two users.
/// </summary> /// </summary>
@ -55,7 +72,27 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="exFriendID"></param> /// <param name="exFriendID"></param>
void RemoveFriendship(IClientAPI client, UUID exFriendID); void RemoveFriendship(IClientAPI client, UUID exFriendID);
uint GetFriendPerms(UUID PrincipalID, UUID FriendID); /// <summary>
/// Get permissions granted by a friend.
/// </summary>
/// <param name="userID">The user.</param>
/// <param name="friendID">The friend that granted.</param>
/// <returns>The permissions. These come from the FriendRights enum.</returns>
int GetRightsGrantedByFriend(UUID userID, UUID friendID);
/// <summary>
/// Grant permissions for a friend.
/// </summary>
/// <remarks>
/// This includes giving them the ability to see when the user is online and permission to edit the user's
/// objects.
/// Granting lower permissions than the friend currently has will rescind the extra permissions.
/// </remarks>
/// <param name="remoteClient">The user granting the permissions.</param>
/// <param name="friendID">The friend.</param>
/// <param name="perms">These come from the FriendRights enum.</param>
void GrantRights(IClientAPI remoteClient, UUID friendID, int perms);
bool SendFriendsOnlineIfNeeded(IClientAPI client); bool SendFriendsOnlineIfNeeded(IClientAPI client);
} }
} }

View File

@ -1883,7 +1883,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
AddRestoredSceneObject(group, true, true); AddRestoredSceneObject(group, true, true);
EventManager.TriggerOnSceneObjectLoaded(group); EventManager.TriggerOnSceneObjectLoaded(group);
SceneObjectPart rootPart = group.GetChildPart(group.UUID); SceneObjectPart rootPart = group.GetPart(group.UUID);
rootPart.Flags &= ~PrimFlags.Scripted; rootPart.Flags &= ~PrimFlags.Scripted;
rootPart.TrimPermissions(); rootPart.TrimPermissions();
@ -2035,6 +2035,12 @@ namespace OpenSim.Region.Framework.Scenes
AddNewPrim(ownerID, groupID, pos, rot, shape); AddNewPrim(ownerID, groupID, pos, rot, shape);
} }
else
{
IClientAPI client = null;
if (TryGetClient(ownerID, out client))
client.SendAlertMessage("You cannot create objects here.");
}
} }
public virtual SceneObjectGroup AddNewPrim( public virtual SceneObjectGroup AddNewPrim(
@ -4348,7 +4354,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
SceneObjectPart part = ((SceneObjectGroup)ent).GetChildPart(((SceneObjectGroup)ent).UUID); SceneObjectPart part = ((SceneObjectGroup)ent).GetPart(((SceneObjectGroup)ent).UUID);
if (part != null) if (part != null)
{ {
if (part.Name == cmdparams[2]) if (part.Name == cmdparams[2])

View File

@ -941,7 +941,7 @@ namespace OpenSim.Region.Framework.Scenes
if (sog != null) if (sog != null)
{ {
if (sog.HasChildPrim(localID)) if (sog.ContainsPart(localID))
{ {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.", // "[SCENE GRAPH]: Found scene object {0} {1} {2} containing part with local id {3} in {4}. Returning.",
@ -969,7 +969,7 @@ namespace OpenSim.Region.Framework.Scenes
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
sog = (SceneObjectGroup)ent; sog = (SceneObjectGroup)ent;
if (sog.HasChildPrim(localID)) if (sog.ContainsPart(localID))
{ {
lock (SceneObjectGroupsByLocalPartID) lock (SceneObjectGroupsByLocalPartID)
SceneObjectGroupsByLocalPartID[localID] = sog; SceneObjectGroupsByLocalPartID[localID] = sog;
@ -1007,7 +1007,7 @@ namespace OpenSim.Region.Framework.Scenes
if (ent is SceneObjectGroup) if (ent is SceneObjectGroup)
{ {
sog = (SceneObjectGroup)ent; sog = (SceneObjectGroup)ent;
if (sog.HasChildPrim(fullID)) if (sog.ContainsPart(fullID))
{ {
lock (SceneObjectGroupsByFullPartID) lock (SceneObjectGroupsByFullPartID)
SceneObjectGroupsByFullPartID[fullID] = sog; SceneObjectGroupsByFullPartID[fullID] = sog;
@ -1096,7 +1096,7 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroup group = GetGroupByPrim(localID); SceneObjectGroup group = GetGroupByPrim(localID);
if (group == null) if (group == null)
return null; return null;
return group.GetChildPart(localID); return group.GetPart(localID);
} }
/// <summary> /// <summary>
@ -1143,7 +1143,7 @@ namespace OpenSim.Region.Framework.Scenes
SceneObjectGroup group = GetGroupByPrim(fullID); SceneObjectGroup group = GetGroupByPrim(fullID);
if (group == null) if (group == null)
return null; return null;
return group.GetChildPart(fullID); return group.GetPart(fullID);
} }
/// <summary> /// <summary>

View File

@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Scenes
UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID; UUID newItemId = (copyItemID != UUID.Zero) ? copyItemID : item.ID;
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
TaskInventoryItem taskItem = new TaskInventoryItem(); TaskInventoryItem taskItem = new TaskInventoryItem();
@ -166,7 +166,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>null if the item does not exist</returns> /// <returns>null if the item does not exist</returns>
public TaskInventoryItem GetInventoryItem(uint primID, UUID itemID) public TaskInventoryItem GetInventoryItem(uint primID, UUID itemID)
{ {
SceneObjectPart part = GetChildPart(primID); SceneObjectPart part = GetPart(primID);
if (part != null) if (part != null)
{ {
return part.Inventory.GetInventoryItem(itemID); return part.Inventory.GetInventoryItem(itemID);
@ -190,7 +190,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>false if the item did not exist, true if the update occurred succesfully</returns> /// <returns>false if the item did not exist, true if the update occurred succesfully</returns>
public bool UpdateInventoryItem(TaskInventoryItem item) public bool UpdateInventoryItem(TaskInventoryItem item)
{ {
SceneObjectPart part = GetChildPart(item.ParentPartID); SceneObjectPart part = GetPart(item.ParentPartID);
if (part != null) if (part != null)
{ {
part.Inventory.UpdateInventoryItem(item); part.Inventory.UpdateInventoryItem(item);
@ -210,7 +210,7 @@ namespace OpenSim.Region.Framework.Scenes
public int RemoveInventoryItem(uint localID, UUID itemID) public int RemoveInventoryItem(uint localID, UUID itemID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
int type = part.Inventory.RemoveInventoryItem(itemID); int type = part.Inventory.RemoveInventoryItem(itemID);

View File

@ -412,6 +412,24 @@ namespace OpenSim.Region.Framework.Scenes
return m_parts.ContainsKey(partID); return m_parts.ContainsKey(partID);
} }
/// <summary>
/// Does this group contain the given part?
/// should be able to remove these methods once we have a entity index in scene
/// </summary>
/// <param name="localID"></param>
/// <returns></returns>
public bool ContainsPart(uint localID)
{
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].LocalId == localID)
return true;
}
return false;
}
/// <value> /// <value>
/// The root part of this scene object /// The root part of this scene object
/// </value> /// </value>
@ -1636,7 +1654,7 @@ namespace OpenSim.Region.Framework.Scenes
public UUID GetPartsFullID(uint localID) public UUID GetPartsFullID(uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
return part.UUID; return part.UUID;
@ -1652,7 +1670,7 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
SceneObjectPart part = GetChildPart(localId); SceneObjectPart part = GetPart(localId);
OnGrabPart(part, offsetPos, remoteClient); OnGrabPart(part, offsetPos, remoteClient);
} }
} }
@ -2513,8 +2531,8 @@ namespace OpenSim.Region.Framework.Scenes
/// Get a part with a given UUID /// Get a part with a given UUID
/// </summary> /// </summary>
/// <param name="primID"></param> /// <param name="primID"></param>
/// <returns>null if a child part with the primID was not found</returns> /// <returns>null if a part with the primID was not found</returns>
public SceneObjectPart GetChildPart(UUID primID) public SceneObjectPart GetPart(UUID primID)
{ {
SceneObjectPart childPart; SceneObjectPart childPart;
m_parts.TryGetValue(primID, out childPart); m_parts.TryGetValue(primID, out childPart);
@ -2525,8 +2543,8 @@ namespace OpenSim.Region.Framework.Scenes
/// Get a part with a given local ID /// Get a part with a given local ID
/// </summary> /// </summary>
/// <param name="localID"></param> /// <param name="localID"></param>
/// <returns>null if a child part with the local ID was not found</returns> /// <returns>null if a part with the local ID was not found</returns>
public SceneObjectPart GetChildPart(uint localID) public SceneObjectPart GetPart(uint localID)
{ {
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++) for (int i = 0; i < parts.Length; i++)
@ -2538,35 +2556,6 @@ namespace OpenSim.Region.Framework.Scenes
return null; return null;
} }
/// <summary>
/// Does this group contain the child prim
/// should be able to remove these methods once we have a entity index in scene
/// </summary>
/// <param name="primID"></param>
/// <returns></returns>
public bool HasChildPrim(UUID primID)
{
return m_parts.ContainsKey(primID);
}
/// <summary>
/// Does this group contain the child prim
/// should be able to remove these methods once we have a entity index in scene
/// </summary>
/// <param name="localID"></param>
/// <returns></returns>
public bool HasChildPrim(uint localID)
{
SceneObjectPart[] parts = m_parts.GetArray();
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].LocalId == localID)
return true;
}
return false;
}
#endregion #endregion
#region Packet Handlers #region Packet Handlers
@ -2720,7 +2709,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>The object group of the newly delinked prim. Null if part could not be found</returns> /// <returns>The object group of the newly delinked prim. Null if part could not be found</returns>
public SceneObjectGroup DelinkFromGroup(uint partID, bool sendEvents) public SceneObjectGroup DelinkFromGroup(uint partID, bool sendEvents)
{ {
SceneObjectPart linkPart = GetChildPart(partID); SceneObjectPart linkPart = GetPart(partID);
if (linkPart != null) if (linkPart != null)
{ {
@ -3024,7 +3013,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="localID"></param> /// <param name="localID"></param>
public void SetPartName(string name, uint localID) public void SetPartName(string name, uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
part.Name = name; part.Name = name;
@ -3033,7 +3022,7 @@ namespace OpenSim.Region.Framework.Scenes
public void SetPartDescription(string des, uint localID) public void SetPartDescription(string des, uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
part.Description = des; part.Description = des;
@ -3042,7 +3031,7 @@ namespace OpenSim.Region.Framework.Scenes
public void SetPartText(string text, uint localID) public void SetPartText(string text, uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
part.SetText(text); part.SetText(text);
@ -3051,7 +3040,7 @@ namespace OpenSim.Region.Framework.Scenes
public void SetPartText(string text, UUID partID) public void SetPartText(string text, UUID partID)
{ {
SceneObjectPart part = GetChildPart(partID); SceneObjectPart part = GetPart(partID);
if (part != null) if (part != null)
{ {
part.SetText(text); part.SetText(text);
@ -3060,7 +3049,7 @@ namespace OpenSim.Region.Framework.Scenes
public string GetPartName(uint localID) public string GetPartName(uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
return part.Name; return part.Name;
@ -3070,7 +3059,7 @@ namespace OpenSim.Region.Framework.Scenes
public string GetPartDescription(uint localID) public string GetPartDescription(uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
return part.Description; return part.Description;
@ -3088,7 +3077,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="SetVolumeDetect"></param> /// <param name="SetVolumeDetect"></param>
public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect) public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect)
{ {
SceneObjectPart selectionPart = GetChildPart(localID); SceneObjectPart selectionPart = GetPart(localID);
if (SetTemporary && Scene != null) if (SetTemporary && Scene != null)
{ {
@ -3148,7 +3137,7 @@ namespace OpenSim.Region.Framework.Scenes
public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data) public void UpdateExtraParam(uint localID, ushort type, bool inUse, byte[] data)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
part.UpdateExtraParam(type, inUse, data); part.UpdateExtraParam(type, inUse, data);
@ -3173,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="textureEntry"></param> /// <param name="textureEntry"></param>
public void UpdateTextureEntry(uint localID, byte[] textureEntry) public void UpdateTextureEntry(uint localID, byte[] textureEntry)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
part.UpdateTextureEntry(textureEntry); part.UpdateTextureEntry(textureEntry);
@ -3205,7 +3194,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="shapeBlock"></param> /// <param name="shapeBlock"></param>
public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID) public void UpdateShape(ObjectShapePacket.ObjectDataBlock shapeBlock, uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
part.UpdateShape(shapeBlock); part.UpdateShape(shapeBlock);
@ -3395,7 +3384,7 @@ namespace OpenSim.Region.Framework.Scenes
public void UpdateSinglePosition(Vector3 pos, uint localID) public void UpdateSinglePosition(Vector3 pos, uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
@ -3508,7 +3497,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="localID"></param> /// <param name="localID"></param>
public void UpdateSingleRotation(Quaternion rot, uint localID) public void UpdateSingleRotation(Quaternion rot, uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
SceneObjectPart[] parts = m_parts.GetArray(); SceneObjectPart[] parts = m_parts.GetArray();
if (part != null) if (part != null)
@ -3537,7 +3527,7 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="localID"></param> /// <param name="localID"></param>
public void UpdateSingleRotation(Quaternion rot, Vector3 pos, uint localID) public void UpdateSingleRotation(Quaternion rot, Vector3 pos, uint localID)
{ {
SceneObjectPart part = GetChildPart(localID); SceneObjectPart part = GetPart(localID);
if (part != null) if (part != null)
{ {
if (m_rootPart.PhysActor != null) if (m_rootPart.PhysActor != null)

View File

@ -815,7 +815,7 @@ namespace OpenSim.Region.Framework.Scenes
group.ResetIDs(); group.ResetIDs();
SceneObjectPart rootPart = group.GetChildPart(group.UUID); SceneObjectPart rootPart = group.GetPart(group.UUID);
// Since renaming the item in the inventory does not affect the name stored // Since renaming the item in the inventory does not affect the name stored
// in the serialization, transfer the correct name from the inventory to the // in the serialization, transfer the correct name from the inventory to the

View File

@ -0,0 +1,189 @@
/*
* 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.Linq;
using System.Reflection;
using System.Text;
using log4net;
using Mono.Addins;
using NDesk.Options;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Statistics;
using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.CoreModules.Avatar.Friends;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
namespace OpenSim.Region.OptionalModules.Avatar.Friends
{
/// <summary>
/// A module that just holds commands for inspecting avatar appearance.
/// </summary>
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FriendsCommandModule")]
public class FriendsCommandsModule : ISharedRegionModule
{
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
private IFriendsModule m_friendsModule;
private IUserManagement m_userManagementModule;
// private IAvatarFactoryModule m_avatarFactory;
public string Name { get { return "Appearance Information Module"; } }
public Type ReplaceableInterface { get { return null; } }
public void Initialise(IConfigSource source)
{
// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: INITIALIZED MODULE");
}
public void PostInitialise()
{
// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: POST INITIALIZED MODULE");
}
public void Close()
{
// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: CLOSED MODULE");
}
public void AddRegion(Scene scene)
{
// m_log.DebugFormat("[FRIENDS COMMANDO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
}
public void RemoveRegion(Scene scene)
{
// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
}
public void RegionLoaded(Scene scene)
{
// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
if (m_scene == null)
m_scene = scene;
m_friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
m_userManagementModule = m_scene.RequestModuleInterface<IUserManagement>();
if (m_friendsModule != null && m_userManagementModule != null)
{
m_scene.AddCommand(
"Friends", this, "friends show",
"friends show [--cache] <first-name> <last-name>",
"Show the friends for the given user if they exist.\n",
"The --cache option will show locally cached information for that user.",
HandleFriendsShowCommand);
}
}
protected void HandleFriendsShowCommand(string module, string[] cmd)
{
Dictionary<string, object> options = new Dictionary<string, object>();
OptionSet optionSet = new OptionSet().Add("c|cache", delegate (string v) { options["cache"] = v != null; });
List<string> mainParams = optionSet.Parse(cmd);
if (mainParams.Count != 4)
{
MainConsole.Instance.OutputFormat("Usage: friends show [--cache] <first-name> <last-name>");
return;
}
string firstName = mainParams[2];
string lastName = mainParams[3];
UUID userId = m_userManagementModule.GetUserIdByName(firstName, lastName);
// UserAccount ua
// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, firstName, lastName);
if (userId == UUID.Zero)
{
MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName);
return;
}
FriendInfo[] friends;
if (options.ContainsKey("cache"))
{
if (!m_friendsModule.AreFriendsCached(userId))
{
MainConsole.Instance.OutputFormat("No friends cached on this simulator for {0} {1}", firstName, lastName);
return;
}
else
{
friends = m_friendsModule.GetFriendsFromCache(userId);
}
}
else
{
// FIXME: We're forced to do this right now because IFriendsService has no region connectors. We can't
// just expose FriendsModule.GetFriendsFromService() because it forces an IClientAPI requirement that
// can't currently be changed because of HGFriendsModule code that takes the scene from the client.
friends = ((FriendsModule)m_friendsModule).FriendsService.GetFriends(userId);
}
MainConsole.Instance.OutputFormat("Friends for {0} {1} {2}:", firstName, lastName, userId);
MainConsole.Instance.OutputFormat("UUID, Name, MyFlags, TheirFlags");
foreach (FriendInfo friend in friends)
{
// MainConsole.Instance.OutputFormat(friend.PrincipalID.ToString());
// string friendFirstName, friendLastName;
//
// UserAccount friendUa
// = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friend.PrincipalID);
UUID friendId;
string friendName;
if (UUID.TryParse(friend.Friend, out friendId))
friendName = m_userManagementModule.GetUserName(friendId);
else
friendName = friend.Friend;
MainConsole.Instance.OutputFormat(
"{0} {1} {2} {3}", friend.Friend, friendName, friend.MyFlags, friend.TheirFlags);
}
}
}
}

View File

@ -510,7 +510,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator
} }
SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape);
SceneObjectPart rootPart = sceneObject.GetChildPart(sceneObject.UUID); SceneObjectPart rootPart = sceneObject.GetPart(sceneObject.UUID);
rootPart.AddFlag(PrimFlags.Phantom); rootPart.AddFlag(PrimFlags.Phantom);

View File

@ -4214,7 +4214,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
World.ForEachRootScenePresence(delegate(ScenePresence presence) World.ForEachRootScenePresence(delegate(ScenePresence presence)
{ {
SceneObjectPart sitPart = presence.ParentPart; SceneObjectPart sitPart = presence.ParentPart;
if (sitPart != null && m_host.ParentGroup.HasChildPrim(sitPart.LocalId)) if (sitPart != null && m_host.ParentGroup.ContainsPart(sitPart.LocalId))
nametable.Add(presence.ControllingClient.Name); nametable.Add(presence.ControllingClient.Name);
}); });

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenMetaverse; using OpenMetaverse;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
@ -58,6 +59,8 @@ namespace OpenSim.Services.HypergridService
private UserAccountCache m_Cache; private UserAccountCache m_Cache;
private ExpiringCache<UUID, List<XInventoryFolder>> m_SuitcaseTrees = new ExpiringCache<UUID,List<XInventoryFolder>>();
public HGSuitcaseInventoryService(IConfigSource config, string configName) public HGSuitcaseInventoryService(IConfigSource config, string configName)
: base(config, configName) : base(config, configName)
{ {
@ -147,16 +150,17 @@ namespace OpenSim.Services.HypergridService
return GetRootFolder(principalID); return GetRootFolder(principalID);
} }
//
// Use the inherited methods
//
public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID) public override InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
{ {
InventoryCollection coll = null; InventoryCollection coll = null;
XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
XInventoryFolder root = GetRootXFolder(principalID); XInventoryFolder root = GetRootXFolder(principalID);
if (!IsWithinSuitcaseTree(folderID, root, suitcase))
return new InventoryCollection();
if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase if (folderID == root.folderID) // someone's asking for the root folder, we'll give them the suitcase
{ {
XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
if (suitcase != null) if (suitcase != null)
{ {
coll = base.GetFolderContent(principalID, suitcase.folderID); coll = base.GetFolderContent(principalID, suitcase.folderID);
@ -180,68 +184,69 @@ namespace OpenSim.Services.HypergridService
return coll; return coll;
} }
//public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) public override List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
//{
//}
//public override bool AddFolder(InventoryFolderBase folder)
//{
// // Check if it's under the Suitcase folder
// List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner);
// InventoryFolderBase suitcase = GetRootFolder(folder.Owner);
// List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
// foreach (InventoryFolderBase f in suitDescendents)
// if (folder.ParentID == f.ID)
// {
// XInventoryFolder xFolder = ConvertFromOpenSim(folder);
// return m_Database.StoreFolder(xFolder);
// }
// return false;
//}
private List<InventoryFolderBase> GetDescendents(List<InventoryFolderBase> lst, UUID root)
{ {
List<InventoryFolderBase> direct = lst.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == root; }); // Let's do a bit of sanity checking, more than the base service does
if (direct == null) // make sure the given folder exists under the suitcase tree of this user
return new List<InventoryFolderBase>(); XInventoryFolder root = GetRootXFolder(principalID);
XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
List<InventoryFolderBase> indirect = new List<InventoryFolderBase>(); if (!IsWithinSuitcaseTree(folderID, root, suitcase))
foreach (InventoryFolderBase f in direct) return new List<InventoryItemBase>();
indirect.AddRange(GetDescendents(lst, f.ID));
direct.AddRange(indirect); return base.GetFolderItems(principalID, folderID);
return direct;
} }
// Use inherited method public override bool AddFolder(InventoryFolderBase folder)
//public bool UpdateFolder(InventoryFolderBase folder) {
//{ // Let's do a bit of sanity checking, more than the base service does
//} // make sure the given folder's parent folder exists under the suitcase tree of this user
XInventoryFolder root = GetRootXFolder(folder.Owner);
XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
//public override bool MoveFolder(InventoryFolderBase folder) if (!IsWithinSuitcaseTree(folder.ParentID, root, suitcase))
//{ return false;
// XInventoryFolder[] x = m_Database.GetFolders(
// new string[] { "folderID" },
// new string[] { folder.ID.ToString() });
// if (x.Length == 0) // OK, it's legit
// return false; // Check if it's under the Root folder directly
if (folder.ParentID == root.folderID)
{
// someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder for root folder for user {0}. Adding in suitcase instead", folder.Owner);
folder.ParentID = suitcase.folderID;
}
// // Check if it's under the Suitcase folder return base.AddFolder(folder);
// List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner); }
// InventoryFolderBase suitcase = GetRootFolder(folder.Owner);
// List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
// foreach (InventoryFolderBase f in suitDescendents) public bool UpdateFolder(InventoryFolderBase folder)
// if (folder.ParentID == f.ID) {
// { XInventoryFolder root = GetRootXFolder(folder.Owner);
// x[0].parentFolderID = folder.ParentID; XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
// return m_Database.StoreFolder(x[0]);
// }
// return false; if (!IsWithinSuitcaseTree(folder.ID, root, suitcase))
//} return false;
return base.UpdateFolder(folder);
}
public override bool MoveFolder(InventoryFolderBase folder)
{
XInventoryFolder root = GetRootXFolder(folder.Owner);
XInventoryFolder suitcase = GetSuitcaseXFolder(folder.Owner);
if (!IsWithinSuitcaseTree(folder.ID, root, suitcase) || !IsWithinSuitcaseTree(folder.ParentID, root, suitcase))
return false;
if (folder.ParentID == root.folderID)
{
// someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveFolder to root folder for user {0}. Moving it to suitcase instead", folder.Owner);
folder.ParentID = suitcase.folderID;
}
return base.MoveFolder(folder);
}
public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs) public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
{ {
@ -255,78 +260,110 @@ namespace OpenSim.Services.HypergridService
return false; return false;
} }
// Unfortunately we need to use the inherited method because of how DeRez works. public override bool AddItem(InventoryItemBase item)
// The viewer sends the folderID hard-wired in the derez message {
//public override bool AddItem(InventoryItemBase item) // Let's do a bit of sanity checking, more than the base service does
//{ // make sure the given folder's parent folder exists under the suitcase tree of this user
// // Check if it's under the Suitcase folder XInventoryFolder root = GetRootXFolder(item.Owner);
// List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner); XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner);
// InventoryFolderBase suitcase = GetRootFolder(item.Owner);
// List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
// foreach (InventoryFolderBase f in suitDescendents) if (!IsWithinSuitcaseTree(item.Folder, root, suitcase))
// if (item.Folder == f.ID) return false;
// return m_Database.StoreItem(ConvertFromOpenSim(item));
// return false; // OK, it's legit
//} // Check if it's under the Root folder directly
if (item.Folder == root.folderID)
{
// someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddItem for root folder for user {0}. Adding in suitcase instead", item.Owner);
item.Folder = suitcase.folderID;
}
//public override bool UpdateItem(InventoryItemBase item) return base.AddItem(item);
//{
// // Check if it's under the Suitcase folder
// List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner);
// InventoryFolderBase suitcase = GetRootFolder(item.Owner);
// List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
// foreach (InventoryFolderBase f in suitDescendents) }
// if (item.Folder == f.ID)
// return m_Database.StoreItem(ConvertFromOpenSim(item));
// return false; public override bool UpdateItem(InventoryItemBase item)
//} {
XInventoryFolder root = GetRootXFolder(item.Owner);
XInventoryFolder suitcase = GetSuitcaseXFolder(item.Owner);
//public override bool MoveItems(UUID principalID, List<InventoryItemBase> items) if (!IsWithinSuitcaseTree(item.Folder, root, suitcase))
//{ return false;
// // Principal is b0rked. *sigh*
// //
// // Let's assume they all have the same principal
// // Check if it's under the Suitcase folder
// List<InventoryFolderBase> skel = base.GetInventorySkeleton(items[0].Owner);
// InventoryFolderBase suitcase = GetRootFolder(items[0].Owner);
// List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
// foreach (InventoryItemBase i in items) return base.UpdateItem(item);
// { }
// foreach (InventoryFolderBase f in suitDescendents)
// if (i.Folder == f.ID)
// m_Database.MoveItem(i.ID.ToString(), i.Folder.ToString());
// }
// return true; public override bool MoveItems(UUID principalID, List<InventoryItemBase> items)
//} {
// Principal is b0rked. *sigh*
XInventoryFolder root = GetRootXFolder(items[0].Owner);
XInventoryFolder suitcase = GetSuitcaseXFolder(items[0].Owner);
if (!IsWithinSuitcaseTree(items[0].Folder, root, suitcase))
return false;
foreach (InventoryItemBase it in items)
if (it.Folder == root.folderID)
{
// someone's trying to add a subfolder of the root folder, we'll add it to the suitcase instead
m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveItem to root folder for user {0}. Moving it to suitcase instead", it.Owner);
it.Folder = suitcase.folderID;
}
return base.MoveItems(principalID, items);
}
// Let these pass. Use inherited methods. // Let these pass. Use inherited methods.
//public bool DeleteItems(UUID principalID, List<UUID> itemIDs) public override bool DeleteItems(UUID principalID, List<UUID> itemIDs)
//{ {
//} return false;
}
public override InventoryItemBase GetItem(InventoryItemBase item)
{
InventoryItemBase it = base.GetItem(item);
XInventoryFolder root = GetRootXFolder(it.Owner);
XInventoryFolder suitcase = GetSuitcaseXFolder(it.Owner);
if (it != null)
{
if (!IsWithinSuitcaseTree(it.Folder, root, suitcase))
return null;
if (it.Folder == suitcase.folderID)
it.Folder = root.folderID;
//public override InventoryItemBase GetItem(InventoryItemBase item)
//{
// InventoryItemBase it = base.GetItem(item);
// if (it != null)
// {
// UserAccount user = m_Cache.GetUser(it.CreatorId); // UserAccount user = m_Cache.GetUser(it.CreatorId);
// // Adjust the creator data // // Adjust the creator data
// if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) // if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty))
// it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName; // it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName;
//} //}
// return it; }
//}
//public InventoryFolderBase GetFolder(InventoryFolderBase folder) return it;
//{ }
//}
public override InventoryFolderBase GetFolder(InventoryFolderBase folder)
{
InventoryFolderBase f = base.GetFolder(folder);
XInventoryFolder root = GetRootXFolder(f.Owner);
XInventoryFolder suitcase = GetSuitcaseXFolder(f.Owner);
if (f != null)
{
if (!IsWithinSuitcaseTree(f.ID, root, suitcase))
return null;
if (f.ParentID == suitcase.folderID)
f.ParentID = root.folderID;
}
return f;
}
//public List<InventoryItemBase> GetActiveGestures(UUID principalID) //public List<InventoryItemBase> GetActiveGestures(UUID principalID)
//{ //{
@ -336,6 +373,19 @@ namespace OpenSim.Services.HypergridService
//{ //{
//} //}
#region Auxiliary functions
private XInventoryFolder GetXFolder(UUID userID, UUID folderID)
{
XInventoryFolder[] folders = m_Database.GetFolders(
new string[] { "agentID", "folderID" },
new string[] { userID.ToString(), folderID.ToString() });
if (folders.Length == 0)
return null;
return folders[0];
}
private XInventoryFolder GetRootXFolder(UUID principalID) private XInventoryFolder GetRootXFolder(UUID principalID)
{ {
XInventoryFolder[] folders = m_Database.GetFolders( XInventoryFolder[] folders = m_Database.GetFolders(
@ -364,5 +414,53 @@ namespace OpenSim.Services.HypergridService
suitcase.folderID = rootID; suitcase.folderID = rootID;
suitcase.parentFolderID = UUID.Zero; suitcase.parentFolderID = UUID.Zero;
} }
private List<XInventoryFolder> GetFolderTree(UUID root)
{
List<XInventoryFolder> t = null;
if (m_SuitcaseTrees.TryGetValue(root, out t))
return t;
t = GetFolderTreeRecursive(root);
m_SuitcaseTrees.AddOrUpdate(root, t, 120);
return t;
}
private List<XInventoryFolder> GetFolderTreeRecursive(UUID root)
{
List<XInventoryFolder> tree = new List<XInventoryFolder>();
XInventoryFolder[] folders = m_Database.GetFolders(
new string[] { "parentFolderID" },
new string[] { root.ToString() });
if (folders == null || (folders != null && folders.Length == 0))
return tree; // empty tree
else
{
foreach (XInventoryFolder f in folders)
{
tree.Add(f);
tree.AddRange(GetFolderTreeRecursive(f.folderID));
}
return tree;
}
}
private bool IsWithinSuitcaseTree(UUID folderID, XInventoryFolder root, XInventoryFolder suitcase)
{
List<XInventoryFolder> tree = new List<XInventoryFolder>();
tree.Add(root); // Warp! the tree is the real root folder plus the children of the suitcase folder
tree.AddRange(GetFolderTree(suitcase.folderID));
XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl)
{
if (fl.folderID == folderID) return true;
else return false;
});
if (f == null) return false;
else return true;
}
#endregion
} }
} }

View File

@ -36,7 +36,15 @@ namespace OpenSim.Services.Interfaces
{ {
public UUID PrincipalID; public UUID PrincipalID;
public string Friend; public string Friend;
/// <summary>
/// The permissions that this user has granted to the friend.
/// </summary>
public int MyFlags; public int MyFlags;
/// <summary>
/// The permissions that the friend has granted to this user.
/// </summary>
public int TheirFlags; public int TheirFlags;
public FriendInfo() public FriendInfo()
@ -51,7 +59,7 @@ namespace OpenSim.Services.Interfaces
Friend = string.Empty; Friend = string.Empty;
if (kvp.ContainsKey("Friend") && kvp["Friend"] != null) if (kvp.ContainsKey("Friend") && kvp["Friend"] != null)
Friend = kvp["Friend"].ToString(); Friend = kvp["Friend"].ToString();
MyFlags = 0; MyFlags = (int)FriendRights.None;
if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null) if (kvp.ContainsKey("MyFlags") && kvp["MyFlags"] != null)
Int32.TryParse(kvp["MyFlags"].ToString(), out MyFlags); Int32.TryParse(kvp["MyFlags"].ToString(), out MyFlags);
TheirFlags = 0; TheirFlags = 0;

View File

@ -151,11 +151,12 @@ namespace OpenSim.Services.PresenceService
info.Add(ret); info.Add(ret);
} }
// m_log.DebugFormat(
// "[PRESENCE SERVICE]: GetAgents for {0} found {1} presences", userIDStr, data.Length);
} }
// m_log.DebugFormat("[PRESENCE SERVICE]: GetAgents for {0} userIDs found {1} presences", userIDs.Length, info.Count);
return info.ToArray(); return info.ToArray();
} }
} }
} }

View File

@ -369,8 +369,11 @@ namespace OpenSim.Tests.Common
agentData.AgentID = agentId; agentData.AgentID = agentId;
agentData.firstname = firstName; agentData.firstname = firstName;
agentData.lastname = "testlastname"; agentData.lastname = "testlastname";
agentData.SessionID = UUID.Zero;
agentData.SecureSessionID = UUID.Zero; // XXX: Sessions must be unique, otherwise one presence can overwrite another in NullPresenceData.
agentData.SessionID = UUID.Random();
agentData.SecureSessionID = UUID.Random();
agentData.circuitcode = 123; agentData.circuitcode = 123;
agentData.BaseFolder = UUID.Zero; agentData.BaseFolder = UUID.Zero;
agentData.InventoryFolder = UUID.Zero; agentData.InventoryFolder = UUID.Zero;
@ -416,7 +419,10 @@ namespace OpenSim.Tests.Common
// We emulate the proper login sequence here by doing things in four stages // We emulate the proper login sequence here by doing things in four stages
// Stage 0: login // Stage 0: login
scene.PresenceService.LoginAgent(agentData.AgentID.ToString(), agentData.SessionID, agentData.SecureSessionID); // We need to punch through to the underlying service because scene will not, correctly, let us call it
// through it's reference to the LPSC
LocalPresenceServicesConnector lpsc = (LocalPresenceServicesConnector)scene.PresenceService;
lpsc.m_PresenceService.LoginAgent(agentData.AgentID.ToString(), agentData.SessionID, agentData.SecureSessionID);
// Stages 1 & 2 // Stages 1 & 2
ScenePresence sp = IntroduceClientToScene(scene, agentData, TeleportFlags.ViaLogin); ScenePresence sp = IntroduceClientToScene(scene, agentData, TeleportFlags.ViaLogin);

View File

@ -349,15 +349,9 @@ namespace OpenSim.Tests.Common.Mock
get { return m_agentId; } get { return m_agentId; }
} }
public UUID SessionId public UUID SessionId { get; set; }
{
get { return UUID.Zero; }
}
public UUID SecureSessionId public UUID SecureSessionId { get; set; }
{
get { return UUID.Zero; }
}
public virtual string FirstName public virtual string FirstName
{ {
@ -381,11 +375,9 @@ namespace OpenSim.Tests.Common.Mock
get { return true; } get { return true; }
set { } set { }
} }
public bool IsLoggingOut
{ public bool IsLoggingOut { get; set; }
get { return false; }
set { }
}
public UUID ActiveGroupId public UUID ActiveGroupId
{ {
get { return UUID.Zero; } get { return UUID.Zero; }
@ -451,6 +443,8 @@ namespace OpenSim.Tests.Common.Mock
m_lastName = agentData.lastname; m_lastName = agentData.lastname;
m_circuitCode = agentData.circuitcode; m_circuitCode = agentData.circuitcode;
m_scene = scene; m_scene = scene;
SessionId = agentData.SessionID;
SecureSessionId = agentData.SecureSessionID;
CapsSeedUrl = agentData.CapsPath; CapsSeedUrl = agentData.CapsPath;
ReceivedOfflineNotifications = new List<UUID>(); ReceivedOfflineNotifications = new List<UUID>();
@ -902,12 +896,29 @@ namespace OpenSim.Tests.Common.Mock
{ {
} }
/// <summary>
/// This is a TestClient only method to do shutdown tasks that are normally carried out by LLUDPServer.RemoveClient()
/// </summary>
public void Logout()
{
// We must set this here so that the presence is removed from the PresenceService by the PresenceDetector
IsLoggingOut = true;
Close();
}
public void Close(bool c)
{
Close();
}
public void Close() public void Close()
{ {
Close(true); // Fire the callback for this connection closing
} // This is necesary to get the presence detector to notice that a client has logged out.
public void Close(bool sendStop) if (OnConnectionClosed != null)
{ OnConnectionClosed(this);
m_scene.RemoveClient(AgentId, true); m_scene.RemoveClient(AgentId, true);
} }

View File

@ -1325,6 +1325,7 @@
<ReferencePath>../../../bin/</ReferencePath> <ReferencePath>../../../bin/</ReferencePath>
<Reference name="System"/> <Reference name="System"/>
<Reference name="System.Core"/>
<Reference name="System.Xml"/> <Reference name="System.Xml"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/> <Reference name="OpenMetaverse" path="../../../bin/"/>
@ -1764,6 +1765,7 @@
<Reference name="System.Xml"/> <Reference name="System.Xml"/>
<Reference name="System.Drawing"/> <Reference name="System.Drawing"/>
<Reference name="System.Web"/> <Reference name="System.Web"/>
<Reference name="NDesk.Options" path="../../../bin/"/>
<Reference name="OpenMetaverseTypes" path="../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/> <Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/> <Reference name="OpenMetaverse" path="../../../bin/"/>
@ -3009,6 +3011,7 @@
<Reference name="OpenMetaverseTypes" path="../../../bin/"/> <Reference name="OpenMetaverseTypes" path="../../../bin/"/>
<Reference name="OpenMetaverse" path="../../../bin/"/> <Reference name="OpenMetaverse" path="../../../bin/"/>
<Reference name="OpenSim.Data"/> <Reference name="OpenSim.Data"/>
<Reference name="OpenSim.Data.Null"/>
<Reference name="OpenSim.Framework"/> <Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Serialization"/> <Reference name="OpenSim.Framework.Serialization"/>
<Reference name="OpenSim.Framework.Communications"/> <Reference name="OpenSim.Framework.Communications"/>