aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs50
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs73
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs10
-rw-r--r--OpenSim/Region/Framework/Interfaces/IFriendsModule.cs24
5 files changed, 102 insertions, 64 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 86e04b9..9d7012e 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -51,6 +51,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
51{ 51{
52 public class FriendsModule : ISharedRegionModule, IFriendsModule 52 public class FriendsModule : ISharedRegionModule, IFriendsModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
54 protected bool m_Enabled = false; 56 protected bool m_Enabled = false;
55 57
56 protected class UserFriendData 58 protected class UserFriendData
@@ -72,7 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
72 } 74 }
73 75
74 protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; 76 protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
75 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
76 77
77 protected List<Scene> m_Scenes = new List<Scene>(); 78 protected List<Scene> m_Scenes = new List<Scene>();
78 79
@@ -156,7 +157,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
156 InitModule(config); 157 InitModule(config);
157 158
158 m_Enabled = true; 159 m_Enabled = true;
159 m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name); 160 m_log.DebugFormat("[FRIENDS MODULE]: {0} enabled.", Name);
160 } 161 }
161 } 162 }
162 } 163 }
@@ -201,7 +202,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
201 if (!m_Enabled) 202 if (!m_Enabled)
202 return; 203 return;
203 204
204 m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name); 205// m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
205 206
206 m_Scenes.Add(scene); 207 m_Scenes.Add(scene);
207 scene.RegisterModuleInterface<IFriendsModule>(this); 208 scene.RegisterModuleInterface<IFriendsModule>(this);
@@ -241,13 +242,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
241 242
242 #endregion 243 #endregion
243 244
244 public virtual uint GetFriendPerms(UUID principalID, UUID friendID) 245 public virtual int GetRightsGrantedByFriend(UUID principalID, UUID friendID)
245 { 246 {
246 FriendInfo[] friends = GetFriends(principalID); 247 FriendInfo[] friends = GetFriends(principalID);
247 FriendInfo finfo = GetFriend(friends, friendID); 248 FriendInfo finfo = GetFriend(friends, friendID);
248 if (finfo != null) 249 if (finfo != null)
249 { 250 {
250 return (uint)finfo.TheirFlags; 251 return finfo.TheirFlags;
251 } 252 }
252 253
253 return 0; 254 return 0;
@@ -259,7 +260,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
259 client.OnApproveFriendRequest += OnApproveFriendRequest; 260 client.OnApproveFriendRequest += OnApproveFriendRequest;
260 client.OnDenyFriendRequest += OnDenyFriendRequest; 261 client.OnDenyFriendRequest += OnDenyFriendRequest;
261 client.OnTerminateFriendship += RemoveFriendship; 262 client.OnTerminateFriendship += RemoveFriendship;
262 client.OnGrantUserRights += OnGrantUserRights; 263 client.OnGrantUserRights += GrantRights;
263 264
264 // We need to cache information for child agents as well as root agents so that friend edit/move/delete 265 // We need to cache information for child agents as well as root agents so that friend edit/move/delete
265 // permissions will work across borders where both regions are on different simulators. 266 // permissions will work across borders where both regions are on different simulators.
@@ -356,10 +357,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
356 // Send the friends online 357 // Send the friends online
357 List<UUID> online = GetOnlineFriends(agentID); 358 List<UUID> online = GetOnlineFriends(agentID);
358 359
359// m_log.DebugFormat(
360// "[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
361// client.Name, client.Scene.RegionInfo.RegionName, online.Count);
362
363 if (online.Count > 0) 360 if (online.Count > 0)
364 client.SendAgentOnline(online.ToArray()); 361 client.SendAgentOnline(online.ToArray());
365 362
@@ -421,23 +418,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
421 List<UUID> GetOnlineFriends(UUID userID) 418 List<UUID> GetOnlineFriends(UUID userID)
422 { 419 {
423 List<string> friendList = new List<string>(); 420 List<string> friendList = new List<string>();
424 List<UUID> online = new List<UUID>();
425 421
426 FriendInfo[] friends = GetFriends(userID); 422 FriendInfo[] friends = GetFriends(userID);
427 foreach (FriendInfo fi in friends) 423 foreach (FriendInfo fi in friends)
428 { 424 {
429 if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) 425 if (((fi.TheirFlags & (int)FriendRights.CanSeeOnline) != 0) && (fi.TheirFlags != -1))
430 friendList.Add(fi.Friend); 426 friendList.Add(fi.Friend);
431 } 427 }
432 428
429 List<UUID> online = new List<UUID>();
430
433 if (friendList.Count > 0) 431 if (friendList.Count > 0)
434 GetOnlineFriends(userID, friendList, online); 432 GetOnlineFriends(userID, friendList, online);
435 433
434// m_log.DebugFormat(
435// "[FRIENDS MODULE]: User {0} has {1} friends online", userID, online.Count);
436
436 return online; 437 return online;
437 } 438 }
438 439
439 protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online) 440 protected virtual void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
440 { 441 {
442// m_log.DebugFormat(
443// "[FRIENDS MODULE]: Looking for online presence of {0} users for {1}", friendList.Count, userID);
444
441 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); 445 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
442 foreach (PresenceInfo pi in presence) 446 foreach (PresenceInfo pi in presence)
443 { 447 {
@@ -717,13 +721,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
717 } 721 }
718 } 722 }
719 723
720 private void OnGrantUserRights(IClientAPI remoteClient, UUID target, int rights) 724 public void GrantRights(IClientAPI remoteClient, UUID friendID, int rights)
721 { 725 {
722 UUID requester = remoteClient.AgentId; 726 UUID requester = remoteClient.AgentId;
723 727
724 m_log.DebugFormat( 728 m_log.DebugFormat(
725 "[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", 729 "[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}",
726 requester, rights, target); 730 requester, rights, friendID);
727 731
728 FriendInfo[] friends = GetFriends(requester); 732 FriendInfo[] friends = GetFriends(requester);
729 if (friends.Length == 0) 733 if (friends.Length == 0)
@@ -732,12 +736,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
732 } 736 }
733 737
734 // Let's find the friend in this user's friend list 738 // Let's find the friend in this user's friend list
735 FriendInfo friend = GetFriend(friends, target); 739 FriendInfo friend = GetFriend(friends, friendID);
736 740
737 if (friend != null) // Found it 741 if (friend != null) // Found it
738 { 742 {
739 // Store it on the DB 743 // Store it on the DB
740 if (!StoreRights(requester, target, rights)) 744 if (!StoreRights(requester, friendID, rights))
741 { 745 {
742 remoteClient.SendAlertMessage("Unable to grant rights."); 746 remoteClient.SendAlertMessage("Unable to grant rights.");
743 return; 747 return;
@@ -748,17 +752,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
748 friend.MyFlags = rights; 752 friend.MyFlags = rights;
749 753
750 // Always send this back to the original client 754 // Always send this back to the original client
751 remoteClient.SendChangeUserRights(requester, target, rights); 755 remoteClient.SendChangeUserRights(requester, friendID, rights);
752 756
753 // 757 //
754 // Notify the friend 758 // Notify the friend
755 // 759 //
756 760
757 // Try local 761 // Try local
758 if (LocalGrantRights(requester, target, myFlags, rights)) 762 if (LocalGrantRights(requester, friendID, myFlags, rights))
759 return; 763 return;
760 764
761 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); 765 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
762 if (friendSessions != null && friendSessions.Length > 0) 766 if (friendSessions != null && friendSessions.Length > 0)
763 { 767 {
764 PresenceInfo friendSession = friendSessions[0]; 768 PresenceInfo friendSession = friendSessions[0];
@@ -767,13 +771,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
767 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 771 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
768 // TODO: You might want to send the delta to save the lookup 772 // TODO: You might want to send the delta to save the lookup
769 // on the other end!! 773 // on the other end!!
770 m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights); 774 m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights);
771 } 775 }
772 } 776 }
773 } 777 }
774 else 778 else
775 { 779 {
776 m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester); 780 m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", friendID, requester);
777 } 781 }
778 } 782 }
779 783
@@ -990,8 +994,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
990 994
991 protected virtual void StoreFriendships(UUID agentID, UUID friendID) 995 protected virtual void StoreFriendships(UUID agentID, UUID friendID)
992 { 996 {
993 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1); 997 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), (int)FriendRights.CanSeeOnline);
994 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1); 998 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), (int)FriendRights.CanSeeOnline);
995 } 999 }
996 1000
997 protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID) 1001 protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
index 94a78cb..45b4264 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/Tests/FriendModuleTests.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using Nini.Config; 30using Nini.Config;
31using NUnit.Framework; 31using NUnit.Framework;
32using OpenMetaverse; 32using OpenMetaverse;
33using OpenSim.Data.Null;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Region.CoreModules.Avatar.Friends; 35using OpenSim.Region.CoreModules.Avatar.Friends;
35using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
@@ -63,6 +64,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
63 [SetUp] 64 [SetUp]
64 public void Init() 65 public void Init()
65 { 66 {
67 // We must clear friends data between tests since Data.Null holds it in static properties. This is necessary
68 // so that different services and simulator can share the data in standalone mode. This is pretty horrible
69 // effectively the statics are global variables.
70 NullFriendsData.Clear();
71
66 IConfigSource config = new IniConfigSource(); 72 IConfigSource config = new IniConfigSource();
67 config.AddConfig("Modules"); 73 config.AddConfig("Modules");
68 // Not strictly necessary since FriendsModule assumes it is the default (!) 74 // Not strictly necessary since FriendsModule assumes it is the default (!)
@@ -110,8 +116,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
110 116
111 m_fm.AddFriendship(sp1.ControllingClient, user2Id); 117 m_fm.AddFriendship(sp1.ControllingClient, user2Id);
112 118
113 m_scene.RemoveClient(sp1.UUID, true); 119 // Not necessary for this test. CanSeeOnline is automatically granted.
114 m_scene.RemoveClient(sp2.UUID, true); 120// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
121
122 // We must logout from the client end so that the presence service is correctly updated by the presence
123 // detector. This is listening to the OnConnectionClosed event on the client.
124 ((TestClient)sp1.ControllingClient).Logout();
125 ((TestClient)sp2.ControllingClient).Logout();
126// m_scene.RemoveClient(sp1.UUID, true);
127// m_scene.RemoveClient(sp2.UUID, true);
115 128
116 ScenePresence sp1Redux = SceneHelpers.AddScenePresence(m_scene, user1Id); 129 ScenePresence sp1Redux = SceneHelpers.AddScenePresence(m_scene, user1Id);
117 130
@@ -120,33 +133,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends.Tests
120 Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0)); 133 Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(0));
121 } 134 }
122 135
123// [Test] 136 [Test]
124// public void TestLoginWithOnlineFriends() 137 public void TestLoginWithOnlineFriends()
125// { 138 {
126// TestHelpers.InMethod(); 139 TestHelpers.InMethod();
127// log4net.Config.XmlConfigurator.Configure(); 140// log4net.Config.XmlConfigurator.Configure();
141
142 UUID user1Id = TestHelpers.ParseTail(0x1);
143 UUID user2Id = TestHelpers.ParseTail(0x2);
144
145// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id);
146// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id);
128// 147//
129// UUID user1Id = TestHelpers.ParseTail(0x1); 148// m_fm.AddFriendship(user1Id, user2Id);
130// UUID user2Id = TestHelpers.ParseTail(0x2); 149
131// 150 ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id);
132//// UserAccountHelpers.CreateUserWithInventory(m_scene, user1Id); 151 ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, user2Id);
133//// UserAccountHelpers.CreateUserWithInventory(m_scene, user2Id); 152
134//// 153 m_fm.AddFriendship(sp1.ControllingClient, user2Id);
135//// m_fm.AddFriendship(user1Id, user2Id); 154
136// 155 // Not necessary for this test. CanSeeOnline is automatically granted.
137// ScenePresence sp1 = SceneHelpers.AddScenePresence(m_scene, user1Id); 156// m_fm.GrantRights(sp1.ControllingClient, user2Id, (int)FriendRights.CanSeeOnline);
138// SceneHelpers.AddScenePresence(m_scene, user2Id); 157
139// 158 // We must logout from the client end so that the presence service is correctly updated by the presence
140// m_fm.AddFriendship(sp1.ControllingClient, user2Id); 159 // detector. This is listening to the OnConnectionClosed event on the client.
141//// m_fm.LocalGrantRights 160// ((TestClient)sp1.ControllingClient).Logout();
142// 161 ((TestClient)sp2.ControllingClient).Logout();
143// m_scene.RemoveClient(sp1.UUID, true); 162// m_scene.RemoveClient(user2Id, true);
144// 163
145// ScenePresence sp1Redux = SceneHelpers.AddScenePresence(m_scene, user1Id); 164 ScenePresence sp2Redux = SceneHelpers.AddScenePresence(m_scene, user2Id);
146// 165
147// Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0)); 166 Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOfflineNotifications.Count, Is.EqualTo(0));
148// Assert.That(((TestClient)sp1Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1)); 167 Assert.That(((TestClient)sp2Redux.ControllingClient).ReceivedOnlineNotifications.Count, Is.EqualTo(1));
149// } 168 }
150 169
151 [Test] 170 [Test]
152 public void TestAddFriendshipWhileOnline() 171 public void TestAddFriendshipWhileOnline()
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
index e2e383f..ccfbf78 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs
@@ -27,14 +27,12 @@
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30 30using log4net;
31using OpenMetaverse;
31using OpenSim.Framework; 32using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes; 33using OpenSim.Region.Framework.Scenes;
33using OpenSim.Services.Interfaces; 34using OpenSim.Services.Interfaces;
34 35
35using OpenMetaverse;
36using log4net;
37
38namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence 36namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
39{ 37{
40 public class PresenceDetector 38 public class PresenceDetector
@@ -97,7 +95,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
97// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); 95// m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName);
98 m_PresenceService.LogoutAgent(client.SessionId); 96 m_PresenceService.LogoutAgent(client.SessionId);
99 } 97 }
100
101 } 98 }
102 } 99 }
103} 100} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
index ac03747..64759a7 100644
--- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs
@@ -487,7 +487,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
487 return false; 487 return false;
488 } 488 }
489 489
490 protected bool IsFriendWithPerms(UUID user,UUID objectOwner) 490 protected bool IsFriendWithPerms(UUID user, UUID objectOwner)
491 { 491 {
492 if (user == UUID.Zero) 492 if (user == UUID.Zero)
493 return false; 493 return false;
@@ -495,11 +495,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
495 if (m_friendsModule == null) 495 if (m_friendsModule == null)
496 return false; 496 return false;
497 497
498 uint friendPerms = m_friendsModule.GetFriendPerms(user, objectOwner); 498 int friendPerms = m_friendsModule.GetRightsGrantedByFriend(user, objectOwner);
499 if ((friendPerms & (uint)FriendRights.CanModifyObjects) != 0) 499 return (friendPerms & (int)FriendRights.CanModifyObjects) != 0;
500 return true;
501
502 return false;
503 } 500 }
504 501
505 protected bool IsEstateManager(UUID user) 502 protected bool IsEstateManager(UUID user)
@@ -508,6 +505,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions
508 505
509 return m_scene.RegionInfo.EstateSettings.IsEstateManager(user); 506 return m_scene.RegionInfo.EstateSettings.IsEstateManager(user);
510 } 507 }
508
511#endregion 509#endregion
512 510
513 public bool PropagatePermissions() 511 public bool PropagatePermissions()
diff --git a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
index 061799e..10bef1e 100644
--- a/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IFriendsModule.cs
@@ -55,7 +55,27 @@ namespace OpenSim.Region.Framework.Interfaces
55 /// <param name="exFriendID"></param> 55 /// <param name="exFriendID"></param>
56 void RemoveFriendship(IClientAPI client, UUID exFriendID); 56 void RemoveFriendship(IClientAPI client, UUID exFriendID);
57 57
58 uint GetFriendPerms(UUID PrincipalID, UUID FriendID); 58 /// <summary>
59 /// Get permissions granted by a friend.
60 /// </summary>
61 /// <param name="PrincipalID">The user.</param>
62 /// <param name="FriendID">The friend that granted.</param>
63 /// <returns>The permissions. These come from the FriendRights enum.</returns>
64 int GetRightsGrantedByFriend(UUID PrincipalID, UUID FriendID);
65
66 /// <summary>
67 /// Grant permissions for a friend.
68 /// </summary>
69 /// <remarks>
70 /// This includes giving them the ability to see when the user is online and permission to edit the user's
71 /// objects.
72 /// Granting lower permissions than the friend currently has will rescind the extra permissions.
73 /// </remarks>
74 /// <param name="remoteClient">The user granting the permissions.</param>
75 /// <param name="friendID">The friend.</param>
76 /// <param name="perms">These come from the FriendRights enum.</param>
77 void GrantRights(IClientAPI remoteClient, UUID friendID, int perms);
78
59 bool SendFriendsOnlineIfNeeded(IClientAPI client); 79 bool SendFriendsOnlineIfNeeded(IClientAPI client);
60 } 80 }
61} 81} \ No newline at end of file