mirror of
https://github.com/opensim/opensim.git
synced 2026-08-10 11:33:28 +08:00
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
This commit is contained in:
@@ -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.Reflection;
|
||||
using log4net;
|
||||
@@ -10,7 +37,7 @@ using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
using Mono.Addins;
|
||||
|
||||
namespace Careminster.XCallingCard.Modules
|
||||
namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")]
|
||||
public class CallingCardModule : ISharedRegionModule, ICallingCardModule
|
||||
|
||||
@@ -51,12 +51,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected bool m_Enabled = false;
|
||||
|
||||
protected class UserFriendData
|
||||
{
|
||||
public UUID PrincipalID;
|
||||
public FriendInfo[] Friends;
|
||||
public int Refcount;
|
||||
|
||||
public bool IsFriend(string friend)
|
||||
{
|
||||
@@ -71,7 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
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>();
|
||||
|
||||
@@ -108,7 +110,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
protected IFriendsService FriendsService
|
||||
public IFriendsService FriendsService
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -155,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
InitModule(config);
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||
// m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
scene.RegisterModuleInterface<IFriendsModule>(this);
|
||||
@@ -211,14 +213,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
scene.EventManager.OnClientLogin += OnClientLogin;
|
||||
}
|
||||
|
||||
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 virtual void RegionLoaded(Scene scene) {}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
@@ -240,13 +235,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
#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);
|
||||
if (finfo != null)
|
||||
{
|
||||
return (uint)finfo.TheirFlags;
|
||||
return finfo.TheirFlags;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -254,15 +249,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
private void OnNewClient(IClientAPI client)
|
||||
{
|
||||
if (client.SceneAgent.IsChildAgent)
|
||||
return;
|
||||
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
||||
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
||||
client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID);
|
||||
client.OnGrantUserRights += OnGrantUserRights;
|
||||
client.OnTerminateFriendship += RemoveFriendship;
|
||||
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
|
||||
// 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
|
||||
@@ -283,14 +278,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
UUID agentID = client.AgentId;
|
||||
lock (m_Friends)
|
||||
{
|
||||
UserFriendData friendsData = new UserFriendData();
|
||||
friendsData.PrincipalID = agentID;
|
||||
friendsData.Friends = GetFriendsFromService(client);
|
||||
UserFriendData friendsData;
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
{
|
||||
friendsData.Refcount++;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
friendsData = new UserFriendData();
|
||||
friendsData.PrincipalID = agentID;
|
||||
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)
|
||||
@@ -300,17 +304,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
// do this for root agents closing out
|
||||
StatusChange(agentID, false);
|
||||
}
|
||||
|
||||
lock (m_Friends)
|
||||
m_Friends.Remove(agentID);
|
||||
lock (m_Friends)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
{
|
||||
friendsData.Refcount--;
|
||||
if (friendsData.Refcount <= 0)
|
||||
m_Friends.Remove(agentID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMakeRootAgent(ScenePresence sp)
|
||||
{
|
||||
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
|
||||
// is on the critical path for transferring an avatar from one region to another.
|
||||
CacheFriends(sp.ControllingClient);
|
||||
RecacheFriends(sp.ControllingClient);
|
||||
}
|
||||
|
||||
private void OnClientLogin(IClientAPI client)
|
||||
@@ -339,18 +349,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
// Send the friends online
|
||||
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());
|
||||
}
|
||||
|
||||
// Send outstanding friendship offers
|
||||
List<string> outstanding = new List<string>();
|
||||
FriendInfo[] friends = GetFriends(agentID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(agentID);
|
||||
foreach (FriendInfo fi in friends)
|
||||
{
|
||||
if (fi.TheirFlags == -1)
|
||||
@@ -406,23 +411,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
List<UUID> GetOnlineFriends(UUID userID)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
|
||||
if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
|
||||
friendList.Add(fi.Friend);
|
||||
}
|
||||
|
||||
List<UUID> online = new List<UUID>();
|
||||
|
||||
if (friendList.Count > 0)
|
||||
GetOnlineFriends(userID, friendList, online);
|
||||
|
||||
// m_log.DebugFormat(
|
||||
// "[FRIENDS MODULE]: User {0} has {1} friends online", userID, online.Count);
|
||||
|
||||
return 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());
|
||||
foreach (PresenceInfo pi in presence)
|
||||
{
|
||||
@@ -473,13 +485,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
/// <param name="online"></param>
|
||||
private void StatusChange(UUID agentID, bool online)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(agentID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(agentID);
|
||||
if (friends.Length > 0)
|
||||
{
|
||||
List<FriendInfo> friendList = new List<FriendInfo>();
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
// Check that the friendship doesn't exist yet
|
||||
FriendInfo[] finfos = GetFriends(principalID);
|
||||
FriendInfo[] finfos = GetFriendsFromCache(principalID);
|
||||
if (finfos != null)
|
||||
{
|
||||
FriendInfo f = GetFriend(finfos, friendID);
|
||||
@@ -598,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
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);
|
||||
|
||||
@@ -616,7 +628,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
// Update the local cache.
|
||||
CacheFriends(client);
|
||||
RecacheFriends(client);
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
// Try local
|
||||
if (LocalFriendshipDenied(agentID, client.Name, friendID))
|
||||
if (LocalFriendshipDenied(client.AgentId, client.Name, friendID))
|
||||
return;
|
||||
|
||||
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);
|
||||
if (region != null)
|
||||
m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID);
|
||||
m_FriendsSimConnector.FriendshipDenied(region, client.AgentId, client.Name, friendID);
|
||||
else
|
||||
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.");
|
||||
|
||||
// Update local cache
|
||||
CacheFriends(client);
|
||||
RecacheFriends(client);
|
||||
|
||||
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)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
// Store it on the DB
|
||||
if (!StoreRights(requester, target, rights))
|
||||
if (!StoreRights(requester, friendID, rights))
|
||||
{
|
||||
remoteClient.SendAlertMessage("Unable to grant rights.");
|
||||
return;
|
||||
@@ -729,17 +745,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
friend.MyFlags = rights;
|
||||
|
||||
// Always send this back to the original client
|
||||
remoteClient.SendChangeUserRights(requester, target, rights);
|
||||
remoteClient.SendChangeUserRights(requester, friendID, rights);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
//
|
||||
|
||||
// Try local
|
||||
if (LocalGrantRights(requester, target, myFlags, rights))
|
||||
if (LocalGrantRights(requester, friendID, myFlags, rights))
|
||||
return;
|
||||
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() });
|
||||
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||
if (friendSessions != null && friendSessions.Length > 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);
|
||||
// TODO: You might want to send the delta to save the lookup
|
||||
// on the other end!!
|
||||
m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
|
||||
m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights);
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
@@ -797,9 +815,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
ccm.CreateCallingCard(friendID, userID, UUID.Zero);
|
||||
}
|
||||
|
||||
|
||||
// Update the local cache
|
||||
CacheFriends(friendClient);
|
||||
RecacheFriends(friendClient);
|
||||
|
||||
// we're done
|
||||
return true;
|
||||
@@ -832,7 +849,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// the friend in this sim as root agent
|
||||
friendClient.SendTerminateFriend(exfriendID);
|
||||
// update local cache
|
||||
CacheFriends(friendClient);
|
||||
RecacheFriends(friendClient);
|
||||
// we're done
|
||||
return true;
|
||||
}
|
||||
@@ -891,20 +908,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
#endregion
|
||||
|
||||
#region Get / Set friends in several flavours
|
||||
/// <summary>
|
||||
/// Get friends from local cache only
|
||||
/// </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)
|
||||
|
||||
public FriendInfo[] GetFriendsFromCache(UUID userID)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
|
||||
lock (m_Friends)
|
||||
{
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
if (m_Friends.TryGetValue(userID, out friendsData))
|
||||
return friendsData.Friends;
|
||||
}
|
||||
|
||||
@@ -922,23 +933,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// Update local cache
|
||||
lock (m_Friends)
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(friendID);
|
||||
FriendInfo[] friends = GetFriendsFromCache(friendID);
|
||||
FriendInfo finfo = GetFriend(friends, userID);
|
||||
finfo.TheirFlags = rights;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
public virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
return FriendsService.GetFriends(client.AgentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Are friends cached on this simulator for a particular user?
|
||||
/// </summary>
|
||||
/// <param name="userID"></param>
|
||||
/// <returns></returns>
|
||||
protected bool AreFriendsCached(UUID userID)
|
||||
protected void RecacheFriends(IClientAPI client)
|
||||
{
|
||||
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
|
||||
// is on the critical path for transferring an avatar from one region to another.
|
||||
UUID agentID = client.AgentId;
|
||||
lock (m_Friends)
|
||||
{
|
||||
UserFriendData friendsData;
|
||||
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||
friendsData.Friends = GetFriendsFromService(client);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AreFriendsCached(UUID userID)
|
||||
{
|
||||
lock (m_Friends)
|
||||
return m_Friends.ContainsKey(userID);
|
||||
@@ -957,8 +976,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
|
||||
{
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
|
||||
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), (int)FriendRights.CanSeeOnline);
|
||||
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), (int)FriendRights.CanSeeOnline);
|
||||
}
|
||||
|
||||
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||
@@ -969,61 +988,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,12 +105,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
#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
|
||||
// because the HGFriendsService placed something on the DB
|
||||
// from under the sim
|
||||
base.OnApproveFriendRequest(client, agentID, friendID, callingCardFolders);
|
||||
base.OnApproveFriendRequest(client, friendID, callingCardFolders);
|
||||
}
|
||||
|
||||
protected override bool CacheFriends(IClientAPI client)
|
||||
@@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
// 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
|
||||
// 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);
|
||||
if (account == null) // foreign
|
||||
{
|
||||
FriendInfo[] friends = GetFriends(client.AgentId);
|
||||
FriendInfo[] friends = GetFriendsFromCache(client.AgentId);
|
||||
foreach (FriendInfo f in friends)
|
||||
{
|
||||
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
|
||||
@@ -300,8 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
public override FriendInfo[] GetFriendsFromService(IClientAPI client)
|
||||
{
|
||||
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering GetFriendsFromService for {0}", client.Name);
|
||||
Boolean agentIsLocal = true;
|
||||
@@ -346,7 +345,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
if (agentIsLocal) // agent is local, friend is foreigner
|
||||
{
|
||||
FriendInfo[] finfos = GetFriends(agentID);
|
||||
FriendInfo[] finfos = GetFriendsFromCache(agentID);
|
||||
FriendInfo finfo = GetFriend(finfos, friendID);
|
||||
if (finfo != null)
|
||||
{
|
||||
@@ -426,14 +425,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
|
||||
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||
CacheFriends(agentClient);
|
||||
RecacheFriends(agentClient);
|
||||
}
|
||||
if (friendClient != null)
|
||||
{
|
||||
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
|
||||
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
|
||||
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||
CacheFriends(friendClient);
|
||||
RecacheFriends(friendClient);
|
||||
}
|
||||
|
||||
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;
|
||||
if (friendUUI == string.Empty)
|
||||
{
|
||||
finfos = GetFriends(agentID);
|
||||
finfos = GetFriendsFromCache(agentID);
|
||||
foreach (FriendInfo finfo in finfos)
|
||||
{
|
||||
if (finfo.TheirFlags == -1)
|
||||
@@ -546,7 +545,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// Delete any previous friendship relations
|
||||
FriendInfo[] finfos = null;
|
||||
FriendInfo f = null;
|
||||
finfos = GetFriends(a1);
|
||||
finfos = GetFriendsFromCache(a1);
|
||||
if (finfos != null)
|
||||
{
|
||||
f = GetFriend(finfos, a2);
|
||||
@@ -558,7 +557,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
|
||||
finfos = GetFriends(a2);
|
||||
finfos = GetFriendsFromCache(a2);
|
||||
if (finfos != null)
|
||||
{
|
||||
f = GetFriend(finfos, a1);
|
||||
@@ -595,7 +594,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (agentIsLocal) // agent is local, 'friend' is foreigner
|
||||
{
|
||||
// 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);
|
||||
if (finfo != null)
|
||||
{
|
||||
@@ -639,7 +638,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
private string GetUUI(UUID localUser, UUID foreignUser)
|
||||
{
|
||||
// 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
|
||||
{
|
||||
FriendInfo finfo = GetFriend(finfos, foreignUser);
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Collections.Generic;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Data.Null;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.CoreModules.Avatar.Friends;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
@@ -44,9 +45,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
private FriendsModule m_fm;
|
||||
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]
|
||||
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();
|
||||
config.AddConfig("Modules");
|
||||
// Not strictly necessary since FriendsModule assumes it is the default (!)
|
||||
@@ -62,7 +84,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestNoFriends()
|
||||
public void TestLoginWithNoFriends()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// 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));
|
||||
}
|
||||
|
||||
[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]
|
||||
public void TestAddFriendshipWhileOnline()
|
||||
{
|
||||
|
||||
@@ -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++)
|
||||
{
|
||||
SceneObjectGroup so = objlist[i];
|
||||
|
||||
@@ -319,7 +319,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
|
||||
// Send message to avatar
|
||||
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();
|
||||
|
||||
@@ -27,14 +27,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Services.Interfaces;
|
||||
|
||||
using OpenMetaverse;
|
||||
using log4net;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
|
||||
{
|
||||
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_PresenceService.LogoutAgent(client.SessionId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -487,7 +487,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
return false;
|
||||
}
|
||||
|
||||
protected bool IsFriendWithPerms(UUID user,UUID objectOwner)
|
||||
protected bool IsFriendWithPerms(UUID user, UUID objectOwner)
|
||||
{
|
||||
if (user == UUID.Zero)
|
||||
return false;
|
||||
@@ -495,11 +495,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
if (m_friendsModule == null)
|
||||
return false;
|
||||
|
||||
uint friendPerms = m_friendsModule.GetFriendPerms(user, objectOwner);
|
||||
if ((friendPerms & (uint)FriendRights.CanModifyObjects) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
int friendPerms = m_friendsModule.GetRightsGrantedByFriend(user, objectOwner);
|
||||
return (friendPerms & (int)FriendRights.CanModifyObjects) != 0;
|
||||
}
|
||||
|
||||
protected bool IsEstateManager(UUID user)
|
||||
@@ -508,6 +505,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
||||
|
||||
return m_scene.RegionInfo.EstateSettings.IsEstateManager(user);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public bool PropagatePermissions()
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation
|
||||
}
|
||||
|
||||
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
|
||||
//rootPart.TrimPermissions();
|
||||
|
||||
Reference in New Issue
Block a user