aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Addons/Groups/GroupsExtendedData.cs24
-rw-r--r--OpenSim/Addons/Groups/GroupsMessagingModule.cs435
-rw-r--r--OpenSim/Addons/Groups/GroupsModule.cs61
-rw-r--r--OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs22
-rw-r--r--OpenSim/Addons/Groups/IGroupsServicesConnector.cs6
-rw-r--r--OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs22
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs30
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs24
-rw-r--r--OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs28
-rw-r--r--OpenSim/Addons/Groups/Service/GroupsService.cs19
-rw-r--r--OpenSim/Data/MySQL/MySQLGroupsData.cs2
-rw-r--r--OpenSim/Framework/GridInstantMessage.cs18
-rw-r--r--OpenSim/Framework/Servers/MainServer.cs5
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs70
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs9
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs11
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs39
-rw-r--r--OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs197
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs16
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEventQueue.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/IGroupsModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs87
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs6
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs18
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs18
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs22
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs1
-rw-r--r--OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs1
-rw-r--r--OpenSim/Services/MapImageService/MapImageService.cs2
-rw-r--r--OpenSim/Tests/Common/OpenSimTestCase.cs12
35 files changed, 836 insertions, 405 deletions
diff --git a/OpenSim/Addons/Groups/GroupsExtendedData.cs b/OpenSim/Addons/Groups/GroupsExtendedData.cs
index 6f4db28..1632aee 100644
--- a/OpenSim/Addons/Groups/GroupsExtendedData.cs
+++ b/OpenSim/Addons/Groups/GroupsExtendedData.cs
@@ -504,6 +504,30 @@ namespace OpenSim.Groups
504 504
505 return notice; 505 return notice;
506 } 506 }
507
508 public static Dictionary<string, object> DirGroupsReplyData(DirGroupsReplyData g)
509 {
510 Dictionary<string, object> dict = new Dictionary<string, object>();
511
512 dict["GroupID"] = g.groupID;
513 dict["Name"] = g.groupName;
514 dict["NMembers"] = g.members;
515 dict["SearchOrder"] = g.searchOrder;
516
517 return dict;
518 }
519
520 public static DirGroupsReplyData DirGroupsReplyData(Dictionary<string, object> dict)
521 {
522 DirGroupsReplyData g;
523
524 g.groupID = new UUID(dict["GroupID"].ToString());
525 g.groupName = dict["Name"].ToString();
526 Int32.TryParse(dict["NMembers"].ToString(), out g.members);
527 float.TryParse(dict["SearchOrder"].ToString(), out g.searchOrder);
528
529 return g;
530 }
507 } 531 }
508 532
509} 533}
diff --git a/OpenSim/Addons/Groups/GroupsMessagingModule.cs b/OpenSim/Addons/Groups/GroupsMessagingModule.cs
index d172d48..5de1fb4 100644
--- a/OpenSim/Addons/Groups/GroupsMessagingModule.cs
+++ b/OpenSim/Addons/Groups/GroupsMessagingModule.cs
@@ -39,6 +39,7 @@ using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; 41using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
42using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42 43
43namespace OpenSim.Groups 44namespace OpenSim.Groups
44{ 45{
@@ -51,7 +52,7 @@ namespace OpenSim.Groups
51 private IPresenceService m_presenceService; 52 private IPresenceService m_presenceService;
52 53
53 private IMessageTransferModule m_msgTransferModule = null; 54 private IMessageTransferModule m_msgTransferModule = null;
54 55 private IUserManagement m_UserManagement = null;
55 private IGroupsServicesConnector m_groupData = null; 56 private IGroupsServicesConnector m_groupData = null;
56 57
57 // Config Options 58 // Config Options
@@ -79,6 +80,10 @@ namespace OpenSim.Groups
79 80
80 private int m_usersOnlineCacheExpirySeconds = 20; 81 private int m_usersOnlineCacheExpirySeconds = 20;
81 82
83 private Dictionary<UUID, List<string>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<string>>();
84 private Dictionary<UUID, List<string>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<string>>();
85
86
82 #region Region Module interfaceBase Members 87 #region Region Module interfaceBase Members
83 88
84 public void Initialise(IConfigSource config) 89 public void Initialise(IConfigSource config)
@@ -124,10 +129,12 @@ namespace OpenSim.Groups
124 m_sceneList.Add(scene); 129 m_sceneList.Add(scene);
125 130
126 scene.EventManager.OnNewClient += OnNewClient; 131 scene.EventManager.OnNewClient += OnNewClient;
132 scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
133 scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
127 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 134 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
128 scene.EventManager.OnClientLogin += OnClientLogin; 135 scene.EventManager.OnClientLogin += OnClientLogin;
129 } 136 }
130 137
131 public void RegionLoaded(Scene scene) 138 public void RegionLoaded(Scene scene)
132 { 139 {
133 if (!m_groupMessagingEnabled) 140 if (!m_groupMessagingEnabled)
@@ -155,6 +162,17 @@ namespace OpenSim.Groups
155 return; 162 return;
156 } 163 }
157 164
165 m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
166
167 // No groups module, no groups messaging
168 if (m_UserManagement == null)
169 {
170 m_log.Error("[Groups.Messaging]: Could not get IUserManagement, GroupsMessagingModule is now disabled.");
171 RemoveRegion(scene);
172 return;
173 }
174
175
158 if (m_presenceService == null) 176 if (m_presenceService == null)
159 m_presenceService = scene.PresenceService; 177 m_presenceService = scene.PresenceService;
160 178
@@ -227,87 +245,106 @@ namespace OpenSim.Groups
227 245
228 public void SendMessageToGroup(GridInstantMessage im, UUID groupID) 246 public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
229 { 247 {
230 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID).ToString(), groupID); 248 UUID fromAgentID = new UUID(im.fromAgentID);
249 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers("all", groupID);
231 int groupMembersCount = groupMembers.Count; 250 int groupMembersCount = groupMembers.Count;
251 PresenceInfo[] onlineAgents = null;
232 252
233 if (m_messageOnlineAgentsOnly) 253 // In V2 we always only send to online members.
234 { 254 // Sending to offline members is not an option.
235 string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray(); 255 string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
236 256
237 // We cache in order not to overwhlem the presence service on large grids with many groups. This does 257 // We cache in order not to overwhlem the presence service on large grids with many groups. This does
238 // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. 258 // mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
239 // (assuming this is the same across all grid simulators). 259 // (assuming this is the same across all grid simulators).
240 PresenceInfo[] onlineAgents; 260 if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
241 if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents)) 261 {
242 { 262 onlineAgents = m_presenceService.GetAgents(t1);
243 onlineAgents = m_presenceService.GetAgents(t1); 263 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
244 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); 264 }
245 }
246 265
247 HashSet<string> onlineAgentsUuidSet = new HashSet<string>(); 266 HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
248 Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID)); 267 Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
249 268
250 groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); 269 groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
251 270
252 // if (m_debugEnabled) 271// if (m_debugEnabled)
253// m_log.DebugFormat( 272// m_log.DebugFormat(
254// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", 273// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
255// groupID, groupMembersCount, groupMembers.Count()); 274// groupID, groupMembersCount, groupMembers.Count());
256 } 275
257 else 276 int requestStartTick = Environment.TickCount;
277
278 im.imSessionID = groupID.Guid;
279 im.fromGroup = true;
280 IClientAPI thisClient = GetActiveClient(fromAgentID);
281 if (thisClient != null)
258 { 282 {
259 if (m_debugEnabled) 283 im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
260 m_log.DebugFormat(
261 "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members",
262 groupID, groupMembers.Count);
263 } 284 }
264 285
265 int requestStartTick = Environment.TickCount; 286 // Send to self first of all
287 im.toAgentID = im.fromAgentID;
288 im.fromGroup = true;
289 ProcessMessageFromGroupSession(im);
266 290
291 List<UUID> regions = new List<UUID>();
292 List<UUID> clientsAlreadySent = new List<UUID>();
293
294 // Then send to everybody else
267 foreach (GroupMembersData member in groupMembers) 295 foreach (GroupMembersData member in groupMembers)
268 { 296 {
269 if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) 297 if (member.AgentID.Guid == im.fromAgentID)
298 continue;
299
300 if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
270 { 301 {
271 // Don't deliver messages to people who have dropped this session 302 // Don't deliver messages to people who have dropped this session
272 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID); 303 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
273 continue; 304 continue;
274 } 305 }
275 306
276 // Copy Message 307 im.toAgentID = member.AgentID.Guid;
277 GridInstantMessage msg = new GridInstantMessage();
278 msg.imSessionID = groupID.Guid;
279 msg.fromAgentName = im.fromAgentName;
280 msg.message = im.message;
281 msg.dialog = im.dialog;
282 msg.offline = im.offline;
283 msg.ParentEstateID = im.ParentEstateID;
284 msg.Position = im.Position;
285 msg.RegionID = im.RegionID;
286 msg.binaryBucket = im.binaryBucket;
287 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
288
289 msg.fromAgentID = im.fromAgentID;
290 msg.fromGroup = true;
291
292 msg.toAgentID = member.AgentID.Guid;
293 308
294 IClientAPI client = GetActiveClient(member.AgentID); 309 IClientAPI client = GetActiveClient(member.AgentID);
295 if (client == null) 310 if (client == null)
296 { 311 {
297 // If they're not local, forward across the grid 312 // If they're not local, forward across the grid
313 // BUT do it only once per region, please! Sim would be even better!
298 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID); 314 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
299 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); 315
316 bool reallySend = true;
317 if (onlineAgents != null)
318 {
319 PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
320 if (regions.Contains(presence.RegionID))
321 reallySend = false;
322 else
323 regions.Add(presence.RegionID);
324 }
325
326 if (reallySend)
327 {
328 // We have to create a new IM structure because the transfer module
329 // uses async send
330 GridInstantMessage msg = new GridInstantMessage(im, true);
331 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
332 }
300 } 333 }
301 else 334 else
302 { 335 {
303 // Deliver locally, directly 336 // Deliver locally, directly
304 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); 337 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
305 ProcessMessageFromGroupSession(msg); 338
339 if (clientsAlreadySent.Contains(member.AgentID))
340 continue;
341 clientsAlreadySent.Add(member.AgentID);
342
343 ProcessMessageFromGroupSession(im);
306 } 344 }
307 } 345 }
308 346
309 // Temporary for assessing how long it still takes to send messages to large online groups. 347 if (m_debugEnabled)
310 if (m_messageOnlineAgentsOnly)
311 m_log.DebugFormat( 348 m_log.DebugFormat(
312 "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", 349 "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
313 groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); 350 groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
@@ -324,9 +361,20 @@ namespace OpenSim.Groups
324 { 361 {
325 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name); 362 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
326 363
327 client.OnInstantMessage += OnInstantMessage; 364 ResetAgentGroupChatSessions(client.AgentId.ToString());
328 } 365 }
329 366
367 void OnMakeRootAgent(ScenePresence sp)
368 {
369 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
370 }
371
372 void OnMakeChildAgent(ScenePresence sp)
373 {
374 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
375 }
376
377
330 private void OnGridInstantMessage(GridInstantMessage msg) 378 private void OnGridInstantMessage(GridInstantMessage msg)
331 { 379 {
332 // The instant message module will only deliver messages of dialog types: 380 // The instant message module will only deliver messages of dialog types:
@@ -335,21 +383,97 @@ namespace OpenSim.Groups
335 // Any other message type will not be delivered to a client by the 383 // Any other message type will not be delivered to a client by the
336 // Instant Message Module 384 // Instant Message Module
337 385
338 386 UUID regionID = new UUID(msg.RegionID);
339 if (m_debugEnabled) 387 if (m_debugEnabled)
340 { 388 {
341 m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 389 m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
390 System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
342 391
343 DebugGridInstantMessage(msg); 392 DebugGridInstantMessage(msg);
344 } 393 }
345 394
346 // Incoming message from a group 395 // Incoming message from a group
347 if ((msg.fromGroup == true) && 396 if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend))
348 ((msg.dialog == (byte)InstantMessageDialog.SessionSend)
349 || (msg.dialog == (byte)InstantMessageDialog.SessionAdd)
350 || (msg.dialog == (byte)InstantMessageDialog.SessionDrop)))
351 { 397 {
352 ProcessMessageFromGroupSession(msg); 398 // We have to redistribute the message across all members of the group who are here
399 // on this sim
400
401 UUID GroupID = new UUID(msg.imSessionID);
402
403 Scene aScene = m_sceneList[0];
404 GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID);
405
406 List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers("all", GroupID);
407 List<UUID> alreadySeen = new List<UUID>();
408
409 //if (m_debugEnabled)
410 // foreach (GroupMembersData m in groupMembers)
411 // m_log.DebugFormat("[Groups.Messaging]: member {0}", m.AgentID);
412
413 foreach (Scene s in m_sceneList)
414 {
415 s.ForEachScenePresence(sp =>
416 {
417 // We need this, because we are searching through all
418 // SPs, both root and children
419 if (alreadySeen.Contains(sp.UUID))
420 {
421 if (m_debugEnabled)
422 m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because we've already seen it", sp.UUID);
423 return;
424 }
425 alreadySeen.Add(sp.UUID);
426
427 GroupMembersData m = groupMembers.Find(gmd =>
428 {
429 return gmd.AgentID == sp.UUID;
430 });
431 if (m.AgentID == UUID.Zero)
432 {
433 if (m_debugEnabled)
434 m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he is not a member of the group", sp.UUID);
435 return;
436 }
437
438 // Check if the user has an agent in the region where
439 // the IM came from, and if so, skip it, because the IM
440 // was already sent via that agent
441 if (regionOfOrigin != null)
442 {
443 AgentCircuitData aCircuit = s.AuthenticateHandler.GetAgentCircuitData(sp.UUID);
444 if (aCircuit != null)
445 {
446 if (aCircuit.ChildrenCapSeeds.Keys.Contains(regionOfOrigin.RegionHandle))
447 {
448 if (m_debugEnabled)
449 m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
450 return;
451 }
452 else
453 {
454 if (m_debugEnabled)
455 m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
456 }
457 }
458 }
459
460 UUID AgentID = sp.UUID;
461 msg.toAgentID = AgentID.Guid;
462
463 if (!hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID))
464 {
465 if (!hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID))
466 AddAgentToSession(AgentID, GroupID, msg);
467 else
468 {
469 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", sp.Name);
470
471 ProcessMessageFromGroupSession(msg);
472 }
473 }
474 });
475
476 }
353 } 477 }
354 } 478 }
355 479
@@ -359,82 +483,40 @@ namespace OpenSim.Groups
359 483
360 UUID AgentID = new UUID(msg.fromAgentID); 484 UUID AgentID = new UUID(msg.fromAgentID);
361 UUID GroupID = new UUID(msg.imSessionID); 485 UUID GroupID = new UUID(msg.imSessionID);
486 UUID toAgentID = new UUID(msg.toAgentID);
362 487
363 switch (msg.dialog) 488 switch (msg.dialog)
364 { 489 {
365 case (byte)InstantMessageDialog.SessionAdd: 490 case (byte)InstantMessageDialog.SessionAdd:
366 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 491 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
367 break; 492 break;
368 493
369 case (byte)InstantMessageDialog.SessionDrop: 494 case (byte)InstantMessageDialog.SessionDrop:
370 m_groupData.AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID); 495 AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
371 break; 496 break;
372 497
373 case (byte)InstantMessageDialog.SessionSend: 498 case (byte)InstantMessageDialog.SessionSend:
374 if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID) 499 // User hasn't dropped, so they're in the session,
375 && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID) 500 // maybe we should deliver it.
376 ) 501 IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
502 if (client != null)
377 { 503 {
378 // Agent not in session and hasn't dropped from session 504 // Deliver locally, directly
379 // Add them to the session for now, and Invite them 505 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
380 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
381 506
382 UUID toAgentID = new UUID(msg.toAgentID); 507 if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID))
383 IClientAPI activeClient = GetActiveClient(toAgentID);
384 if (activeClient != null)
385 { 508 {
386 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null); 509 if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID))
387 if (groupInfo != null) 510 // This actually sends the message too, so no need to resend it
388 { 511 // with client.SendInstantMessage
389 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message"); 512 AddAgentToSession(toAgentID, GroupID, msg);
390 513 else
391 // Force? open the group session dialog??? 514 client.SendInstantMessage(msg);
392 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
393 IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
394 eq.ChatterboxInvitation(
395 GroupID
396 , groupInfo.GroupName
397 , new UUID(msg.fromAgentID)
398 , msg.message
399 , new UUID(msg.toAgentID)
400 , msg.fromAgentName
401 , msg.dialog
402 , msg.timestamp
403 , msg.offline == 1
404 , (int)msg.ParentEstateID
405 , msg.Position
406 , 1
407 , new UUID(msg.imSessionID)
408 , msg.fromGroup
409 , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
410 );
411
412 eq.ChatterBoxSessionAgentListUpdates(
413 new UUID(GroupID)
414 , new UUID(msg.fromAgentID)
415 , new UUID(msg.toAgentID)
416 , false //canVoiceChat
417 , false //isModerator
418 , false //text mute
419 );
420 }
421 } 515 }
422 } 516 }
423 else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID)) 517 else
424 { 518 {
425 // User hasn't dropped, so they're in the session, 519 m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
426 // maybe we should deliver it.
427 IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
428 if (client != null)
429 {
430 // Deliver locally, directly
431 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
432 client.SendInstantMessage(msg);
433 }
434 else
435 {
436 m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
437 }
438 } 520 }
439 break; 521 break;
440 522
@@ -444,6 +526,53 @@ namespace OpenSim.Groups
444 } 526 }
445 } 527 }
446 528
529 private void AddAgentToSession(UUID AgentID, UUID GroupID, GridInstantMessage msg)
530 {
531 // Agent not in session and hasn't dropped from session
532 // Add them to the session for now, and Invite them
533 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
534
535 IClientAPI activeClient = GetActiveClient(AgentID);
536 if (activeClient != null)
537 {
538 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
539 if (groupInfo != null)
540 {
541 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
542
543 // Force? open the group session dialog???
544 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
545 IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
546 eq.ChatterboxInvitation(
547 GroupID
548 , groupInfo.GroupName
549 , new UUID(msg.fromAgentID)
550 , msg.message
551 , AgentID
552 , msg.fromAgentName
553 , msg.dialog
554 , msg.timestamp
555 , msg.offline == 1
556 , (int)msg.ParentEstateID
557 , msg.Position
558 , 1
559 , new UUID(msg.imSessionID)
560 , msg.fromGroup
561 , OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
562 );
563
564 eq.ChatterBoxSessionAgentListUpdates(
565 new UUID(GroupID)
566 , AgentID
567 , new UUID(msg.toAgentID)
568 , false //canVoiceChat
569 , false //isModerator
570 , false //text mute
571 );
572 }
573 }
574 }
575
447 #endregion 576 #endregion
448 577
449 578
@@ -469,7 +598,7 @@ namespace OpenSim.Groups
469 598
470 if (groupInfo != null) 599 if (groupInfo != null)
471 { 600 {
472 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 601 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
473 602
474 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); 603 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
475 604
@@ -495,7 +624,7 @@ namespace OpenSim.Groups
495 m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); 624 m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
496 625
497 //If this agent is sending a message, then they want to be in the session 626 //If this agent is sending a message, then they want to be in the session
498 m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); 627 AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
499 628
500 SendMessageToGroup(im, GroupID); 629 SendMessageToGroup(im, GroupID);
501 } 630 }
@@ -566,12 +695,12 @@ namespace OpenSim.Groups
566 { 695 {
567 if (!sp.IsChildAgent) 696 if (!sp.IsChildAgent)
568 { 697 {
569 if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name); 698 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name);
570 return sp.ControllingClient; 699 return sp.ControllingClient;
571 } 700 }
572 else 701 else
573 { 702 {
574 if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name); 703 if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name);
575 child = sp.ControllingClient; 704 child = sp.ControllingClient;
576 } 705 }
577 } 706 }
@@ -590,5 +719,71 @@ namespace OpenSim.Groups
590 } 719 }
591 720
592 #endregion 721 #endregion
722
723 #region GroupSessionTracking
724
725 public void ResetAgentGroupChatSessions(string agentID)
726 {
727 foreach (List<string> agentList in m_groupsAgentsDroppedFromChatSession.Values)
728 agentList.Remove(agentID);
729
730 foreach (List<string> agentList in m_groupsAgentsInvitedToChatSession.Values)
731 agentList.Remove(agentID);
732 }
733
734 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
735 {
736 // If we're tracking this group, and we can find them in the tracking, then they've been invited
737 return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID)
738 && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID);
739 }
740
741 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
742 {
743 // If we're tracking drops for this group,
744 // and we find them, well... then they've dropped
745 return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
746 && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
747 }
748
749 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
750 {
751 if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
752 {
753 // If not in dropped list, add
754 if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
755 {
756 m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID);
757 }
758 }
759 }
760
761 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
762 {
763 // Add Session Status if it doesn't exist for this session
764 CreateGroupChatSessionTracking(groupID);
765
766 // If nessesary, remove from dropped list
767 if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
768 {
769 m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID);
770 }
771
772 // Add to invited
773 if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
774 m_groupsAgentsInvitedToChatSession[groupID].Add(agentID);
775 }
776
777 private void CreateGroupChatSessionTracking(UUID groupID)
778 {
779 if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
780 {
781 m_groupsAgentsDroppedFromChatSession.Add(groupID, new List<string>());
782 m_groupsAgentsInvitedToChatSession.Add(groupID, new List<string>());
783 }
784
785 }
786 #endregion
787
593 } 788 }
594} 789}
diff --git a/OpenSim/Addons/Groups/GroupsModule.cs b/OpenSim/Addons/Groups/GroupsModule.cs
index 69d03a9..826fcbf 100644
--- a/OpenSim/Addons/Groups/GroupsModule.cs
+++ b/OpenSim/Addons/Groups/GroupsModule.cs
@@ -141,6 +141,8 @@ namespace OpenSim.Groups
141 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 141 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
142 142
143 scene.EventManager.OnNewClient += OnNewClient; 143 scene.EventManager.OnNewClient += OnNewClient;
144 scene.EventManager.OnMakeRootAgent += OnMakeRoot;
145 scene.EventManager.OnMakeChildAgent += OnMakeChild;
144 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 146 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
145 // The InstantMessageModule itself doesn't do this, 147 // The InstantMessageModule itself doesn't do this,
146 // so lets see if things explode if we don't do it 148 // so lets see if things explode if we don't do it
@@ -194,6 +196,8 @@ namespace OpenSim.Groups
194 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 196 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
195 197
196 scene.EventManager.OnNewClient -= OnNewClient; 198 scene.EventManager.OnNewClient -= OnNewClient;
199 scene.EventManager.OnMakeRootAgent -= OnMakeRoot;
200 scene.EventManager.OnMakeChildAgent -= OnMakeChild;
197 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; 201 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
198 202
199 lock (m_sceneList) 203 lock (m_sceneList)
@@ -232,16 +236,29 @@ namespace OpenSim.Groups
232 { 236 {
233 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 237 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
234 238
235 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
236 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 239 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
237 client.OnDirFindQuery += OnDirFindQuery;
238 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 240 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
241 }
242
243 private void OnMakeRoot(ScenePresence sp)
244 {
245 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
239 246
247 sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
240 // Used for Notices and Group Invites/Accept/Reject 248 // Used for Notices and Group Invites/Accept/Reject
241 client.OnInstantMessage += OnInstantMessage; 249 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
242 250
243 // Send client their groups information. 251 // Send client their groups information.
244 SendAgentGroupDataUpdate(client, client.AgentId); 252 SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
253 }
254
255 private void OnMakeChild(ScenePresence sp)
256 {
257 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
258
259 sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
260 // Used for Notices and Group Invites/Accept/Reject
261 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
245 } 262 }
246 263
247 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 264 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
@@ -287,21 +304,6 @@ namespace OpenSim.Groups
287 } 304 }
288 */ 305 */
289 306
290 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
291 {
292 if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
293 {
294 if (m_debugEnabled)
295 m_log.DebugFormat(
296 "[Groups]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
297 System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
298
299 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
300 remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), queryText).ToArray());
301 }
302
303 }
304
305 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) 307 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
306 { 308 {
307 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 309 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -907,23 +909,7 @@ namespace OpenSim.Groups
907 { 909 {
908 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called for notice {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupNoticeID); 910 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called for notice {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupNoticeID);
909 911
910 //GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null);
911
912 GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); 912 GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
913 //GridInstantMessage msg = new GridInstantMessage();
914 //msg.imSessionID = UUID.Zero.Guid;
915 //msg.fromAgentID = data.GroupID.Guid;
916 //msg.toAgentID = GetRequestingAgentID(remoteClient).Guid;
917 //msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
918 //msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName;
919 //msg.message = data.noticeData.Subject + "|" + data.Message;
920 //msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested;
921 //msg.fromGroup = true;
922 //msg.offline = (byte)0;
923 //msg.ParentEstateID = 0;
924 //msg.Position = Vector3.Zero;
925 //msg.RegionID = UUID.Zero.Guid;
926 //msg.binaryBucket = data.BinaryBucket;
927 913
928 OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); 914 OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
929 } 915 }
@@ -1189,6 +1175,11 @@ namespace OpenSim.Groups
1189 } 1175 }
1190 } 1176 }
1191 1177
1178 public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
1179 {
1180 return m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), query);
1181 }
1182
1192 #endregion 1183 #endregion
1193 1184
1194 #region Client/Update Tools 1185 #region Client/Update Tools
diff --git a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
index c3c759e..daa0728 100644
--- a/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
+++ b/OpenSim/Addons/Groups/Hypergrid/GroupsServiceHGConnectorModule.cs
@@ -590,28 +590,6 @@ namespace OpenSim.Groups
590 return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID); 590 return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID);
591 } 591 }
592 592
593 public void ResetAgentGroupChatSessions(string agentID)
594 {
595 }
596
597 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
598 {
599 return false;
600 }
601
602 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
603 {
604 return false;
605 }
606
607 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
608 {
609 }
610
611 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
612 {
613 }
614
615 #endregion 593 #endregion
616 594
617 #region hypergrid groups 595 #region hypergrid groups
diff --git a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs
index 73deb7a..a09b59e 100644
--- a/OpenSim/Addons/Groups/IGroupsServicesConnector.cs
+++ b/OpenSim/Addons/Groups/IGroupsServicesConnector.cs
@@ -92,12 +92,6 @@ namespace OpenSim.Groups
92 GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID); 92 GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
93 List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID); 93 List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID);
94 94
95 void ResetAgentGroupChatSessions(string agentID);
96 bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID);
97 bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID);
98 void AgentDroppedFromGroupChatSession(string agentID, UUID groupID);
99 void AgentInvitedToGroupChatSession(string agentID, UUID groupID);
100
101 } 95 }
102 96
103 public class GroupInviteInfo 97 public class GroupInviteInfo
diff --git a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs
index 905bc91..564dec4 100644
--- a/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs
+++ b/OpenSim/Addons/Groups/Local/GroupsServiceLocalConnectorModule.cs
@@ -320,28 +320,6 @@ namespace OpenSim.Groups
320 return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID); 320 return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
321 } 321 }
322 322
323 public void ResetAgentGroupChatSessions(string agentID)
324 {
325 }
326
327 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
328 {
329 return false;
330 }
331
332 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
333 {
334 return false;
335 }
336
337 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
338 {
339 }
340
341 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
342 {
343 }
344
345 #endregion 323 #endregion
346 } 324 }
347} 325}
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
index 04328c9..9a3e125 100644
--- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnector.cs
@@ -133,6 +133,36 @@ namespace OpenSim.Groups
133 return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]); 133 return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
134 } 134 }
135 135
136 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
137 {
138 List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
139 if (string.IsNullOrEmpty(query))
140 return hits;
141
142 Dictionary<string, object> sendData = new Dictionary<string, object>();
143 sendData["Query"] = query;
144 sendData["RequestingAgentID"] = RequestingAgentID;
145
146 Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
147
148 if (ret == null)
149 return hits;
150
151 if (!ret.ContainsKey("RESULT"))
152 return hits;
153
154 if (ret["RESULT"].ToString() == "NULL")
155 return hits;
156
157 foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
158 {
159 DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary<string, object>)v);
160 hits.Add(m);
161 }
162
163 return hits;
164 }
165
136 public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) 166 public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
137 { 167 {
138 reason = string.Empty; 168 reason = string.Empty;
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs
index f1cf66c..d3de0e8 100644
--- a/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRemoteConnectorModule.cs
@@ -199,7 +199,7 @@ namespace OpenSim.Groups
199 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search) 199 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
200 { 200 {
201 // TODO! 201 // TODO!
202 return new List<DirGroupsReplyData>(); 202 return m_GroupsService.FindGroups(RequestingAgentID, search);
203 } 203 }
204 204
205 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) 205 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
@@ -406,28 +406,6 @@ namespace OpenSim.Groups
406 }); 406 });
407 } 407 }
408 408
409 public void ResetAgentGroupChatSessions(string agentID)
410 {
411 }
412
413 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
414 {
415 return false;
416 }
417
418 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
419 {
420 return false;
421 }
422
423 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
424 {
425 }
426
427 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
428 {
429 }
430
431 #endregion 409 #endregion
432 } 410 }
433 411
diff --git a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs
index 106c6c4..249d974 100644
--- a/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs
+++ b/OpenSim/Addons/Groups/Remote/GroupsServiceRobustConnector.cs
@@ -133,6 +133,8 @@ namespace OpenSim.Groups
133 return HandleAddNotice(request); 133 return HandleAddNotice(request);
134 case "GETNOTICES": 134 case "GETNOTICES":
135 return HandleGetNotices(request); 135 return HandleGetNotices(request);
136 case "FINDGROUPS":
137 return HandleFindGroups(request);
136 } 138 }
137 m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method); 139 m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method);
138 } 140 }
@@ -740,6 +742,32 @@ namespace OpenSim.Groups
740 return Util.UTF8NoBomEncoding.GetBytes(xmlString); 742 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
741 } 743 }
742 744
745 byte[] HandleFindGroups(Dictionary<string, object> request)
746 {
747 Dictionary<string, object> result = new Dictionary<string, object>();
748
749 if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query"))
750 NullResult(result, "Bad network data");
751
752 List<DirGroupsReplyData> hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString());
753
754 if (hits == null || (hits != null && hits.Count == 0))
755 NullResult(result, "No hits");
756 else
757 {
758 Dictionary<string, object> dict = new Dictionary<string, object>();
759 int i = 0;
760 foreach (DirGroupsReplyData n in hits)
761 dict["n-" + i++] = GroupsDataUtils.DirGroupsReplyData(n);
762
763 result["RESULT"] = dict;
764 }
765
766
767 string xmlString = ServerUtils.BuildXmlResponse(result);
768 return Util.UTF8NoBomEncoding.GetBytes(xmlString);
769 }
770
743 771
744 #region Helpers 772 #region Helpers
745 773
diff --git a/OpenSim/Addons/Groups/Service/GroupsService.cs b/OpenSim/Addons/Groups/Service/GroupsService.cs
index a2ef13a..294b89a 100644
--- a/OpenSim/Addons/Groups/Service/GroupsService.cs
+++ b/OpenSim/Addons/Groups/Service/GroupsService.cs
@@ -255,13 +255,20 @@ namespace OpenSim.Groups
255 return members; 255 return members;
256 List<RoleData> rolesList = new List<RoleData>(roles); 256 List<RoleData> rolesList = new List<RoleData>(roles);
257 257
258 // Is the requester a member of the group? 258 // Check visibility?
259 bool isInGroup = false; 259 // When we don't want to check visibility, we pass it "all" as the requestingAgentID
260 if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null) 260 bool checkVisibility = !RequestingAgentID.Equals("all");
261 isInGroup = true; 261 m_log.DebugFormat("[ZZZ]: AgentID is {0}. checkVisibility is {1}", RequestingAgentID, checkVisibility);
262 if (checkVisibility)
263 {
264 // Is the requester a member of the group?
265 bool isInGroup = false;
266 if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
267 isInGroup = true;
262 268
263 if (!isInGroup) // reduce the roles to the visible ones 269 if (!isInGroup) // reduce the roles to the visible ones
264 rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0); 270 rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
271 }
265 272
266 MembershipData[] datas = m_Database.RetrieveMembers(GroupID); 273 MembershipData[] datas = m_Database.RetrieveMembers(GroupID);
267 if (datas == null || (datas != null && datas.Length == 0)) 274 if (datas == null || (datas != null && datas.Length == 0))
diff --git a/OpenSim/Data/MySQL/MySQLGroupsData.cs b/OpenSim/Data/MySQL/MySQLGroupsData.cs
index 2a1bd6c..0318284 100644
--- a/OpenSim/Data/MySQL/MySQLGroupsData.cs
+++ b/OpenSim/Data/MySQL/MySQLGroupsData.cs
@@ -88,7 +88,7 @@ namespace OpenSim.Data.MySQL
88 if (string.IsNullOrEmpty(pattern)) 88 if (string.IsNullOrEmpty(pattern))
89 pattern = "1 ORDER BY Name LIMIT 100"; 89 pattern = "1 ORDER BY Name LIMIT 100";
90 else 90 else
91 pattern = string.Format("Name LIKE %{0}% ORDER BY Name LIMIT 100", pattern); 91 pattern = string.Format("Name LIKE '%{0}%' ORDER BY Name LIMIT 100", pattern);
92 92
93 return m_Groups.Get(pattern); 93 return m_Groups.Get(pattern);
94 } 94 }
diff --git a/OpenSim/Framework/GridInstantMessage.cs b/OpenSim/Framework/GridInstantMessage.cs
index 6ae0488..da3690c 100644
--- a/OpenSim/Framework/GridInstantMessage.cs
+++ b/OpenSim/Framework/GridInstantMessage.cs
@@ -53,6 +53,24 @@ namespace OpenSim.Framework
53 binaryBucket = new byte[0]; 53 binaryBucket = new byte[0];
54 } 54 }
55 55
56 public GridInstantMessage(GridInstantMessage im, bool addTimestamp)
57 {
58 fromAgentID = im.fromAgentID;
59 fromAgentName = im.fromAgentName;
60 toAgentID = im.toAgentID;
61 dialog = im.dialog;
62 fromGroup = im.fromGroup;
63 message = im.message;
64 imSessionID = im.imSessionID;
65 offline = im.offline;
66 Position = im.Position;
67 binaryBucket = im.binaryBucket;
68 RegionID = im.RegionID;
69
70 if (addTimestamp)
71 timestamp = (uint)Util.UnixTimeSinceEpoch();
72 }
73
56 public GridInstantMessage(IScene scene, UUID _fromAgentID, 74 public GridInstantMessage(IScene scene, UUID _fromAgentID,
57 string _fromAgentName, UUID _toAgentID, 75 string _fromAgentName, UUID _toAgentID,
58 byte _dialog, bool _fromGroup, string _message, 76 byte _dialog, bool _fromGroup, string _message,
diff --git a/OpenSim/Framework/Servers/MainServer.cs b/OpenSim/Framework/Servers/MainServer.cs
index d189580..57931d4 100644
--- a/OpenSim/Framework/Servers/MainServer.cs
+++ b/OpenSim/Framework/Servers/MainServer.cs
@@ -285,7 +285,12 @@ namespace OpenSim.Framework.Servers
285 public static bool RemoveHttpServer(uint port) 285 public static bool RemoveHttpServer(uint port)
286 { 286 {
287 lock (m_Servers) 287 lock (m_Servers)
288 {
289 if (instance != null && instance.Port == port)
290 instance = null;
291
288 return m_Servers.Remove(port); 292 return m_Servers.Remove(port);
293 }
289 } 294 }
290 295
291 /// <summary> 296 /// <summary>
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index e98a470..4272375 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -91,7 +91,6 @@ namespace OpenSim.Region.ClientStack.Linden
91 scene.RegisterModuleInterface<IEventQueue>(this); 91 scene.RegisterModuleInterface<IEventQueue>(this);
92 92
93 scene.EventManager.OnClientClosed += ClientClosed; 93 scene.EventManager.OnClientClosed += ClientClosed;
94 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
95 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 94 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
96 95
97 MainConsole.Instance.Commands.AddCommand( 96 MainConsole.Instance.Commands.AddCommand(
@@ -120,7 +119,6 @@ namespace OpenSim.Region.ClientStack.Linden
120 return; 119 return;
121 120
122 scene.EventManager.OnClientClosed -= ClientClosed; 121 scene.EventManager.OnClientClosed -= ClientClosed;
123 scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
124 scene.EventManager.OnRegisterCaps -= OnRegisterCaps; 122 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
125 123
126 scene.UnregisterModuleInterface<IEventQueue>(this); 124 scene.UnregisterModuleInterface<IEventQueue>(this);
@@ -189,14 +187,12 @@ namespace OpenSim.Region.ClientStack.Linden
189 { 187 {
190 if (!queues.ContainsKey(agentId)) 188 if (!queues.ContainsKey(agentId))
191 { 189 {
192 /*
193 m_log.DebugFormat( 190 m_log.DebugFormat(
194 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", 191 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
195 agentId, m_scene.RegionInfo.RegionName); 192 agentId, m_scene.RegionInfo.RegionName);
196 */
197 queues[agentId] = new Queue<OSD>(); 193 queues[agentId] = new Queue<OSD>();
198 } 194 }
199 195
200 return queues[agentId]; 196 return queues[agentId];
201 } 197 }
202 } 198 }
@@ -228,8 +224,12 @@ namespace OpenSim.Region.ClientStack.Linden
228 { 224 {
229 Queue<OSD> queue = GetQueue(avatarID); 225 Queue<OSD> queue = GetQueue(avatarID);
230 if (queue != null) 226 if (queue != null)
227 {
231 lock (queue) 228 lock (queue)
232 queue.Enqueue(ev); 229 queue.Enqueue(ev);
230 }
231 else
232 m_log.WarnFormat("[EVENTQUEUE]: (Enqueue) No queue found for agent {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName);
233 } 233 }
234 catch (NullReferenceException e) 234 catch (NullReferenceException e)
235 { 235 {
@@ -244,48 +244,15 @@ namespace OpenSim.Region.ClientStack.Linden
244 244
245 private void ClientClosed(UUID agentID, Scene scene) 245 private void ClientClosed(UUID agentID, Scene scene)
246 { 246 {
247// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 247 //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
248
249 int count = 0;
250 while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
251 {
252 Thread.Sleep(1000);
253 }
254 248
255 lock (queues) 249 lock (queues)
256 {
257 queues.Remove(agentID); 250 queues.Remove(agentID);
258 }
259 251
260 List<UUID> removeitems = new List<UUID>(); 252 List<UUID> removeitems = new List<UUID>();
261 lock (m_AvatarQueueUUIDMapping) 253 lock (m_AvatarQueueUUIDMapping)
262 m_AvatarQueueUUIDMapping.Remove(agentID); 254 m_AvatarQueueUUIDMapping.Remove(agentID);
263 255
264// lock (m_AvatarQueueUUIDMapping)
265// {
266// foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
267// {
268//// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
269// if (ky == agentID)
270// {
271// removeitems.Add(ky);
272// }
273// }
274//
275// foreach (UUID ky in removeitems)
276// {
277// UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
278// m_AvatarQueueUUIDMapping.Remove(ky);
279//
280// string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
281// MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
282//
283//// m_log.DebugFormat(
284//// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
285//// eqgPath, agentID, m_scene.RegionInfo.RegionName);
286// }
287// }
288
289 UUID searchval = UUID.Zero; 256 UUID searchval = UUID.Zero;
290 257
291 removeitems.Clear(); 258 removeitems.Clear();
@@ -305,19 +272,9 @@ namespace OpenSim.Region.ClientStack.Linden
305 foreach (UUID ky in removeitems) 272 foreach (UUID ky in removeitems)
306 m_QueueUUIDAvatarMapping.Remove(ky); 273 m_QueueUUIDAvatarMapping.Remove(ky);
307 } 274 }
308 }
309 275
310 private void MakeChildAgent(ScenePresence avatar) 276 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
311 { 277
312 //m_log.DebugFormat("[EVENTQUEUE]: Make Child agent {0} in region {1}.", avatar.UUID, m_scene.RegionInfo.RegionName);
313 //lock (m_ids)
314 // {
315 //if (m_ids.ContainsKey(avatar.UUID))
316 //{
317 // close the event queue.
318 //m_ids[avatar.UUID] = -1;
319 //}
320 //}
321 } 278 }
322 279
323 /// <summary> 280 /// <summary>
@@ -417,7 +374,12 @@ namespace OpenSim.Region.ClientStack.Linden
417 if (DebugLevel >= 2) 374 if (DebugLevel >= 2)
418 m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); 375 m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
419 376
420 Queue<OSD> queue = TryGetQueue(pAgentId); 377 Queue<OSD> queue = GetQueue(pAgentId);
378 if (queue == null)
379 {
380 return NoEvents(requestID, pAgentId);
381 }
382
421 OSD element; 383 OSD element;
422 lock (queue) 384 lock (queue)
423 { 385 {
@@ -788,12 +750,12 @@ namespace OpenSim.Region.ClientStack.Linden
788 750
789 } 751 }
790 752
791 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, 753 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
792 bool isModerator, bool textMute) 754 bool isModerator, bool textMute)
793 { 755 {
794 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, 756 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
795 isModerator, textMute); 757 isModerator, textMute);
796 Enqueue(item, toAgent); 758 Enqueue(item, fromAgent);
797 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); 759 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
798 } 760 }
799 761
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 8f9b17e..7c8c189 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -38,6 +38,8 @@ using NUnit.Framework;
38using OpenMetaverse; 38using OpenMetaverse;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Framework.Communications; 40using OpenSim.Framework.Communications;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Region.CoreModules.Avatar.Attachments; 43using OpenSim.Region.CoreModules.Avatar.Attachments;
42using OpenSim.Region.CoreModules.Framework; 44using OpenSim.Region.CoreModules.Framework;
43using OpenSim.Region.CoreModules.Framework.EntityTransfer; 45using OpenSim.Region.CoreModules.Framework.EntityTransfer;
@@ -802,6 +804,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
802 TestHelpers.InMethod(); 804 TestHelpers.InMethod();
803// TestHelpers.EnableLogging(); 805// TestHelpers.EnableLogging();
804 806
807 BaseHttpServer httpServer = new BaseHttpServer(99999);
808 MainServer.AddHttpServer(httpServer);
809 MainServer.Instance = httpServer;
810
805 AttachmentsModule attModA = new AttachmentsModule(); 811 AttachmentsModule attModA = new AttachmentsModule();
806 AttachmentsModule attModB = new AttachmentsModule(); 812 AttachmentsModule attModB = new AttachmentsModule();
807 EntityTransferModule etmA = new EntityTransferModule(); 813 EntityTransferModule etmA = new EntityTransferModule();
@@ -830,6 +836,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
830 SceneHelpers.SetupSceneModules( 836 SceneHelpers.SetupSceneModules(
831 sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); 837 sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
832 838
839 // FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
840 lscm.ServiceVersion = "SIMULATION/0.1";
841
833 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); 842 UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
834 843
835 AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); 844 AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
index 1627f6c..b321adb 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs
@@ -392,7 +392,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
392 gim.fromAgentName = fromAgentName; 392 gim.fromAgentName = fromAgentName;
393 gim.fromGroup = fromGroup; 393 gim.fromGroup = fromGroup;
394 gim.imSessionID = imSessionID.Guid; 394 gim.imSessionID = imSessionID.Guid;
395 gim.RegionID = UUID.Zero.Guid; // RegionID.Guid; 395 gim.RegionID = RegionID.Guid;
396 gim.timestamp = timestamp; 396 gim.timestamp = timestamp;
397 gim.toAgentID = toAgentID.Guid; 397 gim.toAgentID = toAgentID.Guid;
398 gim.message = message; 398 gim.message = message;
@@ -728,7 +728,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
728 gim["position_x"] = msg.Position.X.ToString(); 728 gim["position_x"] = msg.Position.X.ToString();
729 gim["position_y"] = msg.Position.Y.ToString(); 729 gim["position_y"] = msg.Position.Y.ToString();
730 gim["position_z"] = msg.Position.Z.ToString(); 730 gim["position_z"] = msg.Position.Z.ToString();
731 gim["region_id"] = msg.RegionID.ToString(); 731 gim["region_id"] = new UUID(msg.RegionID).ToString();
732 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); 732 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
733 if (m_MessageKey != String.Empty) 733 if (m_MessageKey != String.Empty)
734 gim["message_key"] = m_MessageKey; 734 gim["message_key"] = m_MessageKey;
diff --git a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
index 0c759df..de8925d 100644
--- a/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/Caps/CapabilitiesModule.cs
@@ -133,13 +133,9 @@ namespace OpenSim.Region.CoreModules.Framework
133 { 133 {
134 Caps oldCaps = m_capsObjects[circuitCode]; 134 Caps oldCaps = m_capsObjects[circuitCode];
135 135
136 m_log.DebugFormat( 136 //m_log.WarnFormat(
137 "[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", 137 // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
138 agentId, oldCaps.CapsObjectPath, capsObjectPath); 138 // agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
139 // This should not happen. The caller code is confused. We need to fix that.
140 // CAPs can never be reregistered, or the client will be confused.
141 // Hence this return here.
142 //return;
143 } 139 }
144 140
145 caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, 141 caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
@@ -153,6 +149,7 @@ namespace OpenSim.Region.CoreModules.Framework
153 149
154 public void RemoveCaps(UUID agentId, uint circuitCode) 150 public void RemoveCaps(UUID agentId, uint circuitCode)
155 { 151 {
152 m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName);
156 lock (m_childrenSeeds) 153 lock (m_childrenSeeds)
157 { 154 {
158 if (m_childrenSeeds.ContainsKey(agentId)) 155 if (m_childrenSeeds.ContainsKey(agentId))
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index 29b4296..df95bf0 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -316,7 +316,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
316 m_log.DebugFormat( 316 m_log.DebugFormat(
317 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", 317 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
318 sp.Name, sp.UUID, position, regionHandle); 318 sp.Name, sp.UUID, position, regionHandle);
319 319
320 sp.ControllingClient.SendTeleportFailed("Slow down!");
320 return; 321 return;
321 } 322 }
322 323
@@ -921,13 +922,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
921 922
922 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 923 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
923 { 924 {
924 // RED ALERT!!!! 925 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
925 // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. 926 // they regard the new region as the current region after receiving the AgentMovementComplete
926 // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion 927 // response. If close is sent before then, it will cause the viewer to quit instead.
927 // BEFORE THEY SETTLE IN THE NEW REGION. 928 //
928 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR 929 // This sleep can be increased if necessary. However, whilst it's active,
929 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. 930 // an agent cannot teleport back to this region if it has teleported away.
930 Thread.Sleep(5000); 931 Thread.Sleep(2000);
931 932
932 sp.Scene.IncomingCloseAgent(sp.UUID, false); 933 sp.Scene.IncomingCloseAgent(sp.UUID, false);
933 } 934 }
@@ -1045,21 +1046,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1045 // Now let's make it officially a child agent 1046 // Now let's make it officially a child agent
1046 sp.MakeChildAgent(); 1047 sp.MakeChildAgent();
1047 1048
1048 // OK, it got this agent. Let's close some child agents
1049 sp.CloseChildAgents(newRegionX, newRegionY);
1050
1051 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 1049 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
1052 1050
1053 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 1051 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
1054 { 1052 {
1053 sp.DoNotCloseAfterTeleport = false;
1054
1055 // RED ALERT!!!! 1055 // RED ALERT!!!!
1056 // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. 1056 // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
1057 // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion 1057 // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
1058 // BEFORE THEY SETTLE IN THE NEW REGION. 1058 // BEFORE THEY SETTLE IN THE NEW REGION.
1059 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR 1059 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
1060 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. 1060 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
1061 Thread.Sleep(5000); 1061 Thread.Sleep(15000);
1062 sp.Scene.IncomingCloseAgent(sp.UUID, false); 1062
1063 if (!sp.DoNotCloseAfterTeleport)
1064 {
1065 // OK, it got this agent. Let's close everything
1066 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.RegionInfo.RegionName);
1067 sp.CloseChildAgents(newRegionX, newRegionY);
1068 sp.Scene.IncomingCloseAgent(sp.UUID, false);
1069
1070 }
1071 else
1072 {
1073 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.RegionInfo.RegionName);
1074 sp.DoNotCloseAfterTeleport = false;
1075 }
1063 } 1076 }
1064 else 1077 else
1065 // now we have a child agent in this region. 1078 // now we have a child agent in this region.
diff --git a/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
new file mode 100644
index 0000000..8838612
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/Search/BasicSearchModule.cs
@@ -0,0 +1,197 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.IO;
30using System.Reflection;
31using System.Threading;
32
33using OpenSim.Framework;
34using OpenSim.Framework.Console;
35using OpenSim.Framework.Monitoring;
36using OpenSim.Region.ClientStack.LindenUDP;
37using OpenSim.Region.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42
43using OpenMetaverse;
44using OpenMetaverse.Packets;
45using log4net;
46using Nini.Config;
47using Mono.Addins;
48
49using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
50
51namespace OpenSim.Region.CoreModules.Framework.Search
52{
53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicSearchModule")]
54 public class BasicSearchModule : ISharedRegionModule
55 {
56 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57
58 protected bool m_Enabled;
59 protected List<Scene> m_Scenes = new List<Scene>();
60
61 private IGroupsModule m_GroupsService = null;
62
63 #region ISharedRegionModule
64
65 public void Initialise(IConfigSource config)
66 {
67 string umanmod = config.Configs["Modules"].GetString("SearchModule", Name);
68 if (umanmod == Name)
69 {
70 m_Enabled = true;
71 m_log.DebugFormat("[BASIC SEARCH MODULE]: {0} is enabled", Name);
72 }
73 }
74
75 public bool IsSharedModule
76 {
77 get { return true; }
78 }
79
80 public virtual string Name
81 {
82 get { return "BasicSearchModule"; }
83 }
84
85 public Type ReplaceableInterface
86 {
87 get { return null; }
88 }
89
90 public void AddRegion(Scene scene)
91 {
92 if (m_Enabled)
93 {
94 m_Scenes.Add(scene);
95
96 scene.EventManager.OnMakeRootAgent += new Action<ScenePresence>(EventManager_OnMakeRootAgent);
97 scene.EventManager.OnMakeChildAgent += new EventManager.OnMakeChildAgentDelegate(EventManager_OnMakeChildAgent);
98 }
99 }
100
101 public void RemoveRegion(Scene scene)
102 {
103 if (m_Enabled)
104 {
105 m_Scenes.Remove(scene);
106
107 scene.EventManager.OnMakeRootAgent -= new Action<ScenePresence>(EventManager_OnMakeRootAgent);
108 scene.EventManager.OnMakeChildAgent -= new EventManager.OnMakeChildAgentDelegate(EventManager_OnMakeChildAgent);
109 }
110 }
111
112 public void RegionLoaded(Scene s)
113 {
114 if (!m_Enabled)
115 return;
116
117 if (m_GroupsService == null)
118 {
119 m_GroupsService = s.RequestModuleInterface<IGroupsModule>();
120
121 // No Groups Service Connector, then group search won't work...
122 if (m_GroupsService == null)
123 m_log.Warn("[BASIC SEARCH MODULE]: Could not get IGroupsModule");
124 }
125 }
126
127 public void PostInitialise()
128 {
129 }
130
131 public void Close()
132 {
133 m_Scenes.Clear();
134 }
135
136 #endregion ISharedRegionModule
137
138
139 #region Event Handlers
140
141 void EventManager_OnMakeRootAgent(ScenePresence sp)
142 {
143 sp.ControllingClient.OnDirFindQuery += OnDirFindQuery;
144 }
145
146 void EventManager_OnMakeChildAgent(ScenePresence sp)
147 {
148 sp.ControllingClient.OnDirFindQuery -= OnDirFindQuery;
149 }
150
151 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
152 {
153 if (((DirFindFlags)queryFlags & DirFindFlags.People) == DirFindFlags.People)
154 {
155 if (string.IsNullOrEmpty(queryText))
156 remoteClient.SendDirPeopleReply(queryID, new DirPeopleReplyData[0]);
157
158 List<UserAccount> accounts = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, queryText);
159 DirPeopleReplyData[] hits = new DirPeopleReplyData[accounts.Count];
160 int i = 0;
161 foreach (UserAccount acc in accounts)
162 {
163 DirPeopleReplyData d = new DirPeopleReplyData();
164 d.agentID = acc.PrincipalID;
165 d.firstName = acc.FirstName;
166 d.lastName = acc.LastName;
167 d.online = false;
168
169 hits[i++] = d;
170 }
171
172 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
173 remoteClient.SendDirPeopleReply(queryID, hits);
174 }
175 else if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
176 {
177 if (m_GroupsService == null)
178 {
179 m_log.Warn("[BASIC SEARCH MODULE]: Groups service is not available. Unable to search groups.");
180 remoteClient.SendAlertMessage("Groups search is not enabled");
181 return;
182 }
183
184 if (string.IsNullOrEmpty(queryText))
185 remoteClient.SendDirGroupsReply(queryID, new DirGroupsReplyData[0]);
186
187 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
188 remoteClient.SendDirGroupsReply(queryID, m_GroupsService.FindGroups(remoteClient, queryText).ToArray());
189 }
190
191 }
192
193 #endregion Event Handlers
194
195 }
196
197} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 53bd2e2..7adb203 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -46,6 +46,8 @@ using log4net;
46using Nini.Config; 46using Nini.Config;
47using Mono.Addins; 47using Mono.Addins;
48 48
49using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
50
49namespace OpenSim.Region.CoreModules.Framework.UserManagement 51namespace OpenSim.Region.CoreModules.Framework.UserManagement
50{ 52{
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")] 53 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")]
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
index 39657a3..a5adc29 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs
@@ -46,9 +46,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 /// <summary> 48 /// <summary>
49 /// Version of this service 49 /// Version of this service.
50 /// </summary> 50 /// </summary>
51 private const string m_Version = "SIMULATION/0.2"; 51 /// <remarks>
52 /// Currently valid versions are "SIMULATION/0.1" and "SIMULATION/0.2"
53 /// </remarks>
54 public string ServiceVersion { get; set; }
52 55
53 /// <summary> 56 /// <summary>
54 /// Map region ID to scene. 57 /// Map region ID to scene.
@@ -60,6 +63,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
60 /// </summary> 63 /// </summary>
61 private bool m_ModuleEnabled = false; 64 private bool m_ModuleEnabled = false;
62 65
66 public LocalSimulationConnectorModule()
67 {
68 ServiceVersion = "SIMULATION/0.2";
69 }
70
63 #region Region Module interface 71 #region Region Module interface
64 72
65 public void Initialise(IConfigSource config) 73 public void Initialise(IConfigSource config)
@@ -253,7 +261,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
253 public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) 261 public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
254 { 262 {
255 reason = "Communications failure"; 263 reason = "Communications failure";
256 version = m_Version; 264 version = ServiceVersion;
257 if (destination == null) 265 if (destination == null)
258 return false; 266 return false;
259 267
@@ -358,4 +366,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
358 366
359 #endregion 367 #endregion
360 } 368 }
361} 369} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
index 5512642..3780ece 100644
--- a/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEventQueue.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Region.Framework.Interfaces
53 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, 53 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
54 uint timeStamp, bool offline, int parentEstateID, Vector3 position, 54 uint timeStamp, bool offline, int parentEstateID, Vector3 position,
55 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); 55 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket);
56 void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, 56 void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
57 bool isModerator, bool textMute); 57 bool isModerator, bool textMute);
58 void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); 58 void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID);
59 void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID); 59 void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID);
diff --git a/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs b/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
index 6885327..9ae5e87 100644
--- a/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IGroupsModule.cs
@@ -97,5 +97,7 @@ namespace OpenSim.Region.Framework.Interfaces
97 void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InviteeID, UUID RoleID); 97 void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InviteeID, UUID RoleID);
98 void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID GroupID, UUID InviteeID, UUID RoleID); 98 void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID GroupID, UUID InviteeID, UUID RoleID);
99 void NotifyChange(UUID GroupID); 99 void NotifyChange(UUID GroupID);
100
101 List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query);
100 } 102 }
101} \ No newline at end of file 103} \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 96e45ed..0d9028c 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2955,6 +2955,7 @@ namespace OpenSim.Region.Framework.Scenes
2955 { 2955 {
2956 ScenePresence sp; 2956 ScenePresence sp;
2957 bool vialogin; 2957 bool vialogin;
2958 bool reallyNew = true;
2958 2959
2959 // Validation occurs in LLUDPServer 2960 // Validation occurs in LLUDPServer
2960 // 2961 //
@@ -3013,6 +3014,7 @@ namespace OpenSim.Region.Framework.Scenes
3013 m_log.WarnFormat( 3014 m_log.WarnFormat(
3014 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 3015 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
3015 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 3016 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
3017 reallyNew = false;
3016 } 3018 }
3017 3019
3018 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 3020 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
@@ -3024,7 +3026,9 @@ namespace OpenSim.Region.Framework.Scenes
3024 // places. However, we still need to do it here for NPCs. 3026 // places. However, we still need to do it here for NPCs.
3025 CacheUserName(sp, aCircuit); 3027 CacheUserName(sp, aCircuit);
3026 3028
3027 EventManager.TriggerOnNewClient(client); 3029 if (reallyNew)
3030 EventManager.TriggerOnNewClient(client);
3031
3028 if (vialogin) 3032 if (vialogin)
3029 EventManager.TriggerOnClientLogin(client); 3033 EventManager.TriggerOnClientLogin(client);
3030 } 3034 }
@@ -3583,15 +3587,8 @@ namespace OpenSim.Region.Framework.Scenes
3583 if (closeChildAgents && isChildAgent) 3587 if (closeChildAgents && isChildAgent)
3584 { 3588 {
3585 // Tell a single agent to disconnect from the region. 3589 // Tell a single agent to disconnect from the region.
3586 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3590 // Let's do this via UDP
3587 if (eq != null) 3591 avatar.ControllingClient.SendShutdownConnectionNotice();
3588 {
3589 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3590 }
3591 else
3592 {
3593 avatar.ControllingClient.SendShutdownConnectionNotice();
3594 }
3595 } 3592 }
3596 3593
3597 // Only applies to root agents. 3594 // Only applies to root agents.
@@ -3834,42 +3831,40 @@ namespace OpenSim.Region.Framework.Scenes
3834 return false; 3831 return false;
3835 } 3832 }
3836 3833
3837 ScenePresence sp = GetScenePresence(agent.AgentID); 3834 lock (agent)
3838
3839 // If we have noo presence here or if that presence is a zombie root
3840 // presence that will be kicled, we need a new CAPS object.
3841 if (sp == null || (sp != null && !sp.IsChildAgent))
3842 { 3835 {
3843 if (CapsModule != null) 3836 ScenePresence sp = GetScenePresence(agent.AgentID);
3837
3838 if (sp != null)
3844 { 3839 {
3845 lock (agent) 3840 if (!sp.IsChildAgent)
3846 { 3841 {
3847 CapsModule.SetAgentCapsSeeds(agent); 3842 // We have a root agent. Is it in transit?
3848 CapsModule.CreateCaps(agent.AgentID, agent.circuitcode); 3843 if (!EntityTransferModule.IsInTransit(sp.UUID))
3849 } 3844 {
3850 } 3845 // We have a zombie from a crashed session.
3851 } 3846 // Or the same user is trying to be root twice here, won't work.
3847 // Kill it.
3848 m_log.WarnFormat(
3849 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3850 sp.Name, sp.UUID, RegionInfo.RegionName);
3852 3851
3853 if (sp != null) 3852 if (sp.ControllingClient != null)
3854 { 3853 sp.ControllingClient.Close(true, true);
3855 if (!sp.IsChildAgent)
3856 {
3857 // We have a zombie from a crashed session.
3858 // Or the same user is trying to be root twice here, won't work.
3859 // Kill it.
3860 m_log.WarnFormat(
3861 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3862 sp.Name, sp.UUID, RegionInfo.RegionName);
3863
3864 if (sp.ControllingClient != null)
3865 sp.ControllingClient.Close(true, true);
3866 3854
3867 sp = null; 3855 sp = null;
3856 }
3857 //else
3858 // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName);
3859 }
3860 else
3861 {
3862 // We have a child agent here
3863 sp.DoNotCloseAfterTeleport = true;
3864 //m_log.WarnFormat("[SCENE]: Existing child scene presence for {0} {1} in {2}", sp.Name, sp.UUID, RegionInfo.RegionName);
3865 }
3868 } 3866 }
3869 }
3870 3867
3871 lock (agent)
3872 {
3873 // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags. 3868 // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags.
3874 // We need the circuit data here for some of the subsequent checks. (groups, for example) 3869 // We need the circuit data here for some of the subsequent checks. (groups, for example)
3875 // If the checks fail, we remove the circuit. 3870 // If the checks fail, we remove the circuit.
@@ -3950,7 +3945,10 @@ namespace OpenSim.Region.Framework.Scenes
3950 sp.AdjustKnownSeeds(); 3945 sp.AdjustKnownSeeds();
3951 3946
3952 if (CapsModule != null) 3947 if (CapsModule != null)
3948 {
3953 CapsModule.SetAgentCapsSeeds(agent); 3949 CapsModule.SetAgentCapsSeeds(agent);
3950 CapsModule.CreateCaps(agent.AgentID, agent.circuitcode);
3951 }
3954 } 3952 }
3955 } 3953 }
3956 3954
@@ -5829,17 +5827,6 @@ Environment.Exit(1);
5829 { 5827 {
5830 reason = "You are banned from the region"; 5828 reason = "You are banned from the region";
5831 5829
5832 if (EntityTransferModule.IsInTransit(agentID))
5833 {
5834 reason = "Agent is still in transit from this region";
5835
5836 m_log.WarnFormat(
5837 "[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit",
5838 agentID, RegionInfo.RegionName);
5839
5840 return false;
5841 }
5842
5843 if (Permissions.IsGod(agentID)) 5830 if (Permissions.IsGod(agentID))
5844 { 5831 {
5845 reason = String.Empty; 5832 reason = String.Empty;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c78fe62..c4876b3 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -764,6 +764,13 @@ namespace OpenSim.Region.Framework.Scenes
764 } 764 }
765 } 765 }
766 766
767 /// <summary>
768 /// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
769 /// teleport is reusing the connection.
770 /// </summary>
771 /// <remarks>May be refactored or move somewhere else soon.</remarks>
772 public bool DoNotCloseAfterTeleport { get; set; }
773
767 private float m_speedModifier = 1.0f; 774 private float m_speedModifier = 1.0f;
768 775
769 public float SpeedModifier 776 public float SpeedModifier
@@ -1541,11 +1548,13 @@ namespace OpenSim.Region.Framework.Scenes
1541 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); 1548 client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
1542 1549
1543 // Make sure it's not a login agent. We don't want to wait for updates during login 1550 // Make sure it's not a login agent. We don't want to wait for updates during login
1544 if ((m_teleportFlags & TeleportFlags.ViaLogin) == 0) 1551 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
1552 {
1545 // Let's wait until UpdateAgent (called by departing region) is done 1553 // Let's wait until UpdateAgent (called by departing region) is done
1546 if (!WaitForUpdateAgent(client)) 1554 if (!WaitForUpdateAgent(client))
1547 // The sending region never sent the UpdateAgent data, we have to refuse 1555 // The sending region never sent the UpdateAgent data, we have to refuse
1548 return; 1556 return;
1557 }
1549 1558
1550 Vector3 look = Velocity; 1559 Vector3 look = Velocity;
1551 1560
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
index bbfbbfc..bbe34d2 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs
@@ -119,7 +119,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
119 119
120 UUID spUuid = TestHelpers.ParseTail(0x1); 120 UUID spUuid = TestHelpers.ParseTail(0x1);
121 121
122 // The etm is only invoked by this test to check whether an agent is still in transit if there is a dupe
123 EntityTransferModule etm = new EntityTransferModule();
124
125 IConfigSource config = new IniConfigSource();
126 IConfig modulesConfig = config.AddConfig("Modules");
127 modulesConfig.Set("EntityTransferModule", etm.Name);
128 IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
129
130 // In order to run a single threaded regression test we do not want the entity transfer module waiting
131 // for a callback from the destination scene before removing its avatar data.
132 entityTransferConfig.Set("wait_for_callback", false);
133
122 TestScene scene = new SceneHelpers().SetupScene(); 134 TestScene scene = new SceneHelpers().SetupScene();
135 SceneHelpers.SetupSceneModules(scene, config, etm);
123 SceneHelpers.AddScenePresence(scene, spUuid); 136 SceneHelpers.AddScenePresence(scene, spUuid);
124 SceneHelpers.AddScenePresence(scene, spUuid); 137 SceneHelpers.AddScenePresence(scene, spUuid);
125 138
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index 297c66b..afd2779 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -136,6 +136,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
136 SceneHelpers.SetupSceneModules(sceneB, config, etmB); 136 SceneHelpers.SetupSceneModules(sceneB, config, etmB);
137 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); 137 SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
138 138
139 // FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
140 lscm.ServiceVersion = "SIMULATION/0.1";
141
139 Vector3 teleportPosition = new Vector3(10, 11, 12); 142 Vector3 teleportPosition = new Vector3(10, 11, 12);
140 Vector3 teleportLookAt = new Vector3(20, 21, 22); 143 Vector3 teleportLookAt = new Vector3(20, 21, 22);
141 144
@@ -454,6 +457,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
454 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); 457 SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
455 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); 458 SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
456 459
460 // FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
461 lscm.ServiceVersion = "SIMULATION/0.1";
462
457 Vector3 teleportPosition = new Vector3(10, 11, 12); 463 Vector3 teleportPosition = new Vector3(10, 11, 12);
458 Vector3 teleportLookAt = new Vector3(20, 21, 22); 464 Vector3 teleportLookAt = new Vector3(20, 21, 22);
459 465
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 0cec959..2b33084 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -326,15 +326,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
326 "ParcelVoiceInfoRequest", 326 "ParcelVoiceInfoRequest",
327 agentID.ToString())); 327 agentID.ToString()));
328 328
329 caps.RegisterHandler( 329 //caps.RegisterHandler(
330 "ChatSessionRequest", 330 // "ChatSessionRequest",
331 new RestStreamHandler( 331 // new RestStreamHandler(
332 "POST", 332 // "POST",
333 capsBase + m_chatSessionRequestPath, 333 // capsBase + m_chatSessionRequestPath,
334 (request, path, param, httpRequest, httpResponse) 334 // (request, path, param, httpRequest, httpResponse)
335 => ChatSessionRequest(scene, request, path, param, agentID, caps), 335 // => ChatSessionRequest(scene, request, path, param, agentID, caps),
336 "ChatSessionRequest", 336 // "ChatSessionRequest",
337 agentID.ToString())); 337 // agentID.ToString()));
338 } 338 }
339 339
340 /// <summary> 340 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
index 2f07c42..349c0d0 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -433,15 +433,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
433 "ParcelVoiceInfoRequest", 433 "ParcelVoiceInfoRequest",
434 agentID.ToString())); 434 agentID.ToString()));
435 435
436 caps.RegisterHandler( 436 //caps.RegisterHandler(
437 "ChatSessionRequest", 437 // "ChatSessionRequest",
438 new RestStreamHandler( 438 // new RestStreamHandler(
439 "POST", 439 // "POST",
440 capsBase + m_chatSessionRequestPath, 440 // capsBase + m_chatSessionRequestPath,
441 (request, path, param, httpRequest, httpResponse) 441 // (request, path, param, httpRequest, httpResponse)
442 => ChatSessionRequest(scene, request, path, param, agentID, caps), 442 // => ChatSessionRequest(scene, request, path, param, agentID, caps),
443 "ChatSessionRequest", 443 // "ChatSessionRequest",
444 agentID.ToString())); 444 // agentID.ToString()));
445 } 445 }
446 446
447 /// <summary> 447 /// <summary>
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index d0a5989..e0f061b 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -250,7 +250,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
250 250
251 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; 251 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
252 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 252 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
253 client.OnDirFindQuery += OnDirFindQuery;
254 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 253 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
255 254
256 // Used for Notices and Group Invites/Accept/Reject 255 // Used for Notices and Group Invites/Accept/Reject
@@ -303,21 +302,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
303 } 302 }
304 */ 303 */
305 304
306 void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
307 {
308 if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
309 {
310 if (m_debugEnabled)
311 m_log.DebugFormat(
312 "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
313 System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
314
315 // TODO: This currently ignores pretty much all the query flags including Mature and sort order
316 remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray());
317 }
318
319 }
320
321 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) 305 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
322 { 306 {
323 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 307 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -1178,6 +1162,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1178 } 1162 }
1179 } 1163 }
1180 1164
1165 public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
1166 {
1167 return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query);
1168 }
1169
1170
1181 #endregion 1171 #endregion
1182 1172
1183 #region Client/Update Tools 1173 #region Client/Update Tools
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 34362af..20c178c 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -155,7 +155,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
155 public void TestCreateWithAttachments() 155 public void TestCreateWithAttachments()
156 { 156 {
157 TestHelpers.InMethod(); 157 TestHelpers.InMethod();
158// log4net.Config.XmlConfigurator.Configure(); 158// TestHelpers.EnableLogging();
159 159
160 UUID userId = TestHelpers.ParseTail(0x1); 160 UUID userId = TestHelpers.ParseTail(0x1);
161 UserAccountHelpers.CreateUserWithInventory(m_scene, userId); 161 UserAccountHelpers.CreateUserWithInventory(m_scene, userId);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
index 74f010e..495e684 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
@@ -180,6 +180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
180 public void TestOsNpcLoadAppearance() 180 public void TestOsNpcLoadAppearance()
181 { 181 {
182 TestHelpers.InMethod(); 182 TestHelpers.InMethod();
183 //TestHelpers.EnableLogging();
183 184
184 // Store an avatar with a different height from default in a notecard. 185 // Store an avatar with a different height from default in a notecard.
185 UUID userId = TestHelpers.ParseTail(0x1); 186 UUID userId = TestHelpers.ParseTail(0x1);
diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
index dbce9f6..e19c23d 100644
--- a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
+++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Services.Connectors.InstantMessage
123 gim["position_z"] = msg.Position.Z.ToString(); 123 gim["position_z"] = msg.Position.Z.ToString();
124 gim["region_id"] = msg.RegionID.ToString(); 124 gim["region_id"] = msg.RegionID.ToString();
125 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None); 125 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None);
126 gim["region_id"] = new UUID(msg.RegionID).ToString();
126 127
127 return gim; 128 return gim;
128 } 129 }
diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs
index a85ee70..9ba5dab 100644
--- a/OpenSim/Services/MapImageService/MapImageService.cs
+++ b/OpenSim/Services/MapImageService/MapImageService.cs
@@ -86,7 +86,7 @@ namespace OpenSim.Services.MapImageService
86 { 86 {
87 Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); 87 Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH);
88 FillImage(waterTile, m_Watercolor); 88 FillImage(waterTile, m_Watercolor);
89 waterTile.Save(m_WaterTileFile); 89 waterTile.Save(m_WaterTileFile, ImageFormat.Jpeg);
90 } 90 }
91 } 91 }
92 } 92 }
diff --git a/OpenSim/Tests/Common/OpenSimTestCase.cs b/OpenSim/Tests/Common/OpenSimTestCase.cs
index 8c40923..3c47faa 100644
--- a/OpenSim/Tests/Common/OpenSimTestCase.cs
+++ b/OpenSim/Tests/Common/OpenSimTestCase.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using NUnit.Framework; 29using NUnit.Framework;
30using OpenSim.Framework.Servers;
30 31
31namespace OpenSim.Tests.Common 32namespace OpenSim.Tests.Common
32{ 33{
@@ -40,7 +41,14 @@ namespace OpenSim.Tests.Common
40 // Disable logging for each test so that one where logging is enabled doesn't cause all subsequent tests 41 // Disable logging for each test so that one where logging is enabled doesn't cause all subsequent tests
41 // to have logging on if it failed with an exception. 42 // to have logging on if it failed with an exception.
42 TestHelpers.DisableLogging(); 43 TestHelpers.DisableLogging();
44
45 // This is an unfortunate bit of clean up we have to do because MainServer manages things through static
46 // variables and the VM is not restarted between tests.
47 if (MainServer.Instance != null)
48 {
49 MainServer.RemoveHttpServer(MainServer.Instance.Port);
50// MainServer.Instance = null;
51 }
43 } 52 }
44 } 53 }
45} 54} \ No newline at end of file
46