Finally restire the EMPTY friends module (what a mess)
parent
872387d278
commit
20318dba05
|
@ -58,530 +58,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "FriendsModule"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsSharedModule
|
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IInterregionFriendsComms
|
|
||||||
|
|
||||||
public List<UUID> InformFriendsInOtherRegion(UUID agentId, ulong destRegionHandle, List<UUID> friends, bool online)
|
|
||||||
{
|
|
||||||
List<UUID> tpdAway = new List<UUID>();
|
|
||||||
|
|
||||||
// destRegionHandle is a region on another server
|
|
||||||
uint x = 0, y = 0;
|
|
||||||
Utils.LongToUInts(destRegionHandle, out x, out y);
|
|
||||||
GridRegion info = m_gridServices.GetRegionByPosition(m_initialScene.RegionInfo.ScopeID, (int)x, (int)y);
|
|
||||||
if (info != null)
|
|
||||||
{
|
|
||||||
string httpServer = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/presence_update_bulk";
|
|
||||||
|
|
||||||
Hashtable reqParams = new Hashtable();
|
|
||||||
reqParams["agentID"] = agentId.ToString();
|
|
||||||
reqParams["agentOnline"] = online;
|
|
||||||
int count = 0;
|
|
||||||
foreach (UUID uuid in friends)
|
|
||||||
{
|
|
||||||
reqParams["friendID_" + count++] = uuid.ToString();
|
|
||||||
}
|
|
||||||
reqParams["friendCount"] = count;
|
|
||||||
|
|
||||||
IList parameters = new ArrayList();
|
|
||||||
parameters.Add(reqParams);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
XmlRpcRequest request = new XmlRpcRequest("presence_update_bulk", parameters);
|
|
||||||
XmlRpcResponse response = request.Send(httpServer, 5000);
|
|
||||||
Hashtable respData = (Hashtable)response.Value;
|
|
||||||
|
|
||||||
count = (int)respData["friendCount"];
|
|
||||||
for (int i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
UUID uuid;
|
|
||||||
if (UUID.TryParse((string)respData["friendID_" + i], out uuid)) tpdAway.Add(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (WebException e)
|
|
||||||
{
|
|
||||||
// Ignore connect failures, simulators come and go
|
|
||||||
//
|
|
||||||
if (!e.Message.Contains("ConnectFailure"))
|
|
||||||
{
|
|
||||||
m_log.Error("[OGS1 GRID SERVICES]: InformFriendsInOtherRegion XMLRPC failure: ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error("[OGS1 GRID SERVICES]: InformFriendsInOtherRegion XMLRPC failure: ", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else m_log.WarnFormat("[OGS1 GRID SERVICES]: Couldn't find region {0}???", destRegionHandle);
|
|
||||||
|
|
||||||
return tpdAway;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TriggerTerminateFriend(ulong destRegionHandle, UUID agentID, UUID exFriendID)
|
|
||||||
{
|
|
||||||
// destRegionHandle is a region on another server
|
|
||||||
uint x = 0, y = 0;
|
|
||||||
Utils.LongToUInts(destRegionHandle, out x, out y);
|
|
||||||
GridRegion info = m_gridServices.GetRegionByPosition(m_initialScene.RegionInfo.ScopeID, (int)x, (int)y);
|
|
||||||
if (info == null)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[OGS1 GRID SERVICES]: Couldn't find region {0}", destRegionHandle);
|
|
||||||
return false; // region not found???
|
|
||||||
}
|
|
||||||
|
|
||||||
string httpServer = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/presence_update_bulk";
|
|
||||||
|
|
||||||
Hashtable reqParams = new Hashtable();
|
|
||||||
reqParams["agentID"] = agentID.ToString();
|
|
||||||
reqParams["friendID"] = exFriendID.ToString();
|
|
||||||
|
|
||||||
IList parameters = new ArrayList();
|
|
||||||
parameters.Add(reqParams);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
XmlRpcRequest request = new XmlRpcRequest("terminate_friend", parameters);
|
|
||||||
XmlRpcResponse response = request.Send(httpServer, 5000);
|
|
||||||
Hashtable respData = (Hashtable)response.Value;
|
|
||||||
|
|
||||||
return (bool)respData["success"];
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error("[OGS1 GRID SERVICES]: InformFriendsInOtherRegion XMLRPC failure: ", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Incoming XMLRPC messages
|
|
||||||
/// <summary>
|
|
||||||
/// Receive presence information changes about clients in other regions.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="req"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public XmlRpcResponse processPresenceUpdateBulk(XmlRpcRequest req, IPEndPoint remoteClient)
|
|
||||||
{
|
|
||||||
Hashtable requestData = (Hashtable)req.Params[0];
|
|
||||||
|
|
||||||
List<UUID> friendsNotHere = new List<UUID>();
|
|
||||||
|
|
||||||
// this is called with the expectation that all the friends in the request are on this region-server.
|
|
||||||
// But as some time passed since we checked (on the other region-server, via the MessagingServer),
|
|
||||||
// some of the friends might have teleported away.
|
|
||||||
// Actually, even now, between this line and the sending below, some people could TP away. So,
|
|
||||||
// we'll have to lock the m_rootAgents list for the duration to prevent/delay that.
|
|
||||||
lock (m_rootAgents)
|
|
||||||
{
|
|
||||||
List<ScenePresence> friendsHere = new List<ScenePresence>();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
UUID agentID = new UUID((string)requestData["agentID"]);
|
|
||||||
bool agentOnline = (bool)requestData["agentOnline"];
|
|
||||||
int count = (int)requestData["friendCount"];
|
|
||||||
for (int i = 0; i < count; ++i)
|
|
||||||
{
|
|
||||||
UUID uuid;
|
|
||||||
if (UUID.TryParse((string)requestData["friendID_" + i], out uuid))
|
|
||||||
{
|
|
||||||
if (m_rootAgents.ContainsKey(uuid)) friendsHere.Add(GetRootPresenceFromAgentID(uuid));
|
|
||||||
else friendsNotHere.Add(uuid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now send, as long as they are still here...
|
|
||||||
UUID[] agentUUID = new UUID[] { agentID };
|
|
||||||
if (agentOnline)
|
|
||||||
{
|
|
||||||
foreach (ScenePresence agent in friendsHere)
|
|
||||||
{
|
|
||||||
agent.ControllingClient.SendAgentOnline(agentUUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (ScenePresence agent in friendsHere)
|
|
||||||
{
|
|
||||||
agent.ControllingClient.SendAgentOffline(agentUUID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[FRIENDS]: Got exception while parsing presence_update_bulk request:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no need to lock anymore; if TPs happen now, worst case is that we have an additional agent in this region,
|
|
||||||
// which should be caught on the next iteration...
|
|
||||||
Hashtable result = new Hashtable();
|
|
||||||
int idx = 0;
|
|
||||||
foreach (UUID uuid in friendsNotHere)
|
|
||||||
{
|
|
||||||
result["friendID_" + idx++] = uuid.ToString();
|
|
||||||
}
|
|
||||||
result["friendCount"] = idx;
|
|
||||||
|
|
||||||
XmlRpcResponse response = new XmlRpcResponse();
|
|
||||||
response.Value = result;
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
public XmlRpcResponse processTerminateFriend(XmlRpcRequest req, IPEndPoint remoteClient)
|
|
||||||
{
|
|
||||||
Hashtable requestData = (Hashtable)req.Params[0];
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
UUID agentID;
|
|
||||||
UUID friendID;
|
|
||||||
if (requestData.ContainsKey("agentID") && UUID.TryParse((string)requestData["agentID"], out agentID) &&
|
|
||||||
requestData.ContainsKey("friendID") && UUID.TryParse((string)requestData["friendID"], out friendID))
|
|
||||||
{
|
|
||||||
// try to find it and if it is there, prevent it to vanish before we sent the message
|
|
||||||
lock (m_rootAgents)
|
|
||||||
{
|
|
||||||
if (m_rootAgents.ContainsKey(agentID))
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[FRIEND]: Sending terminate friend {0} to agent {1}", friendID, agentID);
|
|
||||||
GetRootPresenceFromAgentID(agentID).ControllingClient.SendTerminateFriend(friendID);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return whether we were successful
|
|
||||||
Hashtable result = new Hashtable();
|
|
||||||
result["success"] = success;
|
|
||||||
|
|
||||||
XmlRpcResponse response = new XmlRpcResponse();
|
|
||||||
response.Value = result;
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Scene events
|
|
||||||
|
|
||||||
private void OnNewClient(IClientAPI client)
|
|
||||||
{
|
|
||||||
// All friends establishment protocol goes over instant message
|
|
||||||
// There's no way to send a message from the sim
|
|
||||||
// to a user to 'add a friend' without causing dialog box spam
|
|
||||||
|
|
||||||
// Subscribe to instant messages
|
|
||||||
client.OnInstantMessage += OnInstantMessage;
|
|
||||||
|
|
||||||
// Friend list management
|
|
||||||
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
|
||||||
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
|
||||||
client.OnTerminateFriendship += OnTerminateFriendship;
|
|
||||||
|
|
||||||
// ... calling card handling...
|
|
||||||
client.OnOfferCallingCard += OnOfferCallingCard;
|
|
||||||
client.OnAcceptCallingCard += OnAcceptCallingCard;
|
|
||||||
client.OnDeclineCallingCard += OnDeclineCallingCard;
|
|
||||||
|
|
||||||
// we need this one exactly once per agent session (see comments in the handler below)
|
|
||||||
client.OnEconomyDataRequest += OnEconomyDataRequest;
|
|
||||||
|
|
||||||
// if it leaves, we want to know, too
|
|
||||||
client.OnLogout += OnLogout;
|
|
||||||
|
|
||||||
client.OnGrantUserRights += GrantUserFriendRights;
|
|
||||||
client.OnTrackAgentEvent += FindAgent;
|
|
||||||
client.OnFindAgentEvent += FindAgent;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClientClosed(UUID AgentId, Scene scene)
|
|
||||||
{
|
|
||||||
// agent's client was closed. As we handle logout in OnLogout, this here has only to handle
|
|
||||||
// TPing away (root agent is closed) or TPing/crossing in a region far enough away (client
|
|
||||||
// agent is closed).
|
|
||||||
// NOTE: In general, this doesn't mean that the agent logged out, just that it isn't around
|
|
||||||
// in one of the regions here anymore.
|
|
||||||
lock (m_rootAgents)
|
|
||||||
{
|
|
||||||
if (m_rootAgents.ContainsKey(AgentId))
|
|
||||||
{
|
|
||||||
m_rootAgents.Remove(AgentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, UUID regionID)
|
|
||||||
{
|
|
||||||
lock (m_rootAgents)
|
|
||||||
{
|
|
||||||
m_rootAgents[avatar.UUID] = avatar.RegionHandle;
|
|
||||||
// Claim User! my user! Mine mine mine!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void MakeChildAgent(ScenePresence avatar)
|
|
||||||
{
|
|
||||||
lock (m_rootAgents)
|
|
||||||
{
|
|
||||||
if (m_rootAgents.ContainsKey(avatar.UUID))
|
|
||||||
{
|
|
||||||
// only delete if the region matches. As this is a shared module, the avatar could be
|
|
||||||
// root agent in another region on this server.
|
|
||||||
if (m_rootAgents[avatar.UUID] == avatar.RegionHandle)
|
|
||||||
{
|
|
||||||
m_rootAgents.Remove(avatar.UUID);
|
|
||||||
// m_log.Debug("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private ScenePresence GetRootPresenceFromAgentID(UUID AgentID)
|
|
||||||
{
|
|
||||||
ScenePresence returnAgent = null;
|
|
||||||
lock (m_scenes)
|
|
||||||
{
|
|
||||||
ScenePresence queryagent = null;
|
|
||||||
foreach (Scene scene in m_scenes.Values)
|
|
||||||
{
|
|
||||||
queryagent = scene.GetScenePresence(AgentID);
|
|
||||||
if (queryagent != null)
|
|
||||||
{
|
|
||||||
if (!queryagent.IsChildAgent)
|
|
||||||
{
|
|
||||||
returnAgent = queryagent;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnAgent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ScenePresence GetAnyPresenceFromAgentID(UUID AgentID)
|
|
||||||
{
|
|
||||||
ScenePresence returnAgent = null;
|
|
||||||
lock (m_scenes)
|
|
||||||
{
|
|
||||||
ScenePresence queryagent = null;
|
|
||||||
foreach (Scene scene in m_scenes.Values)
|
|
||||||
{
|
|
||||||
queryagent = scene.GetScenePresence(AgentID);
|
|
||||||
if (queryagent != null)
|
|
||||||
{
|
|
||||||
returnAgent = queryagent;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnAgent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OfferFriendship(UUID fromUserId, IClientAPI toUserClient, string offerMessage)
|
|
||||||
{
|
|
||||||
CachedUserInfo userInfo = m_initialScene.CommsManager.UserProfileCacheService.GetUserDetails(fromUserId);
|
|
||||||
|
|
||||||
if (userInfo != null)
|
|
||||||
{
|
|
||||||
GridInstantMessage msg = new GridInstantMessage(
|
|
||||||
toUserClient.Scene, fromUserId, userInfo.UserProfile.Name, toUserClient.AgentId,
|
|
||||||
(byte)InstantMessageDialog.FriendshipOffered, offerMessage, false, Vector3.Zero);
|
|
||||||
|
|
||||||
FriendshipOffered(msg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[FRIENDS]: No user found for id {0} in OfferFriendship()", fromUserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#region FriendRequestHandling
|
|
||||||
|
|
||||||
private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
|
|
||||||
{
|
|
||||||
// Friend Requests go by Instant Message.. using the dialog param
|
|
||||||
// https://wiki.secondlife.com/wiki/ImprovedInstantMessage
|
|
||||||
|
|
||||||
if (im.dialog == (byte)InstantMessageDialog.FriendshipOffered) // 38
|
|
||||||
{
|
|
||||||
// fromAgentName is the *destination* name (the friend we offer friendship to)
|
|
||||||
ScenePresence initiator = GetAnyPresenceFromAgentID(new UUID(im.fromAgentID));
|
|
||||||
im.fromAgentName = initiator != null ? initiator.Name : "(hippo)";
|
|
||||||
|
|
||||||
FriendshipOffered(im);
|
|
||||||
}
|
|
||||||
else if (im.dialog == (byte)InstantMessageDialog.FriendshipAccepted) // 39
|
|
||||||
{
|
|
||||||
FriendshipAccepted(client, im);
|
|
||||||
}
|
|
||||||
else if (im.dialog == (byte)InstantMessageDialog.FriendshipDeclined) // 40
|
|
||||||
{
|
|
||||||
FriendshipDeclined(client, im);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked when a user offers a friendship.
|
|
||||||
/// </summary>
|
|
||||||
///
|
|
||||||
/// <param name="im"></param>
|
|
||||||
/// <param name="client"></param>
|
|
||||||
private void FriendshipOffered(GridInstantMessage im)
|
|
||||||
{
|
|
||||||
// this is triggered by the initiating agent:
|
|
||||||
// A local agent offers friendship to some possibly remote friend.
|
|
||||||
// A IM is triggered, processed here and sent to the friend (possibly in a remote region).
|
|
||||||
|
|
||||||
m_log.DebugFormat("[FRIEND]: Offer(38) - From: {0}, FromName: {1} To: {2}, Session: {3}, Message: {4}, Offline {5}",
|
|
||||||
im.fromAgentID, im.fromAgentName, im.toAgentID, im.imSessionID, im.message, im.offline);
|
|
||||||
|
|
||||||
// 1.20 protocol sends an UUID in the message field, instead of the friendship offer text.
|
|
||||||
// For interoperability, we have to clear that
|
|
||||||
if (Util.isUUID(im.message)) im.message = "";
|
|
||||||
|
|
||||||
// be sneeky and use the initiator-UUID as transactionID. This means we can be stateless.
|
|
||||||
// we have to look up the agent name on friendship-approval, though.
|
|
||||||
im.imSessionID = im.fromAgentID;
|
|
||||||
|
|
||||||
if (m_TransferModule != null)
|
|
||||||
{
|
|
||||||
// Send it to whoever is the destination.
|
|
||||||
// If new friend is local, it will send an IM to the viewer.
|
|
||||||
// If new friend is remote, it will cause a OnGridInstantMessage on the remote server
|
|
||||||
m_TransferModule.SendInstantMessage(
|
|
||||||
im,
|
|
||||||
delegate(bool success)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[FRIEND]: sending IM success = {0}", success);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked when a user accepts a friendship offer.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="im"></param>
|
|
||||||
/// <param name="client"></param>
|
|
||||||
private void FriendshipAccepted(IClientAPI client, GridInstantMessage im)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[FRIEND]: 39 - from client {0}, agent {2} {3}, imsession {4} to {5}: {6} (dialog {7})",
|
|
||||||
client.AgentId, im.fromAgentID, im.fromAgentName, im.imSessionID, im.toAgentID, im.message, im.dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Invoked when a user declines a friendship offer.
|
|
||||||
/// </summary>
|
|
||||||
/// May not currently be used - see OnDenyFriendRequest() instead
|
|
||||||
/// <param name="im"></param>
|
|
||||||
/// <param name="client"></param>
|
|
||||||
private void FriendshipDeclined(IClientAPI client, GridInstantMessage im)
|
|
||||||
{
|
|
||||||
UUID fromAgentID = new UUID(im.fromAgentID);
|
|
||||||
UUID toAgentID = new UUID(im.toAgentID);
|
|
||||||
|
|
||||||
// declining the friendship offer causes a type 40 IM being sent to the (possibly remote) initiator
|
|
||||||
// toAgentID is initiator, fromAgentID declined friendship
|
|
||||||
m_log.DebugFormat("[FRIEND]: 40 - from client {0}, agent {1} {2}, imsession {3} to {4}: {5} (dialog {6})",
|
|
||||||
client != null ? client.AgentId.ToString() : "<null>",
|
|
||||||
fromAgentID, im.fromAgentName, im.imSessionID, im.toAgentID, im.message, im.dialog);
|
|
||||||
|
|
||||||
// Send the decline to whoever is the destination.
|
|
||||||
GridInstantMessage msg
|
|
||||||
= new GridInstantMessage(
|
|
||||||
client.Scene, fromAgentID, client.Name, toAgentID,
|
|
||||||
im.dialog, im.message, im.offline != 0, im.Position);
|
|
||||||
|
|
||||||
// If new friend is local, it will send an IM to the viewer.
|
|
||||||
// If new friend is remote, it will cause a OnGridInstantMessage on the remote server
|
|
||||||
m_TransferModule.SendInstantMessage(msg,
|
|
||||||
delegate(bool success) {
|
|
||||||
m_log.DebugFormat("[FRIEND]: sending IM success = {0}", success);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnGridInstantMessage(GridInstantMessage msg)
|
|
||||||
{
|
|
||||||
// This event won't be raised unless we have that agent,
|
|
||||||
// so we can depend on the above not trying to send
|
|
||||||
// via grid again
|
|
||||||
//m_log.DebugFormat("[FRIEND]: Got GridIM from {0}, to {1}, imSession {2}, message {3}, dialog {4}",
|
|
||||||
// msg.fromAgentID, msg.toAgentID, msg.imSessionID, msg.message, msg.dialog);
|
|
||||||
|
|
||||||
if (msg.dialog == (byte)InstantMessageDialog.FriendshipOffered ||
|
|
||||||
msg.dialog == (byte)InstantMessageDialog.FriendshipAccepted ||
|
|
||||||
msg.dialog == (byte)InstantMessageDialog.FriendshipDeclined)
|
|
||||||
{
|
|
||||||
// this should succeed as we *know* the root agent is here.
|
|
||||||
m_TransferModule.SendInstantMessage(msg,
|
|
||||||
delegate(bool success) {
|
|
||||||
//m_log.DebugFormat("[FRIEND]: sending IM success = {0}", success);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.dialog == (byte)InstantMessageDialog.FriendshipAccepted)
|
|
||||||
{
|
|
||||||
// for accept friendship, we have to do a bit more
|
|
||||||
ApproveFriendship(new UUID(msg.fromAgentID), new UUID(msg.toAgentID), msg.fromAgentName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApproveFriendship(UUID fromAgentID, UUID toAgentID, string fromName)
|
|
||||||
{
|
|
||||||
m_log.DebugFormat("[FRIEND]: Approve friendship from {0} (ID: {1}) to {2}",
|
|
||||||
fromAgentID, fromName, toAgentID);
|
|
||||||
|
|
||||||
// a new friend was added in the initiator's and friend's data, so the cache entries are wrong now.
|
|
||||||
lock (m_friendLists)
|
|
||||||
{
|
|
||||||
m_friendLists.Invalidate(fromAgentID.ToString());
|
|
||||||
m_friendLists.Invalidate(toAgentID.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// now send presence update and add a calling card for the new friend
|
|
||||||
|
|
||||||
ScenePresence initiator = GetAnyPresenceFromAgentID(toAgentID);
|
|
||||||
if (initiator == null)
|
|
||||||
{
|
|
||||||
// quite wrong. Shouldn't happen.
|
|
||||||
m_log.WarnFormat("[FRIEND]: Coudn't find initiator of friend request {0}", toAgentID);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_log.DebugFormat("[FRIEND]: Tell {0} that {1} is online",
|
|
||||||
initiator.Name, fromName);
|
|
||||||
// tell initiator that friend is online
|
|
||||||
initiator.ControllingClient.SendAgentOnline(new UUID[] { fromAgentID });
|
|
||||||
|
|
||||||
// find the folder for the friend...
|
|
||||||
//InventoryFolderImpl folder =
|
|
||||||
// initiator.Scene.CommsManager.UserProfileCacheService.GetUserDetails(toAgentID).FindFolderForType((int)InventoryType.CallingCard);
|
|
||||||
IInventoryService invService = initiator.Scene.InventoryService;
|
|
||||||
InventoryFolderBase folder = invService.GetFolderForType(toAgentID, AssetType.CallingCard);
|
|
||||||
if (folder != null)
|
|
||||||
{
|
|
||||||
// ... and add the calling card
|
|
||||||
CreateCallingCard(initiator.ControllingClient, fromAgentID, folder.ID, fromName);
|
|
||||||
}
|
|
||||||
>>>>>>> master:OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
public void AddRegion(Scene scene)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -594,10 +70,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get { return "FriendsModule"; }
|
get { return "FriendsModule"; }
|
||||||
|
@ -608,30 +80,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
get { return null; }
|
get { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OfferFriendship(UUID fromUserId, IClientAPI toUserClient,
|
public void OfferFriendship(UUID fromUserId, IClientAPI toUserClient, string offerMessage)
|
||||||
string offerMessage)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public void FindAgent(IClientAPI remoteClient, UUID hunter, UUID target)
|
|
||||||
{
|
|
||||||
List<FriendListItem> friendList = GetUserFriends(hunter);
|
|
||||||
foreach (FriendListItem item in friendList)
|
|
||||||
{
|
|
||||||
if(item.onlinestatus == true)
|
|
||||||
{
|
|
||||||
if(item.Friend == target && (item.FriendPerms & (uint)FriendRights.CanSeeOnMap) != 0)
|
|
||||||
{
|
|
||||||
ScenePresence SPTarget = ((Scene)remoteClient.Scene).GetScenePresence(target);
|
|
||||||
string regionname = SPTarget.Scene.RegionInfo.RegionName;
|
|
||||||
remoteClient.SendScriptTeleportRequest("FindAgent", regionname,new Vector3(SPTarget.AbsolutePosition),new Vector3(SPTarget.Lookat));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
remoteClient.SendAgentAlertMessage("The agent you are looking for is not online.", false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<FriendListItem> GetUserFriends(UUID agentID)
|
public List<FriendListItem> GetUserFriends(UUID agentID)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue