* You can add and remove a friend in standalone now within the same simulator. It saves.

* You can add and remove a friend in grid mode now within the same simulator.  It doesn't save yet.
* I got rid of Mr. OpenSim as a friend..   he bothers me /:b...
afrisby
Teravus Ovares 2008-01-01 06:12:04 +00:00
parent b8975ecbd9
commit b4c9b6bd19
17 changed files with 590 additions and 51 deletions

View File

@ -152,6 +152,49 @@ namespace OpenSim.Framework.Communications
} }
} }
#region Friend Methods
/// <summary>
/// Adds a new friend to the database for XUser
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being added to</param>
/// <param name="friend">The agent that being added to the friends list of the friends list owner</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
m_userService.AddNewUserFriend(friendlistowner, friend, perms);
}
/// <summary>
/// Delete friend on friendlistowner's friendlist.
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The Ex-friend agent</param>
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
m_userService.RemoveUserFriend(friendlistowner, friend);
}
/// <summary>
/// Update permissions for friend on friendlistowner's friendlist.
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The agent that is getting or loosing permissions</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
m_userService.UpdateUserFriendPerms(friendlistowner, friend, perms);
}
/// <summary>
/// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner
/// </summary>
/// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
{
return m_userService.GetUserFriendList(friendlistowner);
}
#endregion
#region Packet Handlers #region Packet Handlers
public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client) public void HandleUUIDNameRequest(LLUUID uuid, IClientAPI remote_client)

View File

@ -226,6 +226,13 @@ namespace OpenSim.Framework.Data.MySQL
param); param);
updater.ExecuteNonQuery(); updater.ExecuteNonQuery();
updater =
database.Query(
"delete from userfriends " +
"where ownerID = ?friendID and friendID = ?ownerID",
param);
updater.ExecuteNonQuery();
} }
} }
catch (Exception e) catch (Exception e)

View File

@ -47,16 +47,20 @@ namespace OpenSim.Framework.Data.SQLite
/// </summary> /// </summary>
private const string userSelect = "select * from users"; private const string userSelect = "select * from users";
private const string userFriendsSelect = "select a.ownerID as ownerID,a.friendID as friendID,a.friendPerms as friendPerms,b.friendPerms as ownerperms, b.ownerID as fownerID, b.friendID as ffriendID from userfriends as a, userfriends as b"; private const string userFriendsSelect = "select a.ownerID as ownerID,a.friendID as friendID,a.friendPerms as friendPerms,b.friendPerms as ownerperms, b.ownerID as fownerID, b.friendID as ffriendID from userfriends as a, userfriends as b";
private DataSet ds; private DataSet ds;
private SqliteDataAdapter da; private SqliteDataAdapter da;
private SqliteDataAdapter daf; private SqliteDataAdapter daf;
SqliteConnection g_conn;
public void Initialise() public void Initialise()
{ {
SqliteConnection conn = new SqliteConnection("URI=file:userprofiles.db,version=3"); SqliteConnection conn = new SqliteConnection("URI=file:userprofiles.db,version=3");
TestTables(conn); TestTables(conn);
// This sucks, but It doesn't seem to work with the dataset Syncing :P
g_conn = conn;
ds = new DataSet(); ds = new DataSet();
da = new SqliteDataAdapter(new SqliteCommand(userSelect, conn)); da = new SqliteDataAdapter(new SqliteCommand(userSelect, conn));
daf = new SqliteDataAdapter(new SqliteCommand(userFriendsSelect, conn)); daf = new SqliteDataAdapter(new SqliteCommand(userFriendsSelect, conn));
@ -147,11 +151,11 @@ namespace OpenSim.Framework.Data.SQLite
DataRow row = friends.NewRow(); DataRow row = friends.NewRow();
fillFriendRow(row, friendlistowner,friend,perms); fillFriendRow(row, friendlistowner.UUID.ToString(),friend.UUID.ToString(),perms);
friends.Rows.Add(row); friends.Rows.Add(row);
row = friends.NewRow(); row = friends.NewRow();
fillFriendRow(row, friend, friendlistowner, perms); fillFriendRow(row, friend.UUID.ToString(), friendlistowner.UUID.ToString(), perms);
friends.Rows.Add(row); friends.Rows.Add(row);
MainLog.Instance.Verbose("SQLITE", MainLog.Instance.Verbose("SQLITE",
@ -164,7 +168,7 @@ namespace OpenSim.Framework.Data.SQLite
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend) public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{ {
DataTable ua = ds.Tables["userfriends"]; DataTable ua = ds.Tables["userfriends"];
string select = "a.ownernID '" + friendlistowner.UUID.ToString() + "' and b.friendID ='" + friend.UUID.ToString() + "';"; string select = "`ownerID` ='" + friendlistowner.UUID.ToString() + "' and `friendID` ='" + friend.UUID.ToString() + "'";
lock (ds) lock (ds)
{ {
DataRow[] rows = ds.Tables["userfriends"].Select(select); DataRow[] rows = ds.Tables["userfriends"].Select(select);
@ -175,20 +179,44 @@ namespace OpenSim.Framework.Data.SQLite
{ {
for (int i = 0; i < rows.Length; i++) for (int i = 0; i < rows.Length; i++)
{ {
FriendListItem user = new FriendListItem();
DataRow row = rows[i]; DataRow row = rows[i];
row.Delete(); row.Delete();
} }
daf.Update(ds, "userfriends");
} }
} }
} }
select = "`ownerID` ='" + friend.UUID.ToString() + "' and `friendID` ='" + friendlistowner.UUID.ToString() + "'";
lock (ds)
{
DataRow[] rows = ds.Tables["userfriends"].Select(select);
if (rows != null)
{
if (rows.Length > 0)
{
for (int i = 0; i < rows.Length; i++)
{
DataRow row = rows[i];
row.Delete();
}
}
}
}
SqliteCommand deletecommand = new SqliteCommand("delete from userfriends where `ownerID`='" + friendlistowner.UUID.ToString() + "' and `friendID` ='" + friend.UUID.ToString() + "'", g_conn);
g_conn.Open();
deletecommand.ExecuteNonQuery();
deletecommand = new SqliteCommand("delete from userfriends where `ownerID`='" + friend.UUID.ToString() + "' and `friendID` ='" + friendlistowner.UUID.ToString() + "'", g_conn);
deletecommand.ExecuteNonQuery();
g_conn.Close();
MainLog.Instance.Verbose("FRIEND", "Stub RemoveUserFriend called"); MainLog.Instance.Verbose("FRIEND", "Stub RemoveUserFriend called");
} }
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms) public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{ {
DataTable ua = ds.Tables["userfriends"]; DataTable ua = ds.Tables["userfriends"];
string select = "a.ownernID '" + friendlistowner.UUID.ToString() + "' and b.friendID ='" + friend.UUID.ToString() + "';"; string select = "a.ownerID ='" + friendlistowner.UUID.ToString() + "' and b.friendID ='" + friend.UUID.ToString() + "'";
lock (ds) lock (ds)
{ {
DataRow[] rows = ds.Tables["userfriends"].Select(select); DataRow[] rows = ds.Tables["userfriends"].Select(select);
@ -737,7 +765,7 @@ namespace OpenSim.Framework.Data.SQLite
daf.UpdateCommand = createUpdateCommand("userfriends", "ownerID=:ownerID and friendID=:friendID", ds.Tables["userfriends"]); daf.UpdateCommand = createUpdateCommand("userfriends", "ownerID=:ownerID and friendID=:friendID", ds.Tables["userfriends"]);
daf.UpdateCommand.Connection = conn; daf.UpdateCommand.Connection = conn;
SqliteCommand delete = new SqliteCommand("delete from users where ownerID=:ownerID and friendID=:friendID"); SqliteCommand delete = new SqliteCommand("delete from userfriends where ownerID=:ownerID and friendID=:friendID");
delete.Parameters.Add(createSqliteParameter("ownerID", typeof(String))); delete.Parameters.Add(createSqliteParameter("ownerID", typeof(String)));
delete.Parameters.Add(createSqliteParameter("friendID", typeof(String))); delete.Parameters.Add(createSqliteParameter("friendID", typeof(String)));
delete.Connection = conn; delete.Connection = conn;

View File

@ -0,0 +1,64 @@
/*
* 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 OpenSim 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 OpenSim.Framework;
namespace OpenSim.Framework
{
[Serializable]
public class GridInstantMessage
{
public Guid fromAgentID;
public Guid fromAgentSession;
public Guid toAgentID;
public Guid imSessionID;
public uint timestamp;
public string fromAgentName;
public string message;
public byte dialog;
public bool fromGroup;
public byte offline;
public uint ParentEstateID;
public sLLVector3 Position;
public Guid RegionID;
public byte[] binaryBucket;
public GridInstantMessage()
{
}
}
}

View File

@ -395,6 +395,14 @@ namespace OpenSim.Framework
public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID); public delegate void ConfirmXfer(IClientAPI remoteClient, ulong xferID, uint packetID);
public delegate void FriendActionDelegate(IClientAPI remoteClient,LLUUID agentID,LLUUID transactionID,List<LLUUID> callingCardFolders);
public delegate void FriendshipTermination(IClientAPI remoteClient,LLUUID agentID, LLUUID ExID);
public delegate void ObjectPermissions( public delegate void ObjectPermissions(
IClientAPI remoteClinet, LLUUID AgentID, LLUUID SessionID, IClientAPI remoteClinet, LLUUID AgentID, LLUUID SessionID,
List<ObjectPermissionsPacket.ObjectDataBlock> permChanges); List<ObjectPermissionsPacket.ObjectDataBlock> permChanges);
@ -490,6 +498,11 @@ namespace OpenSim.Framework
event RegionInfoRequest OnRegionInfoRequest; event RegionInfoRequest OnRegionInfoRequest;
event EstateCovenantRequest OnEstateCovenantRequest; event EstateCovenantRequest OnEstateCovenantRequest;
event FriendActionDelegate OnApproveFriendRequest;
event FriendActionDelegate OnDenyFriendRequest;
event FriendshipTermination OnTerminateFriendship;
LLVector3 StartPos { get; set; } LLVector3 StartPos { get; set; }
LLUUID AgentId { get; } LLUUID AgentId { get; }

View File

@ -47,5 +47,35 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="user"></param>
LLUUID AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY); LLUUID AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY);
/// <summary>
/// Adds a new friend to the database for XUser
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being added to</param>
/// <param name="friend">The agent that being added to the friends list of the friends list owner</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms);
/// <summary>
/// Delete friend on friendlistowner's friendlist.
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The Ex-friend agent</param>
void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend);
/// <summary>
/// Update permissions for friend on friendlistowner's friendlist.
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The agent that is getting or loosing permissions</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms);
/// <summary>
/// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner
/// </summary>
/// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
List<FriendListItem> GetUserFriendList(LLUUID friendlistowner);
} }
} }

View File

@ -45,8 +45,8 @@ namespace OpenSim.Framework
z = v.Z; z = v.Z;
} }
public float x; public float x=0;
public float y; public float y=0;
public float z; public float z=0;
} }
} }

View File

@ -551,6 +551,10 @@ namespace OpenSim.Region.ClientStack
public event RegionInfoRequest OnRegionInfoRequest; public event RegionInfoRequest OnRegionInfoRequest;
public event EstateCovenantRequest OnEstateCovenantRequest; public event EstateCovenantRequest OnEstateCovenantRequest;
public event FriendActionDelegate OnApproveFriendRequest;
public event FriendActionDelegate OnDenyFriendRequest;
public event FriendshipTermination OnTerminateFriendship;
#region Scene/Avatar to Client #region Scene/Avatar to Client
/// <summary> /// <summary>
@ -2555,6 +2559,39 @@ namespace OpenSim.Region.ClientStack
msgpack.MessageBlock.BinaryBucket); msgpack.MessageBlock.BinaryBucket);
} }
break; break;
case PacketType.AcceptFriendship:
AcceptFriendshipPacket afriendpack = (AcceptFriendshipPacket)Pack;
// My guess is this is the folder to stick the calling card into
List<LLUUID> callingCardFolders = new List<LLUUID>();
LLUUID agentID = afriendpack.AgentData.AgentID;
LLUUID transactionID = afriendpack.TransactionBlock.TransactionID;
for (int fi = 0; fi < afriendpack.FolderData.Length; fi++)
{
callingCardFolders.Add(afriendpack.FolderData[fi].FolderID);
}
if (OnApproveFriendRequest != null)
{
OnApproveFriendRequest(this, agentID, transactionID, callingCardFolders);
}
break;
case PacketType.TerminateFriendship:
TerminateFriendshipPacket tfriendpack = (TerminateFriendshipPacket)Pack;
LLUUID listOwnerAgentID = tfriendpack.AgentData.AgentID;
LLUUID exFriendID = tfriendpack.ExBlock.OtherID;
if (OnTerminateFriendship != null)
{
OnTerminateFriendship(this, listOwnerAgentID, exFriendID);
}
break;
case PacketType.RezObject: case PacketType.RezObject:
RezObjectPacket rezPacket = (RezObjectPacket) Pack; RezObjectPacket rezPacket = (RezObjectPacket) Pack;
if (OnRezObject != null) if (OnRezObject != null)

View File

@ -138,8 +138,8 @@ namespace OpenSim.Region.Communications.Local
theUser.currentAgent.currentHandle = reg.RegionHandle; theUser.currentAgent.currentHandle = reg.RegionHandle;
LoginResponse.BuddyList buddyList = new LoginResponse.BuddyList(); LoginResponse.BuddyList buddyList = new LoginResponse.BuddyList();
buddyList.AddNewBuddy(new LoginResponse.BuddyList.BuddyInfo("11111111-1111-0000-0000-000100bba000"));
response.BuddList = buddyList; response.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(theUser.UUID));
Login _login = new Login(); Login _login = new Login();
//copy data to login object //copy data to login object
@ -162,7 +162,20 @@ namespace OpenSim.Region.Communications.Local
MainLog.Instance.Warn("LOGIN", "Not found region " + currentRegion); MainLog.Instance.Warn("LOGIN", "Not found region " + currentRegion);
} }
} }
private LoginResponse.BuddyList ConvertFriendListItem(List<FriendListItem> LFL)
{
LoginResponse.BuddyList buddylistreturn = new LoginResponse.BuddyList();
foreach (FriendListItem fl in LFL)
{
LoginResponse.BuddyList.BuddyInfo buddyitem = new LoginResponse.BuddyList.BuddyInfo(fl.Friend);
buddyitem.BuddyID = fl.Friend;
buddyitem.BuddyRightsHave = (int)fl.FriendListOwnerPerms;
buddyitem.BuddyRightsGiven = (int)fl.FriendPerms;
buddylistreturn.AddNewBuddy(buddyitem);
}
return buddylistreturn;
}
protected override InventoryData CreateInventoryData(LLUUID userID) protected override InventoryData CreateInventoryData(LLUUID userID)
{ {
List<InventoryFolderBase> folders = m_Parent.InventoryService.RequestFirstLevelFolders(userID); List<InventoryFolderBase> folders = m_Parent.InventoryService.RequestFirstLevelFolders(userID);
@ -207,6 +220,7 @@ namespace OpenSim.Region.Communications.Local
return new InventoryData(AgentInventoryArray, userInventory.InventoryRoot.FolderID); return new InventoryData(AgentInventoryArray, userInventory.InventoryRoot.FolderID);
} }
} }
} }
} }

View File

@ -213,5 +213,48 @@ namespace OpenSim.Region.Communications.OGS1
{ {
throw new Exception("The method or operation is not implemented."); throw new Exception("The method or operation is not implemented.");
} }
#region IUserServices Friend Methods
/// <summary>
/// Adds a new friend to the database for XUser
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being added to</param>
/// <param name="friend">The agent that being added to the friends list of the friends list owner</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms)
{
}
/// <summary>
/// Delete friend on friendlistowner's friendlist.
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The Ex-friend agent</param>
public void RemoveUserFriend(LLUUID friendlistowner, LLUUID friend)
{
}
/// <summary>
/// Update permissions for friend on friendlistowner's friendlist.
/// </summary>
/// <param name="friendlistowner">The agent that who's friends list is being updated</param>
/// <param name="friend">The agent that is getting or loosing permissions</param>
/// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
public void UpdateUserFriendPerms(LLUUID friendlistowner, LLUUID friend, uint perms)
{
}
/// <summary>
/// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for LLUUID friendslistowner
/// </summary>
/// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param>
public List<FriendListItem> GetUserFriendList(LLUUID friendlistowner)
{
return new List<FriendListItem>();
}
#endregion
} }
} }

View File

@ -0,0 +1,28 @@
using System;
namespace OpenSim.Region.Environment
{
/// <summary>
/// Bit Vector for Which Modules to send an instant message to from the Scene or an Associated Module
/// </summary>
// This prevents the Modules from sending Instant messages to other modules through the scene
// and then receiving the same messages
// This is mostly here because on LLSL and the SecondLife Client, IMs,Groups and friends are linked
// inseparably
[Flags]
public enum InstantMessageReceiver : uint
{
/// <summary>None of them.. here for posterity and amusement</summary>
None = 0,
/// <summary>The IM Module</summary>
IMModule = 0x00000001,
/// <summary>The Friends Module</summary>
FriendsModule = 0x00000002,
/// <summary>The Groups Module</summary>
GroupsModule = 0x00000004
}
}

View File

@ -35,52 +35,179 @@ using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
using libsecondlife; using libsecondlife;
using libsecondlife.Packets;
namespace OpenSim.Region.Environment.Modules namespace OpenSim.Region.Environment.Modules
{ {
public class FriendsModule : IRegionModule public class FriendsModule : IRegionModule
{ {
private List<Scene> m_scenes = new List<Scene>();
private LogBase m_log; private LogBase m_log;
private Scene m_scene;
Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>();
public void Initialise(Scene scene, IConfigSource config) public void Initialise(Scene scene, IConfigSource config)
{ {
m_log = MainLog.Instance; m_log = MainLog.Instance;
if (!m_scenes.Contains(scene)) m_scene = scene;
{ scene.EventManager.OnNewClient += OnNewClient;
m_scenes.Add(scene); scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage;
scene.EventManager.OnNewClient += OnNewClient;
}
} }
private void OnNewClient(IClientAPI client) private void OnNewClient(IClientAPI client)
{ {
//FormFriendship(client,new Guid("c43a67ab-b196-4d62-936c-b40369547dee")); // All friends establishment protocol goes over instant message
//FormFriendship(client, new Guid("0a2f777b-f44c-4662-8b22-c90ae038a3e6")); // There's no way to send a message from the sim
// to a user to 'add a friend' without causing dialog box spam
//
// The base set of friends are added when the user signs on in their XMLRPC response
// Generated by LoginService. The friends are retreived from the database by the UserManager
// Subscribe to instant messages
client.OnInstantMessage += OnInstantMessage;
client.OnApproveFriendRequest += OnApprovedFriendRequest;
client.OnDenyFriendRequest += OnDenyFriendRequest;
client.OnTerminateFriendship += OnTerminateFriendship;
} }
private void OnInstantMessage(LLUUID fromAgentID,
LLUUID fromAgentSession, LLUUID toAgentID,
LLUUID imSessionID, uint timestamp, string fromAgentName,
string message, byte dialog, bool fromGroup, byte offline,
uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
byte[] binaryBucket)
{
// Friend Requests go by Instant Message.. using the dialog param
// https://wiki.secondlife.com/wiki/ImprovedInstantMessage
// 38 == Offer friendship
if (dialog == (byte)38)
{
LLUUID friendTransactionID = LLUUID.Random();
m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
m_log.Verbose("FRIEND", "38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message);
GridInstantMessage msg = new GridInstantMessage();
msg.fromAgentID = fromAgentID.UUID;
msg.fromAgentSession = fromAgentSession.UUID;
msg.toAgentID = toAgentID.UUID;
msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here
m_log.Verbose("FRIEND","Filling Session: " + msg.imSessionID.ToString());
msg.timestamp = timestamp;
msg.fromAgentName = fromAgentName;
msg.message = message;
msg.dialog = dialog;
msg.fromGroup = fromGroup;
msg.offline = offline;
msg.ParentEstateID = ParentEstateID;
msg.Position = new sLLVector3(Position);
msg.RegionID = RegionID.UUID;
msg.binaryBucket = binaryBucket;
m_scene.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
}
if (dialog == (byte)39)
{
m_log.Verbose("FRIEND", "38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message);
}
if (dialog == (byte)40)
{
m_log.Verbose("FRIEND", "38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message);
}
// 39 == Accept Friendship
// 40 == Decline Friendship
}
private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders)
{
if (m_pendingFriendRequests.ContainsKey(transactionID))
{
// Found Pending Friend Request with that Transaction..
// Compose response to other agent.
GridInstantMessage msg = new GridInstantMessage();
msg.toAgentID = m_pendingFriendRequests[transactionID].UUID;
msg.fromAgentID = agentID.UUID;
msg.fromAgentName = client.FirstName + " " + client.LastName;
msg.fromAgentSession = client.SessionId.UUID;
msg.fromGroup = false;
msg.imSessionID = transactionID.UUID;
msg.message = agentID.UUID.ToString();
msg.ParentEstateID = 0;
msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
msg.RegionID = m_scene.RegionInfo.RegionID.UUID;
msg.dialog = (byte)39;// Approved friend request
msg.Position = new sLLVector3();
msg.offline = (byte)0;
msg.binaryBucket = new byte[0];
m_scene.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
m_scene.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint)1);
m_pendingFriendRequests.Remove(transactionID);
// TODO: Inform agent that the friend is online
}
}
private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders)
{
if (m_pendingFriendRequests.ContainsKey(transactionID))
{
// Found Pending Friend Request with that Transaction..
// Compose response to other agent.
GridInstantMessage msg = new GridInstantMessage();
msg.toAgentID = m_pendingFriendRequests[transactionID].UUID;
msg.fromAgentID = agentID.UUID;
msg.fromAgentName = client.FirstName + " " + client.LastName;
msg.fromAgentSession = client.SessionId.UUID;
msg.fromGroup = false;
msg.imSessionID = transactionID.UUID;
msg.message = agentID.UUID.ToString();
msg.ParentEstateID = 0;
msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
msg.RegionID = m_scene.RegionInfo.RegionID.UUID;
msg.dialog = (byte)40;// Deny friend request
msg.Position = new sLLVector3();
msg.offline = (byte)0;
msg.binaryBucket = new byte[0];
m_scene.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
m_pendingFriendRequests.Remove(transactionID);
}
}
private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID)
{
m_scene.StoreRemoveFriendship(agent, exfriendID);
// TODO: Inform the client that the ExFriend is offline
}
private void OnGridInstantMessage(GridInstantMessage msg)
{
// Trigger the above event handler
OnInstantMessage(new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
msg.binaryBucket);
}
public void PostInitialise() public void PostInitialise()
{ {
} }
private void FormFriendship(IClientAPI client, Guid friend)
{
foreach (Scene scene in m_scenes)
{
if (scene.Entities.ContainsKey(client.AgentId) && scene.Entities[client.AgentId] is ScenePresence)
{
OnlineNotificationPacket ONPack = new OnlineNotificationPacket();
OnlineNotificationPacket.AgentBlockBlock[] AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[1];
AgentBlock[0] = new OnlineNotificationPacket.AgentBlockBlock();
AgentBlock[0].AgentID = new LLUUID(friend);
ONPack.AgentBlock = AgentBlock;
client.OutPacket(ONPack,ThrottleOutPacketType.Task);
}
}
}
public void Close() public void Close()
{ {
@ -93,7 +220,7 @@ namespace OpenSim.Region.Environment.Modules
public bool IsSharedModule public bool IsSharedModule
{ {
get { return true; } get { return false; }
} }
} }
} }

View File

@ -52,6 +52,7 @@ namespace OpenSim.Region.Environment.Modules
{ {
m_scenes.Add(scene); m_scenes.Add(scene);
scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage;
} }
} }
@ -67,19 +68,29 @@ namespace OpenSim.Region.Environment.Modules
uint ParentEstateID, LLVector3 Position, LLUUID RegionID, uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
byte[] binaryBucket) byte[] binaryBucket)
{ {
foreach (Scene scene in m_scenes)
bool FriendDialog = ((dialog == (byte)38) || (dialog == (byte)39) || (dialog == (byte)40));
// IM dialogs need to be pre-processed and have their sessionID filled by the server
// so the sim can match the transaction on the return packet.
// Don't send a Friend Dialog IM with a LLUUID.Zero session.
if (!(FriendDialog && imSessionID == LLUUID.Zero))
{ {
if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) foreach (Scene scene in m_scenes)
{ {
// Local message if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence)
ScenePresence user = (ScenePresence) scene.Entities[toAgentID];
if (!user.IsChildAgent)
{ {
user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, // Local message
toAgentID, imSessionID, fromAgentName, dialog, ScenePresence user = (ScenePresence)scene.Entities[toAgentID];
timestamp); if (!user.IsChildAgent)
// Message sent {
return; user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message,
toAgentID, imSessionID, fromAgentName, dialog,
timestamp);
// Message sent
return;
}
} }
} }
} }
@ -87,6 +98,20 @@ namespace OpenSim.Region.Environment.Modules
// Still here, try send via Grid // Still here, try send via Grid
// TODO // TODO
} }
// Trusty OSG1 called method. This method also gets called from the FriendsModule
// Turns out the sim has to send an instant message to the user to get it to show an accepted friend.
private void OnGridInstantMessage(GridInstantMessage msg)
{
// Trigger the above event handler
OnInstantMessage(new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
new LLVector3(msg.Position.x,msg.Position.y,msg.Position.z), new LLUUID(msg.RegionID),
msg.binaryBucket);
}
public void PostInitialise() public void PostInitialise()
{ {

View File

@ -1625,6 +1625,8 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
#endregion #endregion
#region Other Methods #region Other Methods
@ -1699,6 +1701,45 @@ namespace OpenSim.Region.Environment.Scenes
} }
} }
/// <summary>
/// This method is a way for the Friends Module to create an instant
/// message to the avatar and for Instant Messages that travel across
/// gridcomms to make it to the Instant Message Module.
///
/// Friendship establishment and groups are unfortunately tied with instant messaging and
/// there's no way to separate them completely.
/// </summary>
/// <param name="message">object containing the instant message data</param>
/// <returns>void</returns>
public void TriggerGridInstantMessage(GridInstantMessage message,InstantMessageReceiver options)
{
m_eventManager.TriggerGridInstantMessage(message,options);
}
public virtual void StoreAddFriendship(LLUUID ownerID, LLUUID friendID, uint perms)
{
// TODO: m_sceneGridService.DoStuff;
CommsManager.AddNewUserFriend(ownerID, friendID, perms);
}
public virtual void StoreUpdateFriendship(LLUUID ownerID, LLUUID friendID, uint perms)
{
// TODO: m_sceneGridService.DoStuff;
CommsManager.UpdateUserFriendPerms(ownerID, friendID, perms);
}
public virtual void StoreRemoveFriendship(LLUUID ownerID, LLUUID ExfriendID)
{
// TODO: m_sceneGridService.DoStuff;
CommsManager.RemoveUserFriend(ownerID, ExfriendID);
}
public virtual List<FriendListItem> StoreGetFriendsForUser(LLUUID ownerID)
{
// TODO: m_sceneGridService.DoStuff;
return CommsManager.GetUserFriendList(ownerID);
}
#endregion #endregion
#region Console Commands #region Console Commands

View File

@ -27,12 +27,14 @@
*/ */
using libsecondlife; using libsecondlife;
using System;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.LandManagement; using OpenSim.Region.Environment.LandManagement;
namespace OpenSim.Region.Environment.Scenes namespace OpenSim.Region.Environment.Scenes
{ {
/// <summary> /// <summary>
/// A class for triggering remote scene events. /// A class for triggering remote scene events.
/// </summary> /// </summary>
@ -115,6 +117,16 @@ namespace OpenSim.Region.Environment.Scenes
public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel;
public delegate void NewGridInstantMessage(GridInstantMessage message);
public event NewGridInstantMessage OnGridInstantMessageToIMModule;
public event NewGridInstantMessage OnGridInstantMessageToFriendsModule;
public event NewGridInstantMessage OnGridInstantMessageToGroupsModule;
public void TriggerOnClientMovement(ScenePresence avatar) public void TriggerOnClientMovement(ScenePresence avatar)
{ {
if (OnClientMovement != null) if (OnClientMovement != null)
@ -265,5 +277,29 @@ namespace OpenSim.Region.Environment.Scenes
OnAvatarEnteringNewParcel(avatar, localLandID, regionID); OnAvatarEnteringNewParcel(avatar, localLandID, regionID);
} }
} }
///<summary>Used to pass instnat messages around between the Scene, the Friends Module and the Instant Messsage Module</summary>
///<param name="message">Object containing the Instant Message Data</param>
///<param name="whichModule">A bit vector containing the modules to send the message to</param>
public void TriggerGridInstantMessage(GridInstantMessage message, InstantMessageReceiver whichModule)
{
if ((whichModule & InstantMessageReceiver.IMModule) != 0)
{
if (OnGridInstantMessageToIMModule != null)
{
OnGridInstantMessageToIMModule(message);
}
}
if ((whichModule & InstantMessageReceiver.FriendsModule) != 0)
{
if (OnGridInstantMessageToFriendsModule != null)
{
OnGridInstantMessageToFriendsModule(message);
}
}
}
} }
} }

View File

@ -139,6 +139,9 @@ namespace SimpleApp
public event RegionInfoRequest OnRegionInfoRequest; public event RegionInfoRequest OnRegionInfoRequest;
public event EstateCovenantRequest OnEstateCovenantRequest; public event EstateCovenantRequest OnEstateCovenantRequest;
public event FriendActionDelegate OnApproveFriendRequest;
public event FriendActionDelegate OnDenyFriendRequest;
public event FriendshipTermination OnTerminateFriendship;
#pragma warning restore 67 #pragma warning restore 67

View File

@ -7,7 +7,7 @@
the hardcoded root library folder ("OpenSim Library") the hardcoded root library folder ("OpenSim Library")
You can also add folders and items to the folders of libraries defined earlier on in this file --> You can also add folders and items to the folders of libraries defined earlier on in this file -->
<!-- <!--
<Section Name="My Site Library"> <Section Name="My Site Library">
<Key Name="foldersFile" Value="MySiteLibrary/MySiteLibraryFolders.xml"/> <Key Name="foldersFile" Value="MySiteLibrary/MySiteLibraryFolders.xml"/>