aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs1000
1 files changed, 500 insertions, 500 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
index db38d87..dd6a92e 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
@@ -1,501 +1,501 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the 12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27using System; 27using System;
28using System.Collections.Generic; 28using System.Collections.Generic;
29using System.Reflection; 29using System.Reflection;
30using libsecondlife; 30using libsecondlife;
31using libsecondlife.Packets; 31using libsecondlife.Packets;
32using log4net; 32using log4net;
33using Nini.Config; 33using Nini.Config;
34using Nwc.XmlRpc; 34using Nwc.XmlRpc;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Environment.Interfaces; 36using OpenSim.Region.Environment.Interfaces;
37using OpenSim.Region.Environment.Scenes; 37using OpenSim.Region.Environment.Scenes;
38 38
39namespace OpenSim.Region.Environment.Modules.Avatar.Friends 39namespace OpenSim.Region.Environment.Modules.Avatar.Friends
40{ 40{
41 public class FriendsModule : IRegionModule 41 public class FriendsModule : IRegionModule
42 { 42 {
43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
44 44
45 private Dictionary<LLUUID, List<FriendListItem>> FriendLists = new Dictionary<LLUUID, List<FriendListItem>>(); 45 private Dictionary<LLUUID, List<FriendListItem>> FriendLists = new Dictionary<LLUUID, List<FriendListItem>>();
46 private Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>(); 46 private Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>();
47 private Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>(); 47 private Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>();
48 private List<Scene> m_scene = new List<Scene>(); 48 private List<Scene> m_scene = new List<Scene>();
49 49
50 #region IRegionModule Members 50 #region IRegionModule Members
51 51
52 public void Initialise(Scene scene, IConfigSource config) 52 public void Initialise(Scene scene, IConfigSource config)
53 { 53 {
54 lock (m_scene) 54 lock (m_scene)
55 { 55 {
56 if (m_scene.Count == 0) 56 if (m_scene.Count == 0)
57 { 57 {
58 scene.AddXmlRPCHandler("presence_update", processPresenceUpdate); 58 scene.AddXmlRPCHandler("presence_update", processPresenceUpdate);
59 } 59 }
60 60
61 if (!m_scene.Contains(scene)) 61 if (!m_scene.Contains(scene))
62 m_scene.Add(scene); 62 m_scene.Add(scene);
63 } 63 }
64 scene.EventManager.OnNewClient += OnNewClient; 64 scene.EventManager.OnNewClient += OnNewClient;
65 scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage; 65 scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage;
66 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; 66 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
67 scene.EventManager.OnMakeChildAgent += MakeChildAgent; 67 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
68 scene.EventManager.OnClientClosed += ClientLoggedOut; 68 scene.EventManager.OnClientClosed += ClientLoggedOut;
69 } 69 }
70 70
71 public void PostInitialise() 71 public void PostInitialise()
72 { 72 {
73 } 73 }
74 74
75 public void Close() 75 public void Close()
76 { 76 {
77 } 77 }
78 78
79 public string Name 79 public string Name
80 { 80 {
81 get { return "FriendsModule"; } 81 get { return "FriendsModule"; }
82 } 82 }
83 83
84 public bool IsSharedModule 84 public bool IsSharedModule
85 { 85 {
86 get { return true; } 86 get { return true; }
87 } 87 }
88 88
89 #endregion 89 #endregion
90 90
91 public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req) 91 public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req)
92 { 92 {
93 m_log.Info("[FRIENDS]: Got Notification about a user! OMG"); 93 m_log.Info("[FRIENDS]: Got Notification about a user! OMG");
94 return new XmlRpcResponse(); 94 return new XmlRpcResponse();
95 } 95 }
96 96
97 private void OnNewClient(IClientAPI client) 97 private void OnNewClient(IClientAPI client)
98 { 98 {
99 // All friends establishment protocol goes over instant message 99 // All friends establishment protocol goes over instant message
100 // There's no way to send a message from the sim 100 // There's no way to send a message from the sim
101 // to a user to 'add a friend' without causing dialog box spam 101 // to a user to 'add a friend' without causing dialog box spam
102 // 102 //
103 // The base set of friends are added when the user signs on in their XMLRPC response 103 // The base set of friends are added when the user signs on in their XMLRPC response
104 // Generated by LoginService. The friends are retreived from the database by the UserManager 104 // Generated by LoginService. The friends are retreived from the database by the UserManager
105 105
106 // Subscribe to instant messages 106 // Subscribe to instant messages
107 107
108 client.OnInstantMessage += OnInstantMessage; 108 client.OnInstantMessage += OnInstantMessage;
109 client.OnApproveFriendRequest += OnApprovedFriendRequest; 109 client.OnApproveFriendRequest += OnApprovedFriendRequest;
110 client.OnDenyFriendRequest += OnDenyFriendRequest; 110 client.OnDenyFriendRequest += OnDenyFriendRequest;
111 client.OnTerminateFriendship += OnTerminateFriendship; 111 client.OnTerminateFriendship += OnTerminateFriendship;
112 112
113 List<FriendListItem> fl = new List<FriendListItem>(); 113 List<FriendListItem> fl = new List<FriendListItem>();
114 114
115 //bool addFLback = false; 115 //bool addFLback = false;
116 116
117 lock (FriendLists) 117 lock (FriendLists)
118 { 118 {
119 if (FriendLists.ContainsKey(client.AgentId)) 119 if (FriendLists.ContainsKey(client.AgentId))
120 { 120 {
121 fl = FriendLists[client.AgentId]; 121 fl = FriendLists[client.AgentId];
122 } 122 }
123 else 123 else
124 { 124 {
125 fl = m_scene[0].GetFriendList(client.AgentId); 125 fl = m_scene[0].GetFriendList(client.AgentId);
126 126
127 //lock (FriendLists) 127 //lock (FriendLists)
128 //{ 128 //{
129 if (!FriendLists.ContainsKey(client.AgentId)) 129 if (!FriendLists.ContainsKey(client.AgentId))
130 FriendLists.Add(client.AgentId, fl); 130 FriendLists.Add(client.AgentId, fl);
131 //} 131 //}
132 } 132 }
133 } 133 }
134 134
135 List<LLUUID> UpdateUsers = new List<LLUUID>(); 135 List<LLUUID> UpdateUsers = new List<LLUUID>();
136 136
137 foreach (FriendListItem f in fl) 137 foreach (FriendListItem f in fl)
138 { 138 {
139 if (m_rootAgents.ContainsKey(f.Friend)) 139 if (m_rootAgents.ContainsKey(f.Friend))
140 { 140 {
141 if (f.onlinestatus == false) 141 if (f.onlinestatus == false)
142 { 142 {
143 UpdateUsers.Add(f.Friend); 143 UpdateUsers.Add(f.Friend);
144 f.onlinestatus = true; 144 f.onlinestatus = true;
145 } 145 }
146 } 146 }
147 } 147 }
148 foreach (LLUUID user in UpdateUsers) 148 foreach (LLUUID user in UpdateUsers)
149 { 149 {
150 ScenePresence av = GetPresenceFromAgentID(user); 150 ScenePresence av = GetPresenceFromAgentID(user);
151 if (av != null) 151 if (av != null)
152 { 152 {
153 List<FriendListItem> usrfl = new List<FriendListItem>(); 153 List<FriendListItem> usrfl = new List<FriendListItem>();
154 154
155 lock (FriendLists) 155 lock (FriendLists)
156 { 156 {
157 usrfl = FriendLists[user]; 157 usrfl = FriendLists[user];
158 } 158 }
159 159
160 lock (usrfl) 160 lock (usrfl)
161 { 161 {
162 foreach (FriendListItem fli in usrfl) 162 foreach (FriendListItem fli in usrfl)
163 { 163 {
164 if (fli.Friend == client.AgentId) 164 if (fli.Friend == client.AgentId)
165 { 165 {
166 fli.onlinestatus = true; 166 fli.onlinestatus = true;
167 OnlineNotificationPacket onp = new OnlineNotificationPacket(); 167 OnlineNotificationPacket onp = new OnlineNotificationPacket();
168 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[1]; 168 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[1];
169 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); 169 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock();
170 onpbl.AgentID = client.AgentId; 170 onpbl.AgentID = client.AgentId;
171 onpb[0] = onpbl; 171 onpb[0] = onpbl;
172 onp.AgentBlock = onpb; 172 onp.AgentBlock = onpb;
173 av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); 173 av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task);
174 } 174 }
175 } 175 }
176 } 176 }
177 } 177 }
178 } 178 }
179 179
180 if (UpdateUsers.Count > 0) 180 if (UpdateUsers.Count > 0)
181 { 181 {
182 OnlineNotificationPacket onp = new OnlineNotificationPacket(); 182 OnlineNotificationPacket onp = new OnlineNotificationPacket();
183 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[UpdateUsers.Count]; 183 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[UpdateUsers.Count];
184 for (int i = 0; i < UpdateUsers.Count; i++) 184 for (int i = 0; i < UpdateUsers.Count; i++)
185 { 185 {
186 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); 186 OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock();
187 onpbl.AgentID = UpdateUsers[i]; 187 onpbl.AgentID = UpdateUsers[i];
188 onpb[i] = onpbl; 188 onpb[i] = onpbl;
189 } 189 }
190 onp.AgentBlock = onpb; 190 onp.AgentBlock = onpb;
191 client.OutPacket(onp, ThrottleOutPacketType.Task); 191 client.OutPacket(onp, ThrottleOutPacketType.Task);
192 } 192 }
193 } 193 }
194 194
195 private void ClientLoggedOut(LLUUID AgentId) 195 private void ClientLoggedOut(LLUUID AgentId)
196 { 196 {
197 lock (m_rootAgents) 197 lock (m_rootAgents)
198 { 198 {
199 if (m_rootAgents.ContainsKey(AgentId)) 199 if (m_rootAgents.ContainsKey(AgentId))
200 { 200 {
201 m_rootAgents.Remove(AgentId); 201 m_rootAgents.Remove(AgentId);
202 m_log.Info("[FRIEND]: Removing " + AgentId + ". Agent logged out."); 202 m_log.Info("[FRIEND]: Removing " + AgentId + ". Agent logged out.");
203 } 203 }
204 } 204 }
205 List<FriendListItem> lfli = new List<FriendListItem>(); 205 List<FriendListItem> lfli = new List<FriendListItem>();
206 lock (FriendLists) 206 lock (FriendLists)
207 { 207 {
208 if (FriendLists.ContainsKey(AgentId)) 208 if (FriendLists.ContainsKey(AgentId))
209 { 209 {
210 lfli = FriendLists[AgentId]; 210 lfli = FriendLists[AgentId];
211 } 211 }
212 } 212 }
213 List<LLUUID> updateUsers = new List<LLUUID>(); 213 List<LLUUID> updateUsers = new List<LLUUID>();
214 foreach (FriendListItem fli in lfli) 214 foreach (FriendListItem fli in lfli)
215 { 215 {
216 if (fli.onlinestatus == true) 216 if (fli.onlinestatus == true)
217 { 217 {
218 updateUsers.Add(fli.Friend); 218 updateUsers.Add(fli.Friend);
219 } 219 }
220 } 220 }
221 lock (updateUsers) 221 lock (updateUsers)
222 { 222 {
223 for (int i = 0; i < updateUsers.Count; i++) 223 for (int i = 0; i < updateUsers.Count; i++)
224 { 224 {
225 List<FriendListItem> flfli = new List<FriendListItem>(); 225 List<FriendListItem> flfli = new List<FriendListItem>();
226 try 226 try
227 { 227 {
228 lock (FriendLists) 228 lock (FriendLists)
229 { 229 {
230 if (FriendLists.ContainsKey(updateUsers[i])) 230 if (FriendLists.ContainsKey(updateUsers[i]))
231 flfli = FriendLists[updateUsers[i]]; 231 flfli = FriendLists[updateUsers[i]];
232 } 232 }
233 } 233 }
234 catch (IndexOutOfRangeException) 234 catch (IndexOutOfRangeException)
235 { 235 {
236 // Ignore the index out of range exception. 236 // Ignore the index out of range exception.
237 // This causes friend lists to get out of sync slightly.. however 237 // This causes friend lists to get out of sync slightly.. however
238 // prevents a sim crash. 238 // prevents a sim crash.
239 m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); 239 m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off");
240 } 240 }
241 241
242 for (int j = 0; j < flfli.Count; j++) 242 for (int j = 0; j < flfli.Count; j++)
243 { 243 {
244 try 244 try
245 { 245 {
246 if (flfli[i].Friend == AgentId) 246 if (flfli[i].Friend == AgentId)
247 { 247 {
248 flfli[i].onlinestatus = false; 248 flfli[i].onlinestatus = false;
249 } 249 }
250 } 250 }
251 251
252 catch (IndexOutOfRangeException) 252 catch (IndexOutOfRangeException)
253 { 253 {
254 // Ignore the index out of range exception. 254 // Ignore the index out of range exception.
255 // This causes friend lists to get out of sync slightly.. however 255 // This causes friend lists to get out of sync slightly.. however
256 // prevents a sim crash. 256 // prevents a sim crash.
257 m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); 257 m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off");
258 } 258 }
259 } 259 }
260 } 260 }
261 261
262 for (int i = 0; i < updateUsers.Count; i++) 262 for (int i = 0; i < updateUsers.Count; i++)
263 { 263 {
264 ScenePresence av = GetPresenceFromAgentID(updateUsers[i]); 264 ScenePresence av = GetPresenceFromAgentID(updateUsers[i]);
265 if (av != null) 265 if (av != null)
266 { 266 {
267 OfflineNotificationPacket onp = new OfflineNotificationPacket(); 267 OfflineNotificationPacket onp = new OfflineNotificationPacket();
268 OfflineNotificationPacket.AgentBlockBlock[] onpb = new OfflineNotificationPacket.AgentBlockBlock[1]; 268 OfflineNotificationPacket.AgentBlockBlock[] onpb = new OfflineNotificationPacket.AgentBlockBlock[1];
269 OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); 269 OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock();
270 onpbl.AgentID = AgentId; 270 onpbl.AgentID = AgentId;
271 onpb[0] = onpbl; 271 onpb[0] = onpbl;
272 onp.AgentBlock = onpb; 272 onp.AgentBlock = onpb;
273 av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); 273 av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task);
274 } 274 }
275 } 275 }
276 } 276 }
277 lock (FriendLists) 277 lock (FriendLists)
278 { 278 {
279 FriendLists.Remove(AgentId); 279 FriendLists.Remove(AgentId);
280 } 280 }
281 } 281 }
282 282
283 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) 283 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
284 { 284 {
285 lock (m_rootAgents) 285 lock (m_rootAgents)
286 { 286 {
287 if (m_rootAgents.ContainsKey(avatar.UUID)) 287 if (m_rootAgents.ContainsKey(avatar.UUID))
288 { 288 {
289 if (avatar.RegionHandle != m_rootAgents[avatar.UUID]) 289 if (avatar.RegionHandle != m_rootAgents[avatar.UUID])
290 { 290 {
291 m_rootAgents[avatar.UUID] = avatar.RegionHandle; 291 m_rootAgents[avatar.UUID] = avatar.RegionHandle;
292 m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); 292 m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + ".");
293 if (avatar.JID.Length > 0) 293 if (avatar.JID.Length > 0)
294 { 294 {
295 JId avatarID = new JId(avatar.JID); 295 JId avatarID = new JId(avatar.JID);
296 // REST Post XMPP Stanzas! 296 // REST Post XMPP Stanzas!
297 } 297 }
298 // Claim User! my user! Mine mine mine! 298 // Claim User! my user! Mine mine mine!
299 } 299 }
300 } 300 }
301 else 301 else
302 { 302 {
303 m_rootAgents.Add(avatar.UUID, avatar.RegionHandle); 303 m_rootAgents.Add(avatar.UUID, avatar.RegionHandle);
304 m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); 304 m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + ".");
305 } 305 }
306 } 306 }
307 //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); 307 //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString());
308 } 308 }
309 309
310 private void MakeChildAgent(ScenePresence avatar) 310 private void MakeChildAgent(ScenePresence avatar)
311 { 311 {
312 lock (m_rootAgents) 312 lock (m_rootAgents)
313 { 313 {
314 if (m_rootAgents.ContainsKey(avatar.UUID)) 314 if (m_rootAgents.ContainsKey(avatar.UUID))
315 { 315 {
316 if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) 316 if (m_rootAgents[avatar.UUID] == avatar.RegionHandle)
317 { 317 {
318 m_rootAgents.Remove(avatar.UUID); 318 m_rootAgents.Remove(avatar.UUID);
319 m_log.Info("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); 319 m_log.Info("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent");
320 } 320 }
321 } 321 }
322 } 322 }
323 } 323 }
324 324
325 private ScenePresence GetPresenceFromAgentID(LLUUID AgentID) 325 private ScenePresence GetPresenceFromAgentID(LLUUID AgentID)
326 { 326 {
327 ScenePresence returnAgent = null; 327 ScenePresence returnAgent = null;
328 lock (m_scene) 328 lock (m_scene)
329 { 329 {
330 ScenePresence queryagent = null; 330 ScenePresence queryagent = null;
331 for (int i = 0; i < m_scene.Count; i++) 331 for (int i = 0; i < m_scene.Count; i++)
332 { 332 {
333 queryagent = m_scene[i].GetScenePresence(AgentID); 333 queryagent = m_scene[i].GetScenePresence(AgentID);
334 if (queryagent != null) 334 if (queryagent != null)
335 { 335 {
336 if (!queryagent.IsChildAgent) 336 if (!queryagent.IsChildAgent)
337 { 337 {
338 returnAgent = queryagent; 338 returnAgent = queryagent;
339 break; 339 break;
340 } 340 }
341 } 341 }
342 } 342 }
343 } 343 }
344 return returnAgent; 344 return returnAgent;
345 } 345 }
346 346
347 #region FriendRequestHandling 347 #region FriendRequestHandling
348 348
349 private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, 349 private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID,
350 LLUUID fromAgentSession, LLUUID toAgentID, 350 LLUUID fromAgentSession, LLUUID toAgentID,
351 LLUUID imSessionID, uint timestamp, string fromAgentName, 351 LLUUID imSessionID, uint timestamp, string fromAgentName,
352 string message, byte dialog, bool fromGroup, byte offline, 352 string message, byte dialog, bool fromGroup, byte offline,
353 uint ParentEstateID, LLVector3 Position, LLUUID RegionID, 353 uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
354 byte[] binaryBucket) 354 byte[] binaryBucket)
355 { 355 {
356 // Friend Requests go by Instant Message.. using the dialog param 356 // Friend Requests go by Instant Message.. using the dialog param
357 // https://wiki.secondlife.com/wiki/ImprovedInstantMessage 357 // https://wiki.secondlife.com/wiki/ImprovedInstantMessage
358 358
359 // 38 == Offer friendship 359 // 38 == Offer friendship
360 if (dialog == (byte) 38) 360 if (dialog == (byte) 38)
361 { 361 {
362 LLUUID friendTransactionID = LLUUID.Random(); 362 LLUUID friendTransactionID = LLUUID.Random();
363 363
364 m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 364 m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
365 365
366 m_log.Info("[FRIEND]: 38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + 366 m_log.Info("[FRIEND]: 38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" +
367 message); 367 message);
368 GridInstantMessage msg = new GridInstantMessage(); 368 GridInstantMessage msg = new GridInstantMessage();
369 msg.fromAgentID = fromAgentID.UUID; 369 msg.fromAgentID = fromAgentID.UUID;
370 msg.fromAgentSession = fromAgentSession.UUID; 370 msg.fromAgentSession = fromAgentSession.UUID;
371 msg.toAgentID = toAgentID.UUID; 371 msg.toAgentID = toAgentID.UUID;
372 msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here 372 msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here
373 m_log.Info("[FRIEND]: Filling Session: " + msg.imSessionID.ToString()); 373 m_log.Info("[FRIEND]: Filling Session: " + msg.imSessionID.ToString());
374 msg.timestamp = timestamp; 374 msg.timestamp = timestamp;
375 if (client != null) 375 if (client != null)
376 { 376 {
377 msg.fromAgentName = client.FirstName + " " + client.LastName; // fromAgentName; 377 msg.fromAgentName = client.FirstName + " " + client.LastName; // fromAgentName;
378 } 378 }
379 else 379 else
380 { 380 {
381 msg.fromAgentName = "(hippos)"; // Added for posterity. This means that we can't figure out who sent it 381 msg.fromAgentName = "(hippos)"; // Added for posterity. This means that we can't figure out who sent it
382 } 382 }
383 msg.message = message; 383 msg.message = message;
384 msg.dialog = dialog; 384 msg.dialog = dialog;
385 msg.fromGroup = fromGroup; 385 msg.fromGroup = fromGroup;
386 msg.offline = offline; 386 msg.offline = offline;
387 msg.ParentEstateID = ParentEstateID; 387 msg.ParentEstateID = ParentEstateID;
388 msg.Position = new sLLVector3(Position); 388 msg.Position = new sLLVector3(Position);
389 msg.RegionID = RegionID.UUID; 389 msg.RegionID = RegionID.UUID;
390 msg.binaryBucket = binaryBucket; 390 msg.binaryBucket = binaryBucket;
391 // We don't really care which scene we pipe it through. 391 // We don't really care which scene we pipe it through.
392 m_scene[0].TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); 392 m_scene[0].TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
393 } 393 }
394 394
395 // 39 == Accept Friendship 395 // 39 == Accept Friendship
396 if (dialog == (byte) 39) 396 if (dialog == (byte) 39)
397 { 397 {
398 m_log.Info("[FRIEND]: 39 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + 398 m_log.Info("[FRIEND]: 39 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" +
399 message); 399 message);
400 } 400 }
401 401
402 // 40 == Decline Friendship 402 // 40 == Decline Friendship
403 if (dialog == (byte) 40) 403 if (dialog == (byte) 40)
404 { 404 {
405 m_log.Info("[FRIEND]: 40 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + 405 m_log.Info("[FRIEND]: 40 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" +
406 message); 406 message);
407 } 407 }
408 } 408 }
409 409
410 private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) 410 private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders)
411 { 411 {
412 if (m_pendingFriendRequests.ContainsKey(transactionID)) 412 if (m_pendingFriendRequests.ContainsKey(transactionID))
413 { 413 {
414 // Found Pending Friend Request with that Transaction.. 414 // Found Pending Friend Request with that Transaction..
415 Scene SceneAgentIn = m_scene[0]; 415 Scene SceneAgentIn = m_scene[0];
416 416
417 // Found Pending Friend Request with that Transaction.. 417 // Found Pending Friend Request with that Transaction..
418 ScenePresence agentpresence = GetPresenceFromAgentID(agentID); 418 ScenePresence agentpresence = GetPresenceFromAgentID(agentID);
419 if (agentpresence != null) 419 if (agentpresence != null)
420 { 420 {
421 SceneAgentIn = agentpresence.Scene; 421 SceneAgentIn = agentpresence.Scene;
422 } 422 }
423 423
424 // Compose response to other agent. 424 // Compose response to other agent.
425 GridInstantMessage msg = new GridInstantMessage(); 425 GridInstantMessage msg = new GridInstantMessage();
426 msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; 426 msg.toAgentID = m_pendingFriendRequests[transactionID].UUID;
427 msg.fromAgentID = agentID.UUID; 427 msg.fromAgentID = agentID.UUID;
428 msg.fromAgentName = client.FirstName + " " + client.LastName; 428 msg.fromAgentName = client.FirstName + " " + client.LastName;
429 msg.fromAgentSession = client.SessionId.UUID; 429 msg.fromAgentSession = client.SessionId.UUID;
430 msg.fromGroup = false; 430 msg.fromGroup = false;
431 msg.imSessionID = transactionID.UUID; 431 msg.imSessionID = transactionID.UUID;
432 msg.message = agentID.UUID.ToString(); 432 msg.message = agentID.UUID.ToString();
433 msg.ParentEstateID = 0; 433 msg.ParentEstateID = 0;
434 msg.timestamp = (uint) Util.UnixTimeSinceEpoch(); 434 msg.timestamp = (uint) Util.UnixTimeSinceEpoch();
435 msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; 435 msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID;
436 msg.dialog = (byte) 39; // Approved friend request 436 msg.dialog = (byte) 39; // Approved friend request
437 msg.Position = new sLLVector3(); 437 msg.Position = new sLLVector3();
438 msg.offline = (byte) 0; 438 msg.offline = (byte) 0;
439 msg.binaryBucket = new byte[0]; 439 msg.binaryBucket = new byte[0];
440 // We don't really care which scene we pipe it through, it goes to the shared IM Module and/or the database 440 // We don't really care which scene we pipe it through, it goes to the shared IM Module and/or the database
441 441
442 SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); 442 SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
443 SceneAgentIn.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint) 1); 443 SceneAgentIn.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint) 1);
444 m_pendingFriendRequests.Remove(transactionID); 444 m_pendingFriendRequests.Remove(transactionID);
445 445
446 // TODO: Inform agent that the friend is online 446 // TODO: Inform agent that the friend is online
447 } 447 }
448 } 448 }
449 449
450 private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) 450 private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders)
451 { 451 {
452 if (m_pendingFriendRequests.ContainsKey(transactionID)) 452 if (m_pendingFriendRequests.ContainsKey(transactionID))
453 { 453 {
454 Scene SceneAgentIn = m_scene[0]; 454 Scene SceneAgentIn = m_scene[0];
455 455
456 // Found Pending Friend Request with that Transaction.. 456 // Found Pending Friend Request with that Transaction..
457 ScenePresence agentpresence = GetPresenceFromAgentID(agentID); 457 ScenePresence agentpresence = GetPresenceFromAgentID(agentID);
458 if (agentpresence != null) 458 if (agentpresence != null)
459 { 459 {
460 SceneAgentIn = agentpresence.Scene; 460 SceneAgentIn = agentpresence.Scene;
461 } 461 }
462 // Compose response to other agent. 462 // Compose response to other agent.
463 GridInstantMessage msg = new GridInstantMessage(); 463 GridInstantMessage msg = new GridInstantMessage();
464 msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; 464 msg.toAgentID = m_pendingFriendRequests[transactionID].UUID;
465 msg.fromAgentID = agentID.UUID; 465 msg.fromAgentID = agentID.UUID;
466 msg.fromAgentName = client.FirstName + " " + client.LastName; 466 msg.fromAgentName = client.FirstName + " " + client.LastName;
467 msg.fromAgentSession = client.SessionId.UUID; 467 msg.fromAgentSession = client.SessionId.UUID;
468 msg.fromGroup = false; 468 msg.fromGroup = false;
469 msg.imSessionID = transactionID.UUID; 469 msg.imSessionID = transactionID.UUID;
470 msg.message = agentID.UUID.ToString(); 470 msg.message = agentID.UUID.ToString();
471 msg.ParentEstateID = 0; 471 msg.ParentEstateID = 0;
472 msg.timestamp = (uint) Util.UnixTimeSinceEpoch(); 472 msg.timestamp = (uint) Util.UnixTimeSinceEpoch();
473 msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; 473 msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID;
474 msg.dialog = (byte) 40; // Deny friend request 474 msg.dialog = (byte) 40; // Deny friend request
475 msg.Position = new sLLVector3(); 475 msg.Position = new sLLVector3();
476 msg.offline = (byte) 0; 476 msg.offline = (byte) 0;
477 msg.binaryBucket = new byte[0]; 477 msg.binaryBucket = new byte[0];
478 SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); 478 SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
479 m_pendingFriendRequests.Remove(transactionID); 479 m_pendingFriendRequests.Remove(transactionID);
480 } 480 }
481 } 481 }
482 482
483 private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID) 483 private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID)
484 { 484 {
485 m_scene[0].StoreRemoveFriendship(agent, exfriendID); 485 m_scene[0].StoreRemoveFriendship(agent, exfriendID);
486 // TODO: Inform the client that the ExFriend is offline 486 // TODO: Inform the client that the ExFriend is offline
487 } 487 }
488 488
489 private void OnGridInstantMessage(GridInstantMessage msg) 489 private void OnGridInstantMessage(GridInstantMessage msg)
490 { 490 {
491 // Trigger the above event handler 491 // Trigger the above event handler
492 OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), 492 OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession),
493 new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, 493 new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName,
494 msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, 494 msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID,
495 new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), 495 new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
496 msg.binaryBucket); 496 msg.binaryBucket);
497 } 497 }
498 498
499 #endregion 499 #endregion
500 } 500 }
501} \ No newline at end of file 501} \ No newline at end of file