Merge branch 'master' into careminster-presence-refactor

This commit is contained in:
Melanie
2011-06-09 02:05:04 +01:00
119 changed files with 6471 additions and 4318 deletions

View File

@@ -124,7 +124,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog
ScenePresence sp = m_scene.GetScenePresence(avatarID);
if (sp != null)
sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
sp.ControllingClient.SendDialog(
objectName, objectID, ownerID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels);
}
public void SendUrlToUser(

View File

@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
public class FriendsModule : ISharedRegionModule, IFriendsModule
{
protected bool m_Enabled = false;
protected class UserFriendData
{
public UUID PrincipalID;
@@ -67,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
private 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>();
@@ -130,7 +132,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
#region ISharedRegionModule
public void Initialise(IConfigSource config)
{
IConfig moduleConfig = config.Configs["Modules"];
if (moduleConfig != null)
{
string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
if (name == Name)
{
InitModule(config);
m_Enabled = true;
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
}
}
}
protected void InitModule(IConfigSource config)
{
IConfig friendsConfig = config.Configs["Friends"];
if (friendsConfig != null)
@@ -153,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
throw new Exception("Connector load error");
}
}
public void PostInitialise()
@@ -164,8 +182,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
}
public void AddRegion(Scene scene)
public virtual void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
m_Scenes.Add(scene);
scene.RegisterModuleInterface<IFriendsModule>(this);
@@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
m_Scenes.Remove(scene);
}
public string Name
public virtual string Name
{
get { return "FriendsModule"; }
}
@@ -194,13 +219,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
get { return null; }
}
public uint GetFriendPerms(UUID principalID, UUID friendID)
#endregion
public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
{
FriendInfo[] friends = GetFriends(principalID);
foreach (FriendInfo fi in friends)
FriendInfo finfo = GetFriend(friends, friendID);
if (finfo != null)
{
if (fi.Friend == friendID.ToString())
return (uint)fi.TheirFlags;
return (uint)finfo.TheirFlags;
}
return 0;
@@ -214,30 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.OnTerminateFriendship += OnTerminateFriendship;
client.OnGrantUserRights += OnGrantUserRights;
// Asynchronously fetch the friends list or increment the refcount for the existing
// friends list
Util.FireAndForget(
delegate(object o)
{
lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(client.AgentId, out friendsData))
{
friendsData.Refcount++;
}
else
{
friendsData = new UserFriendData();
friendsData.PrincipalID = client.AgentId;
friendsData.Friends = FriendsService.GetFriends(client.AgentId);
friendsData.Refcount = 1;
Util.FireAndForget(delegate { FetchFriendslist(client); });
}
m_Friends[client.AgentId] = friendsData;
}
}
/// Fetch the friends list or increment the refcount for the existing
/// friends list
/// Returns true if the list was fetched, false if it wasn't
protected virtual bool FetchFriendslist(IClientAPI client)
{
UUID agentID = client.AgentId;
lock (m_Friends)
{
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;
return true;
}
}
}
private void OnClientClosed(UUID agentID, Scene scene)
@@ -263,14 +294,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnMakeRootAgent(ScenePresence sp)
{
UUID agentID = sp.ControllingClient.AgentId;
UpdateFriendsCache(agentID);
RefetchFriends(sp.ControllingClient);
}
private void OnClientLogin(IClientAPI client)
{
UUID agentID = client.AgentId;
//m_log.DebugFormat("[XXX]: OnClientLogin!");
// Inform the friends that this user is online
StatusChange(agentID, true);
@@ -279,7 +310,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_NeedsListOfFriends.Add(agentID);
}
public void SendFriendsOnlineIfNeeded(IClientAPI client)
public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
{
UUID agentID = client.AgentId;
@@ -287,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
lock (m_NeedsListOfFriends)
{
if (!m_NeedsListOfFriends.Remove(agentID))
return;
return false;
}
// Send the friends online
@@ -313,10 +344,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
foreach (string fid in outstanding)
{
UUID fromAgentID;
if (!UUID.TryParse(fid, out fromAgentID))
string firstname = "Unknown", lastname = "User";
if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
{
m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
continue;
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
}
PresenceInfo presence = null;
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
@@ -326,13 +359,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
im.offline = 0;
im.fromAgentID = fromAgentID.Guid;
im.fromAgentName = account.FirstName + " " + account.LastName;
im.fromAgentName = firstname + " " + lastname;
im.offline = (byte)((presence == null) ? 1 : 0);
im.imSessionID = im.fromAgentID;
im.message = FriendshipMessage(fid);
// Finally
LocalFriendshipOffered(agentID, im);
}
return true;
}
protected virtual string FriendshipMessage(string friendID)
{
return "Will you be my friend?";
}
protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
{
first = "Unknown"; last = "User";
if (!UUID.TryParse(fid, out agentID))
return false;
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
if (account != null)
{
first = account.FirstName;
last = account.LastName;
}
return true;
}
List<UUID> GetOnlineFriends(UUID userID)
@@ -348,19 +405,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
if (friendList.Count > 0)
{
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
foreach (PresenceInfo pi in presence)
{
UUID presenceID;
if (UUID.TryParse(pi.UserID, out presenceID))
online.Add(presenceID);
}
}
GetOnlineFriends(userID, friendList, online);
return online;
}
protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
{
PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
foreach (PresenceInfo pi in presence)
{
UUID presenceID;
if (UUID.TryParse(pi.UserID, out presenceID))
online.Add(presenceID);
}
}
/// <summary>
/// Find the client for a ID
/// </summary>
@@ -415,51 +475,51 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
Util.FireAndForget(
delegate
{
foreach (FriendInfo fi in friendList)
{
//m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID);
// Notify about this user status
StatusNotify(fi, agentID, online);
}
m_log.DebugFormat("[FRIENDS MODULE]: Notifying {0} friends", friendList.Count);
// Notify about this user status
StatusNotify(friendList, agentID, online);
}
);
}
}
private void StatusNotify(FriendInfo friend, UUID userID, bool online)
protected virtual void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{
UUID friendID;
if (UUID.TryParse(friend.Friend, out friendID))
foreach (FriendInfo friend in friendList)
{
// Try local
if (LocalStatusNotification(userID, friendID, online))
return;
// The friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0)
UUID friendID;
if (UUID.TryParse(friend.Friend, out friendID))
{
PresenceInfo friendSession = null;
foreach (PresenceInfo pinfo in friendSessions)
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
{
friendSession = pinfo;
break;
}
// Try local
if (LocalStatusNotification(userID, friendID, online))
return;
if (friendSession != null)
// The friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
if (friendSessions != null && friendSessions.Length > 0)
{
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
}
}
PresenceInfo friendSession = null;
foreach (PresenceInfo pinfo in friendSessions)
if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
{
friendSession = pinfo;
break;
}
// Friend is not online. Ignore.
}
else
{
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
if (friendSession != null)
{
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
//m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
}
}
// Friend is not online. Ignore.
}
else
{
m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
}
}
}
@@ -475,7 +535,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// This user wants to be friends with the other user.
// Let's add the relation backwards, in case the other is not online
FriendsService.StoreFriend(friendID, principalID.ToString(), 0);
StoreBackwards(friendID, principalID);
// Now let's ask the other user to be friends with this user
ForwardFriendshipOffer(principalID, friendID, im);
@@ -487,11 +547,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
im.imSessionID = im.fromAgentID;
im.fromAgentName = GetFriendshipRequesterName(agentID);
// Try the local sim
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
// Try the local sim
if (LocalFriendshipOffered(friendID, im))
return;
@@ -509,12 +567,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// If the prospective friend is not online, he'll get the message upon login.
}
protected virtual string GetFriendshipRequesterName(UUID agentID)
{
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
}
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
{
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
FriendsService.StoreFriend(agentID, friendID.ToString(), 1);
FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
StoreFriendships(agentID, friendID);
ICallingCardModule ccm = client.Scene.RequestModuleInterface<ICallingCardModule>();
if (ccm != null)
@@ -523,7 +586,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
// Update the local cache
UpdateFriendsCache(agentID);
RefetchFriends(client);
//
// Notify the friend
@@ -554,8 +617,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
FriendsService.Delete(agentID, friendID.ToString());
FriendsService.Delete(friendID, agentID.ToString());
DeleteFriendship(agentID, friendID);
//
// Notify the friend
@@ -582,11 +644,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
{
FriendsService.Delete(agentID, exfriendID.ToString());
FriendsService.Delete(exfriendID, agentID.ToString());
if (!DeleteFriendship(agentID, exfriendID))
client.SendAlertMessage("Unable to terminate friendship on this sim.");
// Update local cache
UpdateFriendsCache(agentID);
RefetchFriends(client);
client.SendTerminateFriend(exfriendID);
@@ -612,23 +674,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
{
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
if (friends.Length == 0)
return;
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
// Let's find the friend in this user's friend list
FriendInfo friend = null;
foreach (FriendInfo fi in friends)
{
if (fi.Friend == target.ToString())
friend = fi;
return;
}
// Let's find the friend in this user's friend list
FriendInfo friend = GetFriend(friends, target);
if (friend != null) // Found it
{
// Store it on the DB
FriendsService.StoreFriend(requester, target.ToString(), rights);
if (!StoreRights(requester, target, rights))
{
remoteClient.SendAlertMessage("Unable to grant rights.");
return;
}
// Store it in the local cache
int myFlags = friend.MyFlags;
@@ -658,6 +722,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
}
else
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
}
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
{
foreach (FriendInfo fi in friends)
{
if (fi.Friend == friendID.ToString())
return fi;
}
return null;
}
#region Local
@@ -693,7 +769,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Update the local cache
UpdateFriendsCache(friendID);
RefetchFriends(friendClient);
// we're done
return true;
@@ -726,7 +802,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// the friend in this sim as root agent
friendClient.SendTerminateFriend(exfriendID);
// update local cache
UpdateFriendsCache(exfriendID);
RefetchFriends(friendClient);
// we're done
return true;
}
@@ -756,15 +832,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
// Update local cache
lock (m_Friends)
{
FriendInfo[] friends = GetFriends(friendID);
foreach (FriendInfo finfo in friends)
{
if (finfo.Friend == userID.ToString())
finfo.TheirFlags = rights;
}
}
UpdateLocalCache(userID, friendID, rights);
return true;
}
@@ -775,10 +843,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
public bool LocalStatusNotification(UUID userID, UUID friendID, bool online)
{
m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
IClientAPI friendClient = LocateClientObject(friendID);
if (friendClient != null)
{
//m_log.DebugFormat("[FRIENDS]: Local Status Notify {0} that user {1} is {2}", friendID, userID, online);
// the friend in this sim as root agent
if (online)
friendClient.SendAgentOnline(new UUID[] { userID });
@@ -793,7 +861,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion
private FriendInfo[] GetFriends(UUID agentID)
#region Get / Set friends in several flavours
/// <summary>
/// Get friends from local cache only
/// </summary>
/// <param name="agentID"></param>
/// <returns></returns>
protected FriendInfo[] GetFriends(UUID agentID)
{
UserFriendData friendsData;
@@ -806,14 +880,63 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return EMPTY_FRIENDS;
}
private void UpdateFriendsCache(UUID agentID)
/// <summary>
/// Update loca cache only
/// </summary>
/// <param name="userID"></param>
/// <param name="friendID"></param>
/// <param name="rights"></param>
protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
{
// Update local cache
lock (m_Friends)
{
FriendInfo[] friends = GetFriends(friendID);
FriendInfo finfo = GetFriend(friends, userID);
finfo.TheirFlags = rights;
}
}
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
{
return FriendsService.GetFriends(client.AgentId);
}
private void RefetchFriends(IClientAPI client)
{
UUID agentID = client.AgentId;
lock (m_Friends)
{
UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData))
friendsData.Friends = FriendsService.GetFriends(agentID);
friendsData.Friends = GetFriendsFromService(client);
}
}
protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
{
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
return true;
}
protected virtual void StoreBackwards(UUID friendID, UUID agentID)
{
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
}
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
{
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
}
protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
{
FriendsService.Delete(agentID, exfriendID.ToString());
FriendsService.Delete(exfriendID, agentID.ToString());
return true;
}
#endregion
}
}

View File

@@ -0,0 +1,628 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using log4net;
using Nini.Config;
using Nwc.XmlRpc;
using Mono.Addins;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.Avatar.Friends
{
public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule, IFriendsSimConnector
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region ISharedRegionModule
public override string Name
{
get { return "HGFriendsModule"; }
}
public override void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
base.AddRegion(scene);
scene.RegisterModuleInterface<IFriendsSimConnector>(this);
}
#endregion
#region IFriendsSimConnector
/// <summary>
/// Notify the user that the friend's status changed
/// </summary>
/// <param name="userID">user to be notified</param>
/// <param name="friendID">friend whose status changed</param>
/// <param name="online">status</param>
/// <returns></returns>
public bool StatusNotify(UUID friendID, UUID userID, bool online)
{
return LocalStatusNotification(friendID, userID, online);
}
#endregion
protected override bool FetchFriendslist(IClientAPI client)
{
if (base.FetchFriendslist(client))
{
UUID agentID = client.AgentId;
// we do this only for the root agent
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
foreach (FriendInfo finfo in m_Friends[agentID].Friends)
{
if (finfo.TheirFlags != -1)
{
UUID id;
if (!UUID.TryParse(finfo.Friend, out id))
{
string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
{
IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
uMan.AddUser(id, url + ";" + first + " " + last);
}
}
}
}
return true;
}
}
return false;
}
public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
{
if (base.SendFriendsOnlineIfNeeded(client))
{
AgentCircuitData aCircuit = ((Scene)client.Scene).AuthenticateHandler.GetAgentCircuitData(client.AgentId);
if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
{
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
if (account == null) // foreign
{
FriendInfo[] friends = GetFriends(client.AgentId);
foreach (FriendInfo f in friends)
{
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
}
}
}
}
return false;
}
protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
{
List<string> fList = new List<string>();
foreach (string s in friendList)
fList.Add(s.Substring(0, 36));
PresenceInfo[] presence = PresenceService.GetAgents(fList.ToArray());
foreach (PresenceInfo pi in presence)
{
UUID presenceID;
if (UUID.TryParse(pi.UserID, out presenceID))
online.Add(presenceID);
}
}
//protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
//{
// // Let's single out the UUIs
// List<string> localFriends = new List<string>();
// List<string> foreignFriends = new List<string>();
// string tmp = string.Empty;
// foreach (string s in friendList)
// {
// UUID id;
// if (UUID.TryParse(s, out id))
// localFriends.Add(s);
// else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
// {
// foreignFriends.Add(s);
// // add it here too, who knows maybe the foreign friends happens to be on this grid
// localFriends.Add(id.ToString());
// }
// }
// // OK, see who's present on this grid
// List<string> toBeRemoved = new List<string>();
// PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
// foreach (PresenceInfo pi in presence)
// {
// UUID presenceID;
// if (UUID.TryParse(pi.UserID, out presenceID))
// {
// online.Add(presenceID);
// foreach (string s in foreignFriends)
// if (s.StartsWith(pi.UserID))
// toBeRemoved.Add(s);
// }
// }
// foreach (string s in toBeRemoved)
// foreignFriends.Remove(s);
// // OK, let's send this up the stack, and leave a closure here
// // collecting online friends in other grids
// Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
//}
private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
{
// let's divide the friends on a per-domain basis
Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
foreach (string friend in foreignFriends)
{
UUID friendID;
if (!UUID.TryParse(friend, out friendID))
{
// it's a foreign friend
string url = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
{
if (!friendsPerDomain.ContainsKey(url))
friendsPerDomain[url] = new List<string>();
friendsPerDomain[url].Add(friend);
}
}
}
// Now, call those worlds
foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
{
List<string> ids = new List<string>();
foreach (string f in kvp.Value)
ids.Add(f);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
List<UUID> online = uConn.GetOnlineFriends(userID, ids);
// Finally send the notifications to the user
// this whole process may take a while, so let's check at every
// iteration that the user is still here
IClientAPI client = LocateClientObject(userID);
if (client != null)
client.SendAgentOnline(online.ToArray());
else
break;
}
}
protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
{
// First, let's divide the friends on a per-domain basis
Dictionary<string, List<FriendInfo>> friendsPerDomain = new Dictionary<string, List<FriendInfo>>();
foreach (FriendInfo friend in friendList)
{
UUID friendID;
if (UUID.TryParse(friend.Friend, out friendID))
{
if (!friendsPerDomain.ContainsKey("local"))
friendsPerDomain["local"] = new List<FriendInfo>();
friendsPerDomain["local"].Add(friend);
}
else
{
// it's a foreign friend
string url = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out tmp, out tmp, out tmp))
{
// Let's try our luck in the local sim. Who knows, maybe it's here
if (LocalStatusNotification(userID, friendID, online))
continue;
if (!friendsPerDomain.ContainsKey(url))
friendsPerDomain[url] = new List<FriendInfo>();
friendsPerDomain[url].Add(friend);
}
}
}
// For the local friends, just call the base method
// Let's do this first of all
if (friendsPerDomain.ContainsKey("local"))
base.StatusNotify(friendsPerDomain["local"], userID, online);
foreach (KeyValuePair<string, List<FriendInfo>> kvp in friendsPerDomain)
{
if (kvp.Key != "local")
{
// For the others, call the user agent service
List<string> ids = new List<string>();
foreach (FriendInfo f in kvp.Value)
ids.Add(f.Friend);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
List<UUID> friendsOnline = uConn.StatusNotification(ids, userID, online);
// need to debug this here
if (online)
{
IClientAPI client = LocateClientObject(userID);
if (client != null)
client.SendAgentOnline(friendsOnline.ToArray());
}
}
}
}
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
{
first = "Unknown"; last = "User";
if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
return true;
// fid is not a UUID...
string url = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
{
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
userMan.AddUser(agentID, url + ";" + first + " " + last);
try // our best
{
string[] parts = userMan.GetUserName(agentID).Split();
first = parts[0];
last = parts[1];
}
catch { }
return true;
}
return false;
}
protected override string GetFriendshipRequesterName(UUID agentID)
{
// For the time being we assume that HG friendship requests can only happen
// when avies are on the same region.
IClientAPI client = LocateClientObject(agentID);
if (client != null)
return client.FirstName + " " + client.LastName;
else
return base.GetFriendshipRequesterName(agentID);
}
protected override string FriendshipMessage(string friendID)
{
UUID id;
if (UUID.TryParse(friendID, out id))
return base.FriendshipMessage(friendID);
return "Please confirm this friendship you made while you were away.";
}
protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
{
foreach (FriendInfo fi in friends)
{
if (fi.Friend.StartsWith(friendID.ToString()))
return fi;
}
return null;
}
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
{
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
if (account1 != null)
return base.GetFriendsFromService(client);
FriendInfo[] finfos = new FriendInfo[0];
// Foreigner
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
if (agentClientCircuit != null)
{
string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
finfos = FriendsService.GetFriends(agentUUI);
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
}
return finfos;
}
protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
{
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
// Are they both local users?
if (account1 != null && account2 != null)
{
// local grid users
return base.StoreRights(agentID, friendID, rights);
}
if (account1 != null) // agent is local, friend is foreigner
{
FriendInfo[] finfos = GetFriends(agentID);
FriendInfo finfo = GetFriend(finfos, friendID);
if (finfo != null)
{
FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
return true;
}
}
if (account2 != null) // agent is foreigner, friend is local
{
string agentUUI = GetUUI(friendID, agentID);
if (agentUUI != string.Empty)
{
FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
return true;
}
}
return false;
}
protected override void StoreBackwards(UUID friendID, UUID agentID)
{
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
// Are they both local users?
if (account1 != null && account2 != null)
{
// local grid users
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
base.StoreBackwards(friendID, agentID);
return;
}
// no provision for this temporary friendship state
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
}
protected override void StoreFriendships(UUID agentID, UUID friendID)
{
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
// Are they both local users?
if (agentAccount != null && friendAccount != null)
{
// local grid users
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
base.StoreFriendships(agentID, friendID);
return;
}
// ok, at least one of them is foreigner, let's get their data
IClientAPI agentClient = LocateClientObject(agentID);
IClientAPI friendClient = LocateClientObject(friendID);
AgentCircuitData agentClientCircuit = null;
AgentCircuitData friendClientCircuit = null;
string agentUUI = string.Empty;
string friendUUI = string.Empty;
string agentFriendService = string.Empty;
string friendFriendService = string.Empty;
if (agentClient != null)
{
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
}
if (friendClient != null)
{
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
}
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
agentUUI, friendUUI, agentFriendService, friendFriendService);
// Generate a random 8-character hex number that will sign this friendship
string secret = UUID.Random().ToString().Substring(0, 8);
if (agentAccount != null) // agent is local, 'friend' is foreigner
{
// This may happen when the agent returned home, in which case the friend is not there
// We need to look for its information in the friends list itself
bool confirming = false;
if (friendUUI == string.Empty)
{
FriendInfo[] finfos = GetFriends(agentID);
foreach (FriendInfo finfo in finfos)
{
if (finfo.TheirFlags == -1)
{
if (finfo.Friend.StartsWith(friendID.ToString()))
{
friendUUI = finfo.Friend;
confirming = true;
}
}
}
}
// If it's confirming the friendship, we already have the full friendUUI with the secret
string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
// store in the local friends service a reference to the foreign friend
FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
// and also the converse
FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
if (!confirming && friendClientCircuit != null)
{
// store in the foreign friends service a reference to the local agent
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
}
}
else if (friendAccount != null) // 'friend' is local, agent is foreigner
{
// store in the local friends service a reference to the foreign agent
FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
// and also the converse
FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
if (agentClientCircuit != null)
{
// store in the foreign friends service a reference to the local agent
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
}
}
else // They're both foreigners!
{
HGFriendsServicesConnector friendsConn;
if (agentClientCircuit != null)
{
friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
}
if (friendClientCircuit != null)
{
friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
}
}
// my brain hurts now
}
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
{
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
// Are they both local users?
if (agentAccount != null && friendAccount != null)
{
// local grid users
return base.DeleteFriendship(agentID, exfriendID);
}
// ok, at least one of them is foreigner, let's get their data
string agentUUI = string.Empty;
string friendUUI = string.Empty;
if (agentAccount != null) // agent is local, 'friend' is foreigner
{
// We need to look for its information in the friends list itself
FriendInfo[] finfos = GetFriends(agentID);
FriendInfo finfo = GetFriend(finfos, exfriendID);
if (finfo != null)
{
friendUUI = finfo.Friend;
// delete in the local friends service the reference to the foreign friend
FriendsService.Delete(agentID, friendUUI);
// and also the converse
FriendsService.Delete(friendUUI, agentID.ToString());
// notify the exfriend's service
Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
return true;
}
}
else if (friendAccount != null) // agent is foreigner, 'friend' is local
{
agentUUI = GetUUI(exfriendID, agentID);
if (agentUUI != string.Empty)
{
// delete in the local friends service the reference to the foreign agent
FriendsService.Delete(exfriendID, agentUUI);
// and also the converse
FriendsService.Delete(agentUUI, exfriendID.ToString());
// notify the agent's service?
Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
return true;
}
}
//else They're both foreigners! Can't handle this
return false;
}
private string GetUUI(UUID localUser, UUID foreignUser)
{
// Let's see if the user is here by any chance
FriendInfo[] finfos = GetFriends(localUser);
if (finfos != EMPTY_FRIENDS) // friend is here, cool
{
FriendInfo finfo = GetFriend(finfos, foreignUser);
if (finfo != null)
{
return finfo.Friend;
}
}
else // user is not currently on this sim, need to get from the service
{
finfos = FriendsService.GetFriends(localUser);
foreach (FriendInfo finfo in finfos)
{
if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
{
return finfo.Friend;
}
}
}
return string.Empty;
}
private void Delete(UUID foreignUser, UUID localUser, string uui)
{
UUID id;
string url = string.Empty, secret = string.Empty, tmp = string.Empty;
if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
{
m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
friendConn.DeleteFriendship(foreignUser, localUser, secret);
}
}
}
}

View File

@@ -0,0 +1,350 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using log4net;
using Nini.Config;
using Nwc.XmlRpc;
using Mono.Addins;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.InstantMessage;
using OpenSim.Services.Connectors.Hypergrid;
using OpenSim.Server.Handlers.Hypergrid;
namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class HGMessageTransferModule : ISharedRegionModule, IMessageTransferModule, IInstantMessageSimConnector
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected bool m_Enabled = false;
protected List<Scene> m_Scenes = new List<Scene>();
protected IInstantMessage m_IMService;
protected Dictionary<UUID, object> m_UserLocationMap = new Dictionary<UUID, object>();
public event UndeliveredMessage OnUndeliveredMessage;
IUserManagement m_uMan;
IUserManagement UserManagementModule
{
get
{
if (m_uMan == null)
m_uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
return m_uMan;
}
}
public virtual void Initialise(IConfigSource config)
{
IConfig cnf = config.Configs["Messaging"];
if (cnf != null && cnf.GetString(
"MessageTransferModule", "MessageTransferModule") != Name)
{
m_log.Debug("[HG MESSAGE TRANSFER]: Disabled by configuration");
return;
}
InstantMessageServerConnector imServer = new InstantMessageServerConnector(config, MainServer.Instance, this);
m_IMService = imServer.GetService();
m_Enabled = true;
}
public virtual void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
lock (m_Scenes)
{
m_log.DebugFormat("[HG MESSAGE TRANSFER]: Message transfer module {0} active", Name);
scene.RegisterModuleInterface<IMessageTransferModule>(this);
m_Scenes.Add(scene);
}
}
public virtual void PostInitialise()
{
if (!m_Enabled)
return;
}
public virtual void RegionLoaded(Scene scene)
{
}
public virtual void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
lock (m_Scenes)
{
m_Scenes.Remove(scene);
}
}
public virtual void Close()
{
}
public virtual string Name
{
get { return "HGMessageTransferModule"; }
}
public virtual Type ReplaceableInterface
{
get { return null; }
}
public void SendInstantMessage(GridInstantMessage im, MessageResultNotification result)
{
UUID toAgentID = new UUID(im.toAgentID);
// Try root avatar only first
foreach (Scene scene in m_Scenes)
{
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
// m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}",
// toAgentID.ToString(), scene.RegionInfo.RegionName);
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
if (!user.IsChildAgent)
{
// Local message
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID);
user.ControllingClient.SendInstantMessage(im);
// Message sent
result(true);
return;
}
}
}
// try child avatar second
foreach (Scene scene in m_Scenes)
{
// m_log.DebugFormat(
// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName);
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
// Local message
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID);
user.ControllingClient.SendInstantMessage(im);
// Message sent
result(true);
return;
}
}
// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID);
// Is the user a local user?
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID);
string url = string.Empty;
bool foreigner = false;
if (account == null) // foreign user
{
url = UserManagementModule.GetUserServerURL(toAgentID, "IMServerURI");
foreigner = true;
}
Util.FireAndForget(delegate
{
bool success = false;
if (foreigner && url == string.Empty) // we don't know about this user
{
string recipientUUI = TryGetRecipientUUI(new UUID(im.fromAgentID), toAgentID);
m_log.DebugFormat("[HG MESSAGE TRANSFER]: Got UUI {0}", recipientUUI);
if (recipientUUI != string.Empty)
{
UUID id; string u = string.Empty, first = string.Empty, last = string.Empty, secret = string.Empty;
if (Util.ParseUniversalUserIdentifier(recipientUUI, out id, out u, out first, out last, out secret))
{
success = m_IMService.OutgoingInstantMessage(im, u, true);
if (success)
UserManagementModule.AddUser(toAgentID, u + ";" + first + " " + last);
}
}
}
else
success = m_IMService.OutgoingInstantMessage(im, url, foreigner);
if (!success && !foreigner)
HandleUndeliveredMessage(im, result);
else
result(success);
});
return;
}
protected bool SendIMToScene(GridInstantMessage gim, UUID toAgentID)
{
bool successful = false;
foreach (Scene scene in m_Scenes)
{
if (scene.Entities.ContainsKey(toAgentID) &&
scene.Entities[toAgentID] is ScenePresence)
{
ScenePresence user =
(ScenePresence)scene.Entities[toAgentID];
if (!user.IsChildAgent)
{
scene.EventManager.TriggerIncomingInstantMessage(gim);
successful = true;
}
}
}
if (!successful)
{
// If the message can't be delivered to an agent, it
// is likely to be a group IM. On a group IM, the
// imSessionID = toAgentID = group id. Raise the
// unhandled IM event to give the groups module
// a chance to pick it up. We raise that in a random
// scene, since the groups module is shared.
//
m_Scenes[0].EventManager.TriggerUnhandledInstantMessage(gim);
}
return successful;
}
protected void HandleUndeliveredMessage(GridInstantMessage im, MessageResultNotification result)
{
UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage;
// If this event has handlers, then an IM from an agent will be
// considered delivered. This will suppress the error message.
//
if (handlerUndeliveredMessage != null)
{
handlerUndeliveredMessage(im);
if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
result(true);
else
result(false);
return;
}
//m_log.DebugFormat("[INSTANT MESSAGE]: Undeliverable");
result(false);
}
private string TryGetRecipientUUI(UUID fromAgent, UUID toAgent)
{
// Let's call back the fromAgent's user agent service
// Maybe that service knows about the toAgent
IClientAPI client = LocateClientObject(fromAgent);
if (client != null)
{
AgentCircuitData circuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.AgentId);
if (circuit != null)
{
if (circuit.ServiceURLs.ContainsKey("HomeURI"))
{
string uasURL = circuit.ServiceURLs["HomeURI"].ToString();
m_log.DebugFormat("[HG MESSAGE TRANSFER]: getting UUI of user {0} from {1}", toAgent, uasURL);
UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uasURL);
return uasConn.GetUUI(fromAgent, toAgent);
}
}
}
return string.Empty;
}
/// <summary>
/// Find the scene for an agent
/// </summary>
private Scene GetClientScene(UUID agentId)
{
lock (m_Scenes)
{
foreach (Scene scene in m_Scenes)
{
ScenePresence presence = scene.GetScenePresence(agentId);
if (presence != null && !presence.IsChildAgent)
return scene;
}
}
return null;
}
/// <summary>
/// Find the client for a ID
/// </summary>
public IClientAPI LocateClientObject(UUID agentID)
{
Scene scene = GetClientScene(agentID);
if (scene != null)
{
ScenePresence presence = scene.GetScenePresence(agentID);
if (presence != null)
return presence.ControllingClient;
}
return null;
}
#region IInstantMessageSimConnector
public bool SendInstantMessage(GridInstantMessage im)
{
//m_log.DebugFormat("[XXX] Hook SendInstantMessage {0}", im.message);
UUID agentID = new UUID(im.toAgentID);
return SendIMToScene(im, agentID);
}
#endregion
}
}

View File

@@ -149,14 +149,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
/// <summary>
/// Find an item given a PATH_DELIMITOR delimited path starting from the user's root folder.
///
/// </summary>
/// <remarks>
/// This method does not handle paths that contain multiple delimitors
///
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
/// XPath like expression
///
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
/// </summary>
/// </remarks>
///
/// <param name="inventoryService">
/// Inventory service to query
@@ -178,32 +179,66 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
return FindItemByPath(inventoryService, rootFolder, path);
}
/// <summary>
/// Find an item given a PATH_DELIMITOR delimited path starting from this folder.
///
/// This method does not handle paths that contain multiple delimitors
/// </summary>
/// <remarks>
/// This method does not handle paths that contain multiple delimiters
///
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
/// XPath like expression
///
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
/// </summary>
///
/// <param name="inventoryService">
/// Inventory service to query
/// </param>
/// <param name="startFolder">
/// The folder from which the path starts
/// </param>
/// <param name="path">
/// <param name="path">
/// The path to the required item.
/// </param>
/// </remarks>
///
/// <param name="inventoryService">Inventory service to query</param>
/// <param name="startFolder">The folder from which the path starts</param>
/// <param name="path">The path to the required item.</param>
/// <returns>null if the item is not found</returns>
public static InventoryItemBase FindItemByPath(
IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
{
List<InventoryItemBase> foundItems = FindItemsByPath(inventoryService, startFolder, path);
if (foundItems.Count != 0)
return foundItems[0];
else
return null;
}
public static List<InventoryItemBase> FindItemsByPath(
IInventoryService inventoryService, UUID userId, string path)
{
InventoryFolderBase rootFolder = inventoryService.GetRootFolder(userId);
if (null == rootFolder)
return new List<InventoryItemBase>();
return FindItemsByPath(inventoryService, rootFolder, path);
}
/// <summary>
/// Find items that match a given PATH_DELIMITOR delimited path starting from this folder.
/// </summary>
/// <remarks>
/// This method does not handle paths that contain multiple delimiters
///
/// FIXME: We do not yet handle situations where folders or items have the same name. We could handle this by some
/// XPath like expression
///
/// FIXME: Delimitors which occur in names themselves are not currently escapable.
/// </remarks>
///
/// <param name="inventoryService">Inventory service to query</param>
/// <param name="startFolder">The folder from which the path starts</param>
/// <param name="path">The path to the required item.</param>
/// <returns>The items that were found with this path. An empty list if no items were found.</returns>
public static List<InventoryItemBase> FindItemsByPath(
IInventoryService inventoryService, InventoryFolderBase startFolder, string path)
{
List<InventoryItemBase> foundItems = new List<InventoryItemBase>();
// If the path isn't just / then trim any starting extraneous slashes
path = path.TrimStart(new char[] { PATH_DELIMITER });
@@ -215,11 +250,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
if (components.Length == 1)
{
// m_log.DebugFormat(
// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
// "FOUND SINGLE COMPONENT [{0}]. Looking for this in [{1}] {2}",
// components[0], startFolder.Name, startFolder.ID);
List<InventoryItemBase> items = inventoryService.GetFolderItems(startFolder.Owner, startFolder.ID);
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Found {0} items in FindItemByPath()", items.Count);
foreach (InventoryItemBase item in items)
@@ -227,24 +262,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// m_log.DebugFormat("[INVENTORY ARCHIVE UTILS]: Inspecting item {0} {1}", item.Name, item.ID);
if (item.Name == components[0])
return item;
foundItems.Add(item);
}
}
else
{
// m_log.DebugFormat("FOUND COMPONENTS [{0}] and [{1}]", components[0], components[1]);
InventoryCollection contents = inventoryService.GetFolderContent(startFolder.Owner, startFolder.ID);
foreach (InventoryFolderBase folder in contents.Folders)
{
if (folder.Name == components[0])
return FindItemByPath(inventoryService, folder, components[1]);
foundItems.AddRange(FindItemsByPath(inventoryService, folder, components[1]));
}
}
// We didn't find an item or intermediate folder with the given name
return null;
return foundItems;
}
/// <summary>

View File

@@ -154,7 +154,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
string serialization = UserInventoryItemSerializer.Serialize(inventoryItem, options, userAccountService);
m_archiveWriter.WriteFile(filename, serialization);
if (SaveAssets)
AssetType itemAssetType = (AssetType)inventoryItem.AssetType;
// Don't chase down link asset items as they actually point to their target item IDs rather than an asset
if (SaveAssets && itemAssetType != AssetType.Link && itemAssetType != AssetType.LinkFolder)
m_assetGatherer.GatherAssetUuids(inventoryItem.AssetID, (AssetType)inventoryItem.AssetType, m_assetUuids);
}
@@ -246,10 +249,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
// The path may point to an item instead
if (inventoryFolder == null)
{
inventoryItem = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, rootFolder, m_invPath);
//inventoryItem = m_userInfo.RootFolder.FindItemByPath(m_invPath);
}
if (null == inventoryFolder && null == inventoryItem)
{

View File

@@ -0,0 +1,244 @@
/*
* 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;
using Nini.Config;
using OpenMetaverse;
using Mono.Addins;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Connectors.Hypergrid;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Region.CoreModules.Avatar.Lure
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class HGLureModule : ISharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private readonly List<Scene> m_scenes = new List<Scene>();
private IMessageTransferModule m_TransferModule = null;
private bool m_Enabled = false;
private string m_ThisGridURL;
private ExpiringCache<UUID, GridInstantMessage> m_PendingLures = new ExpiringCache<UUID, GridInstantMessage>();
public void Initialise(IConfigSource config)
{
if (config.Configs["Messaging"] != null)
{
if (config.Configs["Messaging"].GetString("LureModule", string.Empty) == "HGLureModule")
{
m_Enabled = true;
m_ThisGridURL = config.Configs["Messaging"].GetString("Gatekeeper", string.Empty);
m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
}
}
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
lock (m_scenes)
{
m_scenes.Add(scene);
scene.EventManager.OnIncomingInstantMessage += OnIncomingInstantMessage;
scene.EventManager.OnNewClient += OnNewClient;
}
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
if (m_TransferModule == null)
{
m_TransferModule =
scene.RequestModuleInterface<IMessageTransferModule>();
if (m_TransferModule == null)
{
m_log.Error("[LURE MODULE]: No message transfer module, lures will not work!");
m_Enabled = false;
m_scenes.Clear();
scene.EventManager.OnNewClient -= OnNewClient;
scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
}
}
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
lock (m_scenes)
{
m_scenes.Remove(scene);
scene.EventManager.OnNewClient -= OnNewClient;
scene.EventManager.OnIncomingInstantMessage -= OnIncomingInstantMessage;
}
}
void OnNewClient(IClientAPI client)
{
client.OnInstantMessage += OnInstantMessage;
client.OnStartLure += OnStartLure;
client.OnTeleportLureRequest += OnTeleportLureRequest;
}
public void PostInitialise()
{
}
public void Close()
{
}
public string Name
{
get { return "HGLureModule"; }
}
public Type ReplaceableInterface
{
get { return null; }
}
void OnInstantMessage(IClientAPI client, GridInstantMessage im)
{
}
void OnIncomingInstantMessage(GridInstantMessage im)
{
if (im.dialog == (byte)InstantMessageDialog.RequestTeleport)
{
UUID sessionID = new UUID(im.imSessionID);
m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message);
m_PendingLures.Add(sessionID, im, 7200); // 2 hours
// Forward. We do this, because the IM module explicitly rejects
// IMs of this type
if (m_TransferModule != null)
m_TransferModule.SendInstantMessage(im, delegate(bool success) { });
}
}
public void OnStartLure(byte lureType, string message, UUID targetid, IClientAPI client)
{
if (!(client.Scene is Scene))
return;
Scene scene = (Scene)(client.Scene);
ScenePresence presence = scene.GetScenePresence(client.AgentId);
message += "@" + m_ThisGridURL;
m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message);
GridInstantMessage m = new GridInstantMessage(scene, client.AgentId,
client.FirstName+" "+client.LastName, targetid,
(byte)InstantMessageDialog.RequestTeleport, false,
message, UUID.Random(), false, presence.AbsolutePosition,
new Byte[0]);
m.RegionID = client.Scene.RegionInfo.RegionID.Guid;
if (m_TransferModule != null)
{
m_TransferModule.SendInstantMessage(m,
delegate(bool success) { });
}
}
public void OnTeleportLureRequest(UUID lureID, uint teleportFlags, IClientAPI client)
{
if (!(client.Scene is Scene))
return;
Scene scene = (Scene)(client.Scene);
GridInstantMessage im = null;
if (m_PendingLures.TryGetValue(lureID, out im))
{
m_PendingLures.Remove(lureID);
Lure(client, teleportFlags, im);
}
else
m_log.DebugFormat("[HG LURE MODULE]: pending lure {0} not found", lureID);
}
private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im)
{
Scene scene = (Scene)(client.Scene);
GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID));
if (region != null)
scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags);
else // we don't have that region here. Check if it's HG
{
string[] parts = im.message.Split(new char[] { '@' });
if (parts.Length > 1)
{
string url = parts[parts.Length - 1]; // the last part
if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'}))
{
m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position);
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
GridRegion gatekeeper = new GridRegion();
gatekeeper.ServerURI = url;
GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID));
if (finalDestination != null)
{
ScenePresence sp = scene.GetScenePresence(client.AgentId);
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
if (transferMod != null && sp != null && eq != null)
transferMod.DoTeleport(sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags, eq);
}
}
}
}
}
}
}

View File

@@ -45,16 +45,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
private readonly List<Scene> m_scenes = new List<Scene>();
private IMessageTransferModule m_TransferModule = null;
private bool m_Enabled = true;
private bool m_Enabled = false;
public void Initialise(IConfigSource config)
{
if (config.Configs["Messaging"] != null)
{
if (config.Configs["Messaging"].GetString(
"LureModule", "LureModule") !=
"LureModule", "LureModule") ==
"LureModule")
m_Enabled = false;
{
m_Enabled = true;
m_log.DebugFormat("[LURE MODULE]: {0} enabled", Name);
}
}
}
@@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
if (m_TransferModule == null)
{
m_TransferModule =
@@ -96,6 +102,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
lock (m_scenes)
{
m_scenes.Remove(scene);

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using OpenMetaverse;
using log4net;
using Nini.Config;
using Mono.Addins;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
namespace OpenSim.Region.CoreModules.Avatar.Profile
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
public class BasicProfileModule : ISharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//
// Module vars
//
private List<Scene> m_Scenes = new List<Scene>();
private bool m_Enabled = false;
#region ISharedRegionModule
public void Initialise(IConfigSource config)
{
if (config.Configs["Profile"] != null)
{
if (config.Configs["Profile"].GetString("Module", string.Empty) != "BasicProfileModule")
return;
}
m_log.DebugFormat("[PROFILE MODULE]: Basic Profile Module enabled");
m_Enabled = true;
}
public void AddRegion(Scene scene)
{
if (!m_Enabled)
return;
lock (m_Scenes)
{
if (!m_Scenes.Contains(scene))
{
m_Scenes.Add(scene);
// Hook up events
scene.EventManager.OnNewClient += OnNewClient;
}
}
}
public void RegionLoaded(Scene scene)
{
if (!m_Enabled)
return;
}
public void RemoveRegion(Scene scene)
{
if (!m_Enabled)
return;
lock (m_Scenes)
{
m_Scenes.Remove(scene);
}
}
public void PostInitialise()
{
}
public void Close()
{
}
public string Name
{
get { return "BasicProfileModule"; }
}
public Type ReplaceableInterface
{
get { return null; }
}
#endregion
/// New Client Event Handler
private void OnNewClient(IClientAPI client)
{
//Profile
client.OnRequestAvatarProperties += RequestAvatarProperties;
}
public void RequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
{
IScene s = remoteClient.Scene;
if (!(s is Scene))
return;
Scene scene = (Scene)s;
string profileUrl = String.Empty;
string aboutText = String.Empty;
string firstLifeAboutText = String.Empty;
UUID image = UUID.Zero;
UUID firstLifeImage = UUID.Zero;
UUID partner = UUID.Zero;
uint wantMask = 0;
string wantText = String.Empty;
uint skillsMask = 0;
string skillsText = String.Empty;
string languages = String.Empty;
Byte[] charterMember = Utils.StringToBytes("Avatar");
profileUrl = "No profile data";
aboutText = string.Empty;
firstLifeAboutText = string.Empty;
image = UUID.Zero;
firstLifeImage = UUID.Zero;
partner = UUID.Zero;
remoteClient.SendAvatarProperties(avatarID, aboutText,
Util.ToDateTime(0).ToString(
"M/d/yyyy", CultureInfo.InvariantCulture),
charterMember, firstLifeAboutText,
(uint)(0 & 0xff),
firstLifeImage, image, profileUrl, partner);
//Viewer expects interest data when it asks for properties.
remoteClient.SendAvatarInterestsReply(avatarID, wantMask, wantText,
skillsMask, skillsText, languages);
}
}
}

View File

@@ -52,6 +52,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected bool m_Enabled = false;
protected Scene m_aScene;
protected List<Scene> m_Scenes = new List<Scene>();
protected List<UUID> m_agentsInTransit;
private ExpiringCache<UUID, ExpiringCache<ulong, DateTime>> m_bannedRegions =
new ExpiringCache<UUID, ExpiringCache<ulong, DateTime>>();
@@ -96,13 +97,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (m_aScene == null)
m_aScene = scene;
m_Scenes.Add(scene);
scene.RegisterModuleInterface<IEntityTransferModule>(this);
scene.EventManager.OnNewClient += OnNewClient;
}
protected virtual void OnNewClient(IClientAPI client)
{
client.OnTeleportHomeRequest += TeleportHomeFired;
client.OnTeleportHomeRequest += TriggerTeleportHome;
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
}
public virtual void Close()
@@ -118,6 +121,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return;
if (scene == m_aScene)
m_aScene = null;
m_Scenes.Remove(scene);
}
public virtual void RegionLoaded(Scene scene)
@@ -127,7 +132,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
#endregion
#region Agent Teleports
@@ -249,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
}
}
protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
public void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq)
{
if (reg == null || finalDestination == null)
{
@@ -557,9 +561,32 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
#endregion
#region Landmark Teleport
/// <summary>
/// Tries to teleport agent to landmark.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="regionHandle"></param>
/// <param name="position"></param>
public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
{
GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
if (info == null)
{
// can't find the region: Tell viewer and abort
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
return;
}
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
}
#endregion
#region Teleport Home
public void TeleportHomeFired(UUID id, IClientAPI client)
public virtual void TriggerTeleportHome(UUID id, IClientAPI client)
{
TeleportHome(id, client);
}

View File

@@ -86,7 +86,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
protected override void OnNewClient(IClientAPI client)
{
client.OnTeleportHomeRequest += TeleportHomeFired;
client.OnTeleportHomeRequest += TriggerTeleportHome;
client.OnTeleportLandmarkRequest += RequestTeleportLandmark;
client.OnConnectionClosed += new Action<IClientAPI>(OnConnectionClosed);
}
@@ -178,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason);
}
public void TeleportHomeFired(UUID id, IClientAPI client)
public void TriggerTeleportHome(UUID id, IClientAPI client)
{
TeleportHome(id, client);
}
@@ -233,6 +234,58 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq);
return true;
}
/// <summary>
/// Tries to teleport agent to landmark.
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="regionHandle"></param>
/// <param name="position"></param>
public override void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm)
{
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}",
(lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position);
if (lm.Gatekeeper == string.Empty)
{
base.RequestTeleportLandmark(remoteClient, lm);
return;
}
GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID);
// Local region?
if (info != null)
{
((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position,
Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark));
return;
}
else
{
// Foreign region
Scene scene = (Scene)(remoteClient.Scene);
GatekeeperServiceConnector gConn = new GatekeeperServiceConnector();
GridRegion gatekeeper = new GridRegion();
gatekeeper.ServerURI = lm.Gatekeeper;
GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID));
if (finalDestination != null)
{
ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId);
IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>();
IEventQueue eq = sp.Scene.RequestModuleInterface<IEventQueue>();
if (transferMod != null && sp != null && eq != null)
transferMod.DoTeleport(sp, gatekeeper, finalDestination, lm.Position,
Vector3.UnitX, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark), eq);
}
}
// can't find the region: Tell viewer and abort
remoteClient.SendTeleportFailed("The teleport destination could not be found.");
}
#endregion
#region IUserAgentVerificationModule

View File

@@ -56,6 +56,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
private string m_ProfileServerURI;
private bool m_OutboundPermission;
private string m_ThisGatekeeper;
// private bool m_Initialized = false;
@@ -85,6 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
{
m_ProfileServerURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty);
m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty);
}
else
m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
@@ -110,7 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
{
string userAssetServer = string.Empty;
if (IsForeignUser(avatarID, out userAssetServer) && m_OutboundPermission)
if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
{
Util.FireAndForget(delegate { m_assMapper.Post(assetID, avatarID, userAssetServer); });
}
@@ -119,6 +121,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
#endregion
#region Overrides of Basic Inventory Access methods
protected override string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
{
UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, presence.UUID);
if (account == null)
prefix = "HG ";
else
prefix = string.Empty;
suffix = " @ " + m_ThisGatekeeper;
Vector3 pos = presence.AbsolutePosition;
return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n",
presence.Scene.RegionInfo.RegionID,
pos.X, pos.Y, pos.Z,
presence.RegionHandle,
m_ThisGatekeeper);
}
///
/// CapsUpdateInventoryItemAsset
///
@@ -180,10 +200,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
{
string userAssetServer = string.Empty;
if (IsForeignUser(sender, out userAssetServer))
if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty)
m_assMapper.Get(item.AssetID, sender, userAssetServer);
if (IsForeignUser(receiver, out userAssetServer) && m_OutboundPermission)
if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
m_assMapper.Post(item.AssetID, receiver, userAssetServer);
}
@@ -203,9 +223,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
{
assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true;
assetServerURL = assetServerURL.Trim(new char[] { '/' });
}
}
else
{
assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI");
assetServerURL = assetServerURL.Trim(new char[] { '/' });
}
return true;
}
return false;

View File

@@ -30,6 +30,7 @@ using System.Collections.Generic;
using System.Net;
using System.Xml;
using System.Reflection;
using System.Text;
using System.Threading;
using OpenSim.Framework;
@@ -128,7 +129,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
protected virtual void OnNewClient(IClientAPI client)
{
client.OnCreateNewInventoryItem += CreateNewInventoryItem;
}
public virtual void Close()
@@ -156,6 +157,87 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
#region Inventory Access
/// <summary>
/// Create a new inventory item. Called when the client creates a new item directly within their
/// inventory (e.g. by selecting a context inventory menu option).
/// </summary>
/// <param name="remoteClient"></param>
/// <param name="transactionID"></param>
/// <param name="folderID"></param>
/// <param name="callbackID"></param>
/// <param name="description"></param>
/// <param name="name"></param>
/// <param name="invType"></param>
/// <param name="type"></param>
/// <param name="wearableType"></param>
/// <param name="nextOwnerMask"></param>
public void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID,
uint callbackID, string description, string name, sbyte invType,
sbyte assetType,
byte wearableType, uint nextOwnerMask, int creationDate)
{
m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID);
if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
return;
InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId);
InventoryFolderBase folder = m_Scene.InventoryService.GetFolder(f);
if (folder == null || folder.Owner != remoteClient.AgentId)
return;
if (transactionID == UUID.Zero)
{
ScenePresence presence;
if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence))
{
byte[] data = null;
if (invType == (sbyte)InventoryType.Landmark && presence != null)
{
string suffix = string.Empty, prefix = string.Empty;
string strdata = GenerateLandmark(presence, out prefix, out suffix);
data = Encoding.ASCII.GetBytes(strdata);
name = prefix + name;
description += suffix;
}
AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId);
m_Scene.AssetService.Store(asset);
m_Scene.CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
}
else
{
m_log.ErrorFormat(
"ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
remoteClient.AgentId);
}
}
else
{
IAgentAssetTransactions agentTransactions = m_Scene.RequestModuleInterface<IAgentAssetTransactions>();
if (agentTransactions != null)
{
agentTransactions.HandleItemCreationFromTransaction(
remoteClient, transactionID, folderID, callbackID, description,
name, invType, assetType, wearableType, nextOwnerMask);
}
}
}
protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
{
prefix = string.Empty;
suffix = string.Empty;
Vector3 pos = presence.AbsolutePosition;
return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\n",
presence.Scene.RegionInfo.RegionID,
pos.X, pos.Y, pos.Z,
presence.RegionHandle);
}
/// <summary>
/// Capability originating call to update the asset of an item in an agent's inventory
/// </summary>

View File

@@ -30,11 +30,13 @@ using System.IO;
using System.Reflection;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using OpenMetaverse;
using log4net;
@@ -47,7 +49,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public UUID Id;
public string FirstName;
public string LastName;
public string ProfileURL;
public string HomeURL;
public Dictionary<string, object> ServerURLs;
}
public class UserManagementModule : ISharedRegionModule, IUserManagement
@@ -78,6 +81,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
// }
// }
//}
MainConsole.Instance.Commands.AddCommand("grid", true,
"show user-names",
"show user-names",
"Show the bindings between user UUIDs and user names",
String.Empty,
HandleShowUsers);
}
public bool IsSharedModule
@@ -101,6 +112,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
scene.RegisterModuleInterface<IUserManagement>(this);
scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(EventManager_OnNewClient);
scene.EventManager.OnPrimsLoaded += new EventManager.PrimsLoaded(EventManager_OnPrimsLoaded);
}
public void RemoveRegion(Scene scene)
@@ -109,18 +121,12 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
m_Scenes.Remove(scene);
}
public void RegionLoaded(Scene scene)
public void RegionLoaded(Scene s)
{
}
public void PostInitialise()
{
foreach (Scene s in m_Scenes)
{
// let's sniff all the user names referenced by objects in the scene
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
}
}
public void Close()
@@ -134,6 +140,14 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
#region Event Handlers
void EventManager_OnPrimsLoaded(Scene s)
{
// let's sniff all the user names referenced by objects in the scene
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Caching creators' data from {0} ({1} objects)...", s.RegionInfo.RegionName, s.GetEntities().Length);
s.ForEachSOG(delegate(SceneObjectGroup sog) { CacheCreators(sog); });
}
void EventManager_OnNewClient(IClientAPI client)
{
client.OnNameFromUUIDRequest += new UUIDNameRequest(HandleUUIDNameRequest);
@@ -150,6 +164,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
string[] names = GetUserNames(uuid);
if (names.Length == 2)
{
//m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]);
remote_client.SendNameReply(uuid, names[0], names[1]);
}
@@ -210,6 +225,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public string GetUserName(UUID uuid)
{
//m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
string[] names = GetUserNames(uuid);
if (names.Length == 2)
{
@@ -222,6 +238,60 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return "(hippos)";
}
public string GetUserHomeURL(UUID userID)
{
if (m_UserCache.ContainsKey(userID))
return m_UserCache[userID].HomeURL;
return string.Empty;
}
public string GetUserServerURL(UUID userID, string serverType)
{
if (m_UserCache.ContainsKey(userID))
{
UserData userdata = m_UserCache[userID];
if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
return userdata.ServerURLs[serverType].ToString();
if (userdata.HomeURL != string.Empty)
{
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
userdata.ServerURLs = uConn.GetServerURLs(userID);
if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null)
return userdata.ServerURLs[serverType].ToString();
}
}
return string.Empty;
}
public string GetUserUUI(UUID userID)
{
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID);
if (account != null)
return userID.ToString();
if (m_UserCache.ContainsKey(userID))
{
UserData ud = m_UserCache[userID];
string homeURL = ud.HomeURL;
string first = ud.FirstName, last = ud.LastName;
if (ud.LastName.StartsWith("@"))
{
string[] parts = ud.FirstName.Split('.');
if (parts.Length >= 2)
{
first = parts[0];
last = parts[1];
}
return userID + ";" + homeURL + ";" + first + " " + last;
}
}
return userID.ToString();
}
public void AddUser(UUID id, string creatorData)
{
if (m_UserCache.ContainsKey(id))
@@ -247,13 +317,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
string[] parts = creatorData.Split(';');
if (parts.Length >= 1)
{
user.ProfileURL = parts[0];
user.HomeURL = parts[0];
try
{
Uri uri = new Uri(parts[0]);
user.LastName = "@" + uri.Authority;
}
catch
catch (UriFormatException)
{
m_log.DebugFormat("[SCENE]: Unable to parse Uri {0}", parts[0]);
user.LastName = "@unknown";
@@ -272,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
lock (m_UserCache)
m_UserCache[id] = user;
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.ProfileURL);
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", user.Id, user.FirstName, user.LastName, user.HomeURL);
}
public void AddUser(UUID uuid, string first, string last, string profileURL)
@@ -311,5 +381,25 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
//}
#endregion IUserManagement
private void HandleShowUsers(string module, string[] cmd)
{
if (m_UserCache.Count == 0)
{
MainConsole.Instance.Output("No users not found");
return;
}
MainConsole.Instance.Output("UUID User Name");
MainConsole.Instance.Output("-----------------------------------------------------------------------------");
foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
{
MainConsole.Instance.Output(String.Format("{0} {1} {2}",
kvp.Key, kvp.Value.FirstName, kvp.Value.LastName));
}
return;
}
}
}

View File

@@ -25,6 +25,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using log4net;
@@ -67,9 +68,26 @@ namespace OpenSim.Region.CoreModules.Hypergrid
foreach (GridRegion r in regions)
{
MapBlockData block = new MapBlockData();
MapBlockFromGridRegion(block, r);
mapBlocks.Add(block);
uint x = 0, y = 0;
long handle = 0;
if (r.RegionSecret != null && r.RegionSecret != string.Empty)
{
if (long.TryParse(r.RegionSecret, out handle))
{
Utils.LongToUInts((ulong)handle, out x, out y);
x = x / Constants.RegionSize;
y = y / Constants.RegionSize;
}
}
if (handle == 0 ||
// Check the distance from the current region
(handle != 0 && Math.Abs((int)(x - m_scene.RegionInfo.RegionLocX)) < 4096 && Math.Abs((int)(y - m_scene.RegionInfo.RegionLocY)) < 4096))
{
MapBlockData block = new MapBlockData();
MapBlockFromGridRegion(block, r);
mapBlocks.Add(block);
}
}
// Different from super
@@ -77,6 +95,7 @@ namespace OpenSim.Region.CoreModules.Hypergrid
//
remoteClient.SendMapBlock(mapBlocks, 0);
}

View File

@@ -24,6 +24,7 @@
<RegionModule id="UrlModule" type="OpenSim.Region.CoreModules.Scripting.LSLHttp.UrlModule" />
<RegionModule id="Chat" type="OpenSim.Region.CoreModules.Avatar.Chat.ChatModule" />
<RegionModule id="FriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.FriendsModule" />
<RegionModule id="HGFriendsModule" type="OpenSim.Region.CoreModules.Avatar.Friends.HGFriendsModule" />
<RegionModule id="PresenceModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.PresenceModule" />
<RegionModule id="MuteListModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.MuteListModule" />
<RegionModule id="OfflineMessageModule" type="OpenSim.Region.CoreModules.Avatar.InstantMessage.OfflineMessageModule" />

View File

@@ -113,8 +113,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
new UserAgentServerConnector(m_Config, MainServer.Instance);
IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
}
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
}

View File

@@ -58,6 +58,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
private List<Scene> m_Scenes = new List<Scene>();
protected IUserManagement m_UserManagement;
protected IUserManagement UserManagementModule
{
get
{
if (m_UserManagement == null)
m_UserManagement = m_Scenes[0].RequestModuleInterface<IUserManagement>();
return m_UserManagement;
}
}
public Type ReplaceableInterface
{
get { return null; }
@@ -207,6 +218,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
}
}
}
if (sp == null)
{
inventoryURL = UserManagementModule.GetUserServerURL(userID, "InventoryServerURI");
if (inventoryURL != null && inventoryURL != string.Empty)
{
inventoryURL = inventoryURL.Trim(new char[] { '/' });
m_InventoryURLs.Add(userID, inventoryURL);
m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
}
}
}
}

View File

@@ -230,6 +230,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// <param name="asset"></param>
public void AssetRequestCallback(string id, object sender, AssetBase asset)
{
Culture.SetCurrentCulture();
try
{
lock (this)
@@ -289,6 +291,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
/// </summary>
protected void PerformAssetsRequestCallback(object o)
{
Culture.SetCurrentCulture();
try
{
m_assetsRequestCallback(m_foundAssetUuids, m_notFoundAssetUuids);

View File

@@ -548,18 +548,18 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// libomv will moan about PrimFlags.ObjectYouOfficer being
// deprecated
#pragma warning disable 0612
#pragma warning disable 0612
objflags &= (uint)
~(PrimFlags.ObjectCopy | // Tells client you can copy the object
PrimFlags.ObjectModify | // tells client you can modify the object
PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
PrimFlags.ObjectModify | // tells client you can modify the object
PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod)
PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it
PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object
PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object
PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object
PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set
);
#pragma warning restore 0612
#pragma warning restore 0612
// Creating the three ObjectFlags options for this method to choose from.
// Customize the OwnerMask
@@ -576,22 +576,27 @@ namespace OpenSim.Region.CoreModules.World.Permissions
if (m_bypassPermissions)
return objectOwnerMask;
// Object owners should be able to edit their own content
if (user == objectOwner)
return objectOwnerMask;
if (IsFriendWithPerms(user, objectOwner))
return objectOwnerMask;
if (IsFriendWithPerms(user, objectOwner))
{
return objectOwnerMask;
}
// Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
{
return objectOwnerMask;
}
// Admin should be able to edit anything in the sim (including admin objects)
if (IsAdministrator(user))
{
return objectOwnerMask;
}
// Users should be able to edit what is over their land.
Vector3 taskPos = task.AbsolutePosition;
ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y);
@@ -599,13 +604,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions
{
// Admin objects should not be editable by the above
if (!IsAdministrator(objectOwner))
{
return objectOwnerMask;
}
}
// Group permissions
if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
return objectGroupMask | objectEveryoneMask;
return objectEveryoneMask;
}
@@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
//
// Nobody but the object owner can set permissions on an object
//
if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
{
return false;
@@ -704,6 +710,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// Return immediately, so that the administrator can shares group objects
return true;
}
// Friends with benefits should be able to edit the objects too
if (IsFriendWithPerms(currentUser, objectOwner))
// Return immediately, so that the administrator can share objects with friends
return true;
// Users should be able to edit what is over their land.
ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);

View File

@@ -208,52 +208,65 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
//m_log.DebugFormat("[MAPLAYER]: path: {0}, param: {1}, agent:{2}",
// path, param, agentID.ToString());
// this is here because CAPS map requests work even beyond the 10,000 limit.
ScenePresence avatarPresence = null;
// There is a major hack going on in this method. The viewer doesn't request
// map blocks (RequestMapBlocks) above 4096. That means that if we don't hack,
// grids above that cell don't have a map at all. So, here's the hack: we wait
// for this CAP request to come, and we inject the map blocks at this point.
// In a normal scenario, this request simply sends back the MapLayer (the blue color).
// In the hacked scenario, it also sends the map blocks via UDP.
//
// 6/8/2011 -- I'm adding an explicit 4096 check, so that we never forget that there is
// a hack here, and so that regions below 4096 don't get spammed with unnecessary map blocks.
m_scene.TryGetScenePresence(agentID, out avatarPresence);
if (avatarPresence != null)
if (m_scene.RegionInfo.RegionLocX >= 4096 || m_scene.RegionInfo.RegionLocY >= 4096)
{
bool lookup = false;
ScenePresence avatarPresence = null;
lock (cachedMapBlocks)
m_scene.TryGetScenePresence(agentID, out avatarPresence);
if (avatarPresence != null)
{
if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
{
List<MapBlockData> mapBlocks;
mapBlocks = cachedMapBlocks;
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
}
else
{
lookup = true;
}
}
if (lookup)
{
List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
(int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
foreach (GridRegion r in regions)
{
MapBlockData block = new MapBlockData();
MapBlockFromGridRegion(block, r);
mapBlocks.Add(block);
}
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
bool lookup = false;
lock (cachedMapBlocks)
cachedMapBlocks = mapBlocks;
{
if (cachedMapBlocks.Count > 0 && ((cachedTime + 1800) > Util.UnixTimeSinceEpoch()))
{
List<MapBlockData> mapBlocks;
cachedTime = Util.UnixTimeSinceEpoch();
mapBlocks = cachedMapBlocks;
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
}
else
{
lookup = true;
}
}
if (lookup)
{
List<MapBlockData> mapBlocks = new List<MapBlockData>(); ;
List<GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID,
(int)(m_scene.RegionInfo.RegionLocX - 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocX + 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocY - 8) * (int)Constants.RegionSize,
(int)(m_scene.RegionInfo.RegionLocY + 8) * (int)Constants.RegionSize);
foreach (GridRegion r in regions)
{
MapBlockData block = new MapBlockData();
MapBlockFromGridRegion(block, r);
mapBlocks.Add(block);
}
avatarPresence.ControllingClient.SendMapBlock(mapBlocks, 0);
lock (cachedMapBlocks)
cachedMapBlocks = mapBlocks;
cachedTime = Util.UnixTimeSinceEpoch();
}
}
}
LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
return mapResponse.ToString();