Merge branch 'master' into careminster

Conflicts:
	OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
	OpenSim/Region/Framework/Scenes/Scene.cs
avinationmerge
Melanie 2013-07-29 02:08:05 +01:00
commit bf283208df
42 changed files with 857 additions and 415 deletions

View File

@ -65,6 +65,7 @@ what it is today.
* A_Biondi * A_Biondi
* alex_carnell * alex_carnell
* Alan Webb (IBM) * Alan Webb (IBM)
* Aleric
* Allen Kerensky * Allen Kerensky
* BigFootAg * BigFootAg
* BlueWall Slade * BlueWall Slade

View File

@ -504,6 +504,30 @@ namespace OpenSim.Groups
return notice; return notice;
} }
public static Dictionary<string, object> DirGroupsReplyData(DirGroupsReplyData g)
{
Dictionary<string, object> dict = new Dictionary<string, object>();
dict["GroupID"] = g.groupID;
dict["Name"] = g.groupName;
dict["NMembers"] = g.members;
dict["SearchOrder"] = g.searchOrder;
return dict;
}
public static DirGroupsReplyData DirGroupsReplyData(Dictionary<string, object> dict)
{
DirGroupsReplyData g;
g.groupID = new UUID(dict["GroupID"].ToString());
g.groupName = dict["Name"].ToString();
Int32.TryParse(dict["NMembers"].ToString(), out g.members);
float.TryParse(dict["SearchOrder"].ToString(), out g.searchOrder);
return g;
}
} }
} }

View File

@ -39,6 +39,7 @@ using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo; using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
namespace OpenSim.Groups namespace OpenSim.Groups
{ {
@ -51,7 +52,7 @@ namespace OpenSim.Groups
private IPresenceService m_presenceService; private IPresenceService m_presenceService;
private IMessageTransferModule m_msgTransferModule = null; private IMessageTransferModule m_msgTransferModule = null;
private IUserManagement m_UserManagement = null;
private IGroupsServicesConnector m_groupData = null; private IGroupsServicesConnector m_groupData = null;
// Config Options // Config Options
@ -79,6 +80,10 @@ namespace OpenSim.Groups
private int m_usersOnlineCacheExpirySeconds = 20; private int m_usersOnlineCacheExpirySeconds = 20;
private Dictionary<UUID, List<string>> m_groupsAgentsDroppedFromChatSession = new Dictionary<UUID, List<string>>();
private Dictionary<UUID, List<string>> m_groupsAgentsInvitedToChatSession = new Dictionary<UUID, List<string>>();
#region Region Module interfaceBase Members #region Region Module interfaceBase Members
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
@ -124,10 +129,12 @@ namespace OpenSim.Groups
m_sceneList.Add(scene); m_sceneList.Add(scene);
scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
scene.EventManager.OnMakeChildAgent += OnMakeChildAgent;
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
scene.EventManager.OnClientLogin += OnClientLogin; scene.EventManager.OnClientLogin += OnClientLogin;
} }
public void RegionLoaded(Scene scene) public void RegionLoaded(Scene scene)
{ {
if (!m_groupMessagingEnabled) if (!m_groupMessagingEnabled)
@ -155,6 +162,17 @@ namespace OpenSim.Groups
return; return;
} }
m_UserManagement = scene.RequestModuleInterface<IUserManagement>();
// No groups module, no groups messaging
if (m_UserManagement == null)
{
m_log.Error("[Groups.Messaging]: Could not get IUserManagement, GroupsMessagingModule is now disabled.");
RemoveRegion(scene);
return;
}
if (m_presenceService == null) if (m_presenceService == null)
m_presenceService = scene.PresenceService; m_presenceService = scene.PresenceService;
@ -227,87 +245,106 @@ namespace OpenSim.Groups
public void SendMessageToGroup(GridInstantMessage im, UUID groupID) public void SendMessageToGroup(GridInstantMessage im, UUID groupID)
{ {
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers(new UUID(im.fromAgentID).ToString(), groupID); UUID fromAgentID = new UUID(im.fromAgentID);
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers("all", groupID);
int groupMembersCount = groupMembers.Count; int groupMembersCount = groupMembers.Count;
PresenceInfo[] onlineAgents = null;
if (m_messageOnlineAgentsOnly) // In V2 we always only send to online members.
// Sending to offline members is not an option.
string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray();
// We cache in order not to overwhlem the presence service on large grids with many groups. This does
// mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed.
// (assuming this is the same across all grid simulators).
if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
{ {
string[] t1 = groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()).ToArray(); onlineAgents = m_presenceService.GetAgents(t1);
m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
}
// We cache in order not to overwhlem the presence service on large grids with many groups. This does HashSet<string> onlineAgentsUuidSet = new HashSet<string>();
// mean that members coming online will not see all group members until after m_usersOnlineCacheExpirySeconds has elapsed. Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
// (assuming this is the same across all grid simulators).
PresenceInfo[] onlineAgents;
if (!m_usersOnlineCache.TryGetValue(groupID, out onlineAgents))
{
onlineAgents = m_presenceService.GetAgents(t1);
m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
}
HashSet<string> onlineAgentsUuidSet = new HashSet<string>(); groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
Array.ForEach<PresenceInfo>(onlineAgents, pi => onlineAgentsUuidSet.Add(pi.UserID));
groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList(); // if (m_debugEnabled)
// if (m_debugEnabled)
// m_log.DebugFormat( // m_log.DebugFormat(
// "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online", // "[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
// groupID, groupMembersCount, groupMembers.Count()); // groupID, groupMembersCount, groupMembers.Count());
}
else
{
if (m_debugEnabled)
m_log.DebugFormat(
"[Groups.Messaging]: SendMessageToGroup called for group {0} with {1} visible members",
groupID, groupMembers.Count);
}
int requestStartTick = Environment.TickCount; int requestStartTick = Environment.TickCount;
im.imSessionID = groupID.Guid;
im.fromGroup = true;
IClientAPI thisClient = GetActiveClient(fromAgentID);
if (thisClient != null)
{
im.RegionID = thisClient.Scene.RegionInfo.RegionID.Guid;
}
// Send to self first of all
im.toAgentID = im.fromAgentID;
im.fromGroup = true;
ProcessMessageFromGroupSession(im);
List<UUID> regions = new List<UUID>();
List<UUID> clientsAlreadySent = new List<UUID>();
// Then send to everybody else
foreach (GroupMembersData member in groupMembers) foreach (GroupMembersData member in groupMembers)
{ {
if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID)) if (member.AgentID.Guid == im.fromAgentID)
continue;
if (hasAgentDroppedGroupChatSession(member.AgentID.ToString(), groupID))
{ {
// Don't deliver messages to people who have dropped this session // Don't deliver messages to people who have dropped this session
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID); if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: {0} has dropped session, not delivering to them", member.AgentID);
continue; continue;
} }
// Copy Message im.toAgentID = member.AgentID.Guid;
GridInstantMessage msg = new GridInstantMessage();
msg.imSessionID = groupID.Guid;
msg.fromAgentName = im.fromAgentName;
msg.message = im.message;
msg.dialog = im.dialog;
msg.offline = im.offline;
msg.ParentEstateID = im.ParentEstateID;
msg.Position = im.Position;
msg.RegionID = im.RegionID;
msg.binaryBucket = im.binaryBucket;
msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
msg.fromAgentID = im.fromAgentID;
msg.fromGroup = true;
msg.toAgentID = member.AgentID.Guid;
IClientAPI client = GetActiveClient(member.AgentID); IClientAPI client = GetActiveClient(member.AgentID);
if (client == null) if (client == null)
{ {
// If they're not local, forward across the grid // If they're not local, forward across the grid
// BUT do it only once per region, please! Sim would be even better!
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID); if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} via Grid", member.AgentID);
m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
bool reallySend = true;
if (onlineAgents != null)
{
PresenceInfo presence = onlineAgents.First(p => p.UserID == member.AgentID.ToString());
if (regions.Contains(presence.RegionID))
reallySend = false;
else
regions.Add(presence.RegionID);
}
if (reallySend)
{
// We have to create a new IM structure because the transfer module
// uses async send
GridInstantMessage msg = new GridInstantMessage(im, true);
m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
}
} }
else else
{ {
// Deliver locally, directly // Deliver locally, directly
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name);
ProcessMessageFromGroupSession(msg);
if (clientsAlreadySent.Contains(member.AgentID))
continue;
clientsAlreadySent.Add(member.AgentID);
ProcessMessageFromGroupSession(im);
} }
} }
// Temporary for assessing how long it still takes to send messages to large online groups. if (m_debugEnabled)
if (m_messageOnlineAgentsOnly)
m_log.DebugFormat( m_log.DebugFormat(
"[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms", "[Groups.Messaging]: SendMessageToGroup for group {0} with {1} visible members, {2} online took {3}ms",
groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick); groupID, groupMembersCount, groupMembers.Count(), Environment.TickCount - requestStartTick);
@ -324,9 +361,20 @@ namespace OpenSim.Groups
{ {
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name); if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: OnInstantMessage registered for {0}", client.Name);
client.OnInstantMessage += OnInstantMessage; ResetAgentGroupChatSessions(client.AgentId.ToString());
} }
void OnMakeRootAgent(ScenePresence sp)
{
sp.ControllingClient.OnInstantMessage += OnInstantMessage;
}
void OnMakeChildAgent(ScenePresence sp)
{
sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
}
private void OnGridInstantMessage(GridInstantMessage msg) private void OnGridInstantMessage(GridInstantMessage msg)
{ {
// The instant message module will only deliver messages of dialog types: // The instant message module will only deliver messages of dialog types:
@ -335,21 +383,97 @@ namespace OpenSim.Groups
// Any other message type will not be delivered to a client by the // Any other message type will not be delivered to a client by the
// Instant Message Module // Instant Message Module
UUID regionID = new UUID(msg.RegionID);
if (m_debugEnabled) if (m_debugEnabled)
{ {
m_log.DebugFormat("[Groups.Messaging]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); m_log.DebugFormat("[Groups.Messaging]: {0} called, IM from region {1}",
System.Reflection.MethodBase.GetCurrentMethod().Name, regionID);
DebugGridInstantMessage(msg); DebugGridInstantMessage(msg);
} }
// Incoming message from a group // Incoming message from a group
if ((msg.fromGroup == true) && if ((msg.fromGroup == true) && (msg.dialog == (byte)InstantMessageDialog.SessionSend))
((msg.dialog == (byte)InstantMessageDialog.SessionSend)
|| (msg.dialog == (byte)InstantMessageDialog.SessionAdd)
|| (msg.dialog == (byte)InstantMessageDialog.SessionDrop)))
{ {
ProcessMessageFromGroupSession(msg); // We have to redistribute the message across all members of the group who are here
// on this sim
UUID GroupID = new UUID(msg.imSessionID);
Scene aScene = m_sceneList[0];
GridRegion regionOfOrigin = aScene.GridService.GetRegionByUUID(aScene.RegionInfo.ScopeID, regionID);
List<GroupMembersData> groupMembers = m_groupData.GetGroupMembers("all", GroupID);
List<UUID> alreadySeen = new List<UUID>();
//if (m_debugEnabled)
// foreach (GroupMembersData m in groupMembers)
// m_log.DebugFormat("[Groups.Messaging]: member {0}", m.AgentID);
foreach (Scene s in m_sceneList)
{
s.ForEachScenePresence(sp =>
{
// We need this, because we are searching through all
// SPs, both root and children
if (alreadySeen.Contains(sp.UUID))
{
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because we've already seen it", sp.UUID);
return;
}
alreadySeen.Add(sp.UUID);
GroupMembersData m = groupMembers.Find(gmd =>
{
return gmd.AgentID == sp.UUID;
});
if (m.AgentID == UUID.Zero)
{
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he is not a member of the group", sp.UUID);
return;
}
// Check if the user has an agent in the region where
// the IM came from, and if so, skip it, because the IM
// was already sent via that agent
if (regionOfOrigin != null)
{
AgentCircuitData aCircuit = s.AuthenticateHandler.GetAgentCircuitData(sp.UUID);
if (aCircuit != null)
{
if (aCircuit.ChildrenCapSeeds.Keys.Contains(regionOfOrigin.RegionHandle))
{
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: skipping agent {0} because he has an agent in region of origin", sp.UUID);
return;
}
else
{
if (m_debugEnabled)
m_log.DebugFormat("[Groups.Messaging]: not skipping agent {0}", sp.UUID);
}
}
}
UUID AgentID = sp.UUID;
msg.toAgentID = AgentID.Guid;
if (!hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID))
{
if (!hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID))
AddAgentToSession(AgentID, GroupID, msg);
else
{
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", sp.Name);
ProcessMessageFromGroupSession(msg);
}
}
});
}
} }
} }
@ -359,82 +483,40 @@ namespace OpenSim.Groups
UUID AgentID = new UUID(msg.fromAgentID); UUID AgentID = new UUID(msg.fromAgentID);
UUID GroupID = new UUID(msg.imSessionID); UUID GroupID = new UUID(msg.imSessionID);
UUID toAgentID = new UUID(msg.toAgentID);
switch (msg.dialog) switch (msg.dialog)
{ {
case (byte)InstantMessageDialog.SessionAdd: case (byte)InstantMessageDialog.SessionAdd:
m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
break; break;
case (byte)InstantMessageDialog.SessionDrop: case (byte)InstantMessageDialog.SessionDrop:
m_groupData.AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID); AgentDroppedFromGroupChatSession(AgentID.ToString(), GroupID);
break; break;
case (byte)InstantMessageDialog.SessionSend: case (byte)InstantMessageDialog.SessionSend:
if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID) // User hasn't dropped, so they're in the session,
&& !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID.ToString(), GroupID) // maybe we should deliver it.
) IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
if (client != null)
{ {
// Agent not in session and hasn't dropped from session // Deliver locally, directly
// Add them to the session for now, and Invite them if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
UUID toAgentID = new UUID(msg.toAgentID); if (!hasAgentDroppedGroupChatSession(toAgentID.ToString(), GroupID))
IClientAPI activeClient = GetActiveClient(toAgentID);
if (activeClient != null)
{ {
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null); if (!hasAgentBeenInvitedToGroupChatSession(toAgentID.ToString(), GroupID))
if (groupInfo != null) // This actually sends the message too, so no need to resend it
{ // with client.SendInstantMessage
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message"); AddAgentToSession(toAgentID, GroupID, msg);
else
// Force? open the group session dialog??? client.SendInstantMessage(msg);
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
eq.ChatterboxInvitation(
GroupID
, groupInfo.GroupName
, new UUID(msg.fromAgentID)
, msg.message
, new UUID(msg.toAgentID)
, msg.fromAgentName
, msg.dialog
, msg.timestamp
, msg.offline == 1
, (int)msg.ParentEstateID
, msg.Position
, 1
, new UUID(msg.imSessionID)
, msg.fromGroup
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
);
eq.ChatterBoxSessionAgentListUpdates(
new UUID(GroupID)
, new UUID(msg.fromAgentID)
, new UUID(msg.toAgentID)
, false //canVoiceChat
, false //isModerator
, false //text mute
);
}
} }
} }
else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID.ToString(), GroupID)) else
{ {
// User hasn't dropped, so they're in the session, m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
// maybe we should deliver it.
IClientAPI client = GetActiveClient(new UUID(msg.toAgentID));
if (client != null)
{
// Deliver locally, directly
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Delivering to {0} locally", client.Name);
client.SendInstantMessage(msg);
}
else
{
m_log.WarnFormat("[Groups.Messaging]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
}
} }
break; break;
@ -444,6 +526,53 @@ namespace OpenSim.Groups
} }
} }
private void AddAgentToSession(UUID AgentID, UUID GroupID, GridInstantMessage msg)
{
// Agent not in session and hasn't dropped from session
// Add them to the session for now, and Invite them
AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
IClientAPI activeClient = GetActiveClient(AgentID);
if (activeClient != null)
{
GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero.ToString(), GroupID, null);
if (groupInfo != null)
{
if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Sending chatterbox invite instant message");
// Force? open the group session dialog???
// and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg);
IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>();
eq.ChatterboxInvitation(
GroupID
, groupInfo.GroupName
, new UUID(msg.fromAgentID)
, msg.message
, AgentID
, msg.fromAgentName
, msg.dialog
, msg.timestamp
, msg.offline == 1
, (int)msg.ParentEstateID
, msg.Position
, 1
, new UUID(msg.imSessionID)
, msg.fromGroup
, OpenMetaverse.Utils.StringToBytes(groupInfo.GroupName)
);
eq.ChatterBoxSessionAgentListUpdates(
new UUID(GroupID)
, AgentID
, new UUID(msg.toAgentID)
, false //canVoiceChat
, false //isModerator
, false //text mute
);
}
}
}
#endregion #endregion
@ -469,7 +598,7 @@ namespace OpenSim.Groups
if (groupInfo != null) if (groupInfo != null)
{ {
m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
@ -495,7 +624,7 @@ namespace OpenSim.Groups
m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); m_log.DebugFormat("[Groups.Messaging]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
//If this agent is sending a message, then they want to be in the session //If this agent is sending a message, then they want to be in the session
m_groupData.AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID); AgentInvitedToGroupChatSession(AgentID.ToString(), GroupID);
SendMessageToGroup(im, GroupID); SendMessageToGroup(im, GroupID);
} }
@ -566,12 +695,12 @@ namespace OpenSim.Groups
{ {
if (!sp.IsChildAgent) if (!sp.IsChildAgent)
{ {
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name); if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found root agent for client : {0}", sp.ControllingClient.Name);
return sp.ControllingClient; return sp.ControllingClient;
} }
else else
{ {
if (m_debugEnabled) m_log.WarnFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name); if (m_debugEnabled) m_log.DebugFormat("[Groups.Messaging]: Found child agent for client : {0}", sp.ControllingClient.Name);
child = sp.ControllingClient; child = sp.ControllingClient;
} }
} }
@ -590,5 +719,71 @@ namespace OpenSim.Groups
} }
#endregion #endregion
#region GroupSessionTracking
public void ResetAgentGroupChatSessions(string agentID)
{
foreach (List<string> agentList in m_groupsAgentsDroppedFromChatSession.Values)
agentList.Remove(agentID);
foreach (List<string> agentList in m_groupsAgentsInvitedToChatSession.Values)
agentList.Remove(agentID);
}
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
{
// If we're tracking this group, and we can find them in the tracking, then they've been invited
return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID)
&& m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID);
}
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
{
// If we're tracking drops for this group,
// and we find them, well... then they've dropped
return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)
&& m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID);
}
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
{
if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
{
// If not in dropped list, add
if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
{
m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID);
}
}
}
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
{
// Add Session Status if it doesn't exist for this session
CreateGroupChatSessionTracking(groupID);
// If nessesary, remove from dropped list
if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
{
m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID);
}
// Add to invited
if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
m_groupsAgentsInvitedToChatSession[groupID].Add(agentID);
}
private void CreateGroupChatSessionTracking(UUID groupID)
{
if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
{
m_groupsAgentsDroppedFromChatSession.Add(groupID, new List<string>());
m_groupsAgentsInvitedToChatSession.Add(groupID, new List<string>());
}
}
#endregion
} }
} }

View File

@ -141,6 +141,8 @@ namespace OpenSim.Groups
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnMakeRootAgent += OnMakeRoot;
scene.EventManager.OnMakeChildAgent += OnMakeChild;
scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
// The InstantMessageModule itself doesn't do this, // The InstantMessageModule itself doesn't do this,
// so lets see if things explode if we don't do it // so lets see if things explode if we don't do it
@ -194,6 +196,8 @@ namespace OpenSim.Groups
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
scene.EventManager.OnNewClient -= OnNewClient; scene.EventManager.OnNewClient -= OnNewClient;
scene.EventManager.OnMakeRootAgent -= OnMakeRoot;
scene.EventManager.OnMakeChildAgent -= OnMakeChild;
scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
lock (m_sceneList) lock (m_sceneList)
@ -232,16 +236,29 @@ namespace OpenSim.Groups
{ {
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
client.OnDirFindQuery += OnDirFindQuery;
client.OnRequestAvatarProperties += OnRequestAvatarProperties; client.OnRequestAvatarProperties += OnRequestAvatarProperties;
}
private void OnMakeRoot(ScenePresence sp)
{
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
// Used for Notices and Group Invites/Accept/Reject // Used for Notices and Group Invites/Accept/Reject
client.OnInstantMessage += OnInstantMessage; sp.ControllingClient.OnInstantMessage += OnInstantMessage;
// Send client their groups information. // Send client their groups information.
SendAgentGroupDataUpdate(client, client.AgentId); SendAgentGroupDataUpdate(sp.ControllingClient, sp.UUID);
}
private void OnMakeChild(ScenePresence sp)
{
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
// Used for Notices and Group Invites/Accept/Reject
sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
} }
private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
@ -287,21 +304,6 @@ namespace OpenSim.Groups
} }
*/ */
void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
{
if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
{
if (m_debugEnabled)
m_log.DebugFormat(
"[Groups]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
// TODO: This currently ignores pretty much all the query flags including Mature and sort order
remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), queryText).ToArray());
}
}
private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
{ {
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@ -907,23 +909,7 @@ namespace OpenSim.Groups
{ {
if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called for notice {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupNoticeID); if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called for notice {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, groupNoticeID);
//GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null);
GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested);
//GridInstantMessage msg = new GridInstantMessage();
//msg.imSessionID = UUID.Zero.Guid;
//msg.fromAgentID = data.GroupID.Guid;
//msg.toAgentID = GetRequestingAgentID(remoteClient).Guid;
//msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
//msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName;
//msg.message = data.noticeData.Subject + "|" + data.Message;
//msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested;
//msg.fromGroup = true;
//msg.offline = (byte)0;
//msg.ParentEstateID = 0;
//msg.Position = Vector3.Zero;
//msg.RegionID = UUID.Zero.Guid;
//msg.binaryBucket = data.BinaryBucket;
OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient));
} }
@ -1189,6 +1175,11 @@ namespace OpenSim.Groups
} }
} }
public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
{
return m_groupData.FindGroups(GetRequestingAgentIDStr(remoteClient), query);
}
#endregion #endregion
#region Client/Update Tools #region Client/Update Tools

View File

@ -590,28 +590,6 @@ namespace OpenSim.Groups
return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID); return m_LocalGroupsConnector.GetGroupNotices(AgentUUI(RequestingAgentID), GroupID);
} }
public void ResetAgentGroupChatSessions(string agentID)
{
}
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
{
return false;
}
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
{
return false;
}
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
{
}
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
{
}
#endregion #endregion
#region hypergrid groups #region hypergrid groups

View File

@ -92,12 +92,6 @@ namespace OpenSim.Groups
GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID); GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID);
List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID); List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID GroupID);
void ResetAgentGroupChatSessions(string agentID);
bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID);
bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID);
void AgentDroppedFromGroupChatSession(string agentID, UUID groupID);
void AgentInvitedToGroupChatSession(string agentID, UUID groupID);
} }
public class GroupInviteInfo public class GroupInviteInfo

View File

@ -320,28 +320,6 @@ namespace OpenSim.Groups
return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID); return m_GroupsService.GetGroupNotices(RequestingAgentID, GroupID);
} }
public void ResetAgentGroupChatSessions(string agentID)
{
}
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
{
return false;
}
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
{
return false;
}
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
{
}
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
{
}
#endregion #endregion
} }
} }

View File

@ -133,6 +133,36 @@ namespace OpenSim.Groups
return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]); return GroupsDataUtils.GroupRecord((Dictionary<string, object>)ret["RESULT"]);
} }
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string query)
{
List<DirGroupsReplyData> hits = new List<DirGroupsReplyData>();
if (string.IsNullOrEmpty(query))
return hits;
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["Query"] = query;
sendData["RequestingAgentID"] = RequestingAgentID;
Dictionary<string, object> ret = MakeRequest("FINDGROUPS", sendData);
if (ret == null)
return hits;
if (!ret.ContainsKey("RESULT"))
return hits;
if (ret["RESULT"].ToString() == "NULL")
return hits;
foreach (object v in ((Dictionary<string, object>)ret["RESULT"]).Values)
{
DirGroupsReplyData m = GroupsDataUtils.DirGroupsReplyData((Dictionary<string, object>)v);
hits.Add(m);
}
return hits;
}
public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) public GroupMembershipData AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
{ {
reason = string.Empty; reason = string.Empty;

View File

@ -199,7 +199,7 @@ namespace OpenSim.Groups
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search) public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
{ {
// TODO! // TODO!
return new List<DirGroupsReplyData>(); return m_GroupsService.FindGroups(RequestingAgentID, search);
} }
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason) public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
@ -406,28 +406,6 @@ namespace OpenSim.Groups
}); });
} }
public void ResetAgentGroupChatSessions(string agentID)
{
}
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
{
return false;
}
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
{
return false;
}
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
{
}
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
{
}
#endregion #endregion
} }

View File

@ -133,6 +133,8 @@ namespace OpenSim.Groups
return HandleAddNotice(request); return HandleAddNotice(request);
case "GETNOTICES": case "GETNOTICES":
return HandleGetNotices(request); return HandleGetNotices(request);
case "FINDGROUPS":
return HandleFindGroups(request);
} }
m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method); m_log.DebugFormat("[GROUPS HANDLER]: unknown method request: {0}", method);
} }
@ -740,6 +742,32 @@ namespace OpenSim.Groups
return Util.UTF8NoBomEncoding.GetBytes(xmlString); return Util.UTF8NoBomEncoding.GetBytes(xmlString);
} }
byte[] HandleFindGroups(Dictionary<string, object> request)
{
Dictionary<string, object> result = new Dictionary<string, object>();
if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("Query"))
NullResult(result, "Bad network data");
List<DirGroupsReplyData> hits = m_GroupsService.FindGroups(request["RequestingAgentID"].ToString(), request["Query"].ToString());
if (hits == null || (hits != null && hits.Count == 0))
NullResult(result, "No hits");
else
{
Dictionary<string, object> dict = new Dictionary<string, object>();
int i = 0;
foreach (DirGroupsReplyData n in hits)
dict["n-" + i++] = GroupsDataUtils.DirGroupsReplyData(n);
result["RESULT"] = dict;
}
string xmlString = ServerUtils.BuildXmlResponse(result);
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
}
#region Helpers #region Helpers

View File

@ -255,13 +255,20 @@ namespace OpenSim.Groups
return members; return members;
List<RoleData> rolesList = new List<RoleData>(roles); List<RoleData> rolesList = new List<RoleData>(roles);
// Is the requester a member of the group? // Check visibility?
bool isInGroup = false; // When we don't want to check visibility, we pass it "all" as the requestingAgentID
if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null) bool checkVisibility = !RequestingAgentID.Equals("all");
isInGroup = true; m_log.DebugFormat("[ZZZ]: AgentID is {0}. checkVisibility is {1}", RequestingAgentID, checkVisibility);
if (checkVisibility)
{
// Is the requester a member of the group?
bool isInGroup = false;
if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
isInGroup = true;
if (!isInGroup) // reduce the roles to the visible ones if (!isInGroup) // reduce the roles to the visible ones
rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0); rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
}
MembershipData[] datas = m_Database.RetrieveMembers(GroupID); MembershipData[] datas = m_Database.RetrieveMembers(GroupID);
if (datas == null || (datas != null && datas.Length == 0)) if (datas == null || (datas != null && datas.Length == 0))

View File

@ -88,7 +88,7 @@ namespace OpenSim.Data.MySQL
if (string.IsNullOrEmpty(pattern)) if (string.IsNullOrEmpty(pattern))
pattern = "1 ORDER BY Name LIMIT 100"; pattern = "1 ORDER BY Name LIMIT 100";
else else
pattern = string.Format("Name LIKE %{0}% ORDER BY Name LIMIT 100", pattern); pattern = string.Format("Name LIKE '%{0}%' ORDER BY Name LIMIT 100", pattern);
return m_Groups.Get(pattern); return m_Groups.Get(pattern);
} }

View File

@ -53,6 +53,24 @@ namespace OpenSim.Framework
binaryBucket = new byte[0]; binaryBucket = new byte[0];
} }
public GridInstantMessage(GridInstantMessage im, bool addTimestamp)
{
fromAgentID = im.fromAgentID;
fromAgentName = im.fromAgentName;
toAgentID = im.toAgentID;
dialog = im.dialog;
fromGroup = im.fromGroup;
message = im.message;
imSessionID = im.imSessionID;
offline = im.offline;
Position = im.Position;
binaryBucket = im.binaryBucket;
RegionID = im.RegionID;
if (addTimestamp)
timestamp = (uint)Util.UnixTimeSinceEpoch();
}
public GridInstantMessage(IScene scene, UUID _fromAgentID, public GridInstantMessage(IScene scene, UUID _fromAgentID,
string _fromAgentName, UUID _toAgentID, string _fromAgentName, UUID _toAgentID,
byte _dialog, bool _fromGroup, string _message, byte _dialog, bool _fromGroup, string _message,

View File

@ -285,7 +285,12 @@ namespace OpenSim.Framework.Servers
public static bool RemoveHttpServer(uint port) public static bool RemoveHttpServer(uint port)
{ {
lock (m_Servers) lock (m_Servers)
{
if (instance != null && instance.Port == port)
instance = null;
return m_Servers.Remove(port); return m_Servers.Remove(port);
}
} }
/// <summary> /// <summary>

View File

@ -91,7 +91,6 @@ namespace OpenSim.Region.ClientStack.Linden
scene.RegisterModuleInterface<IEventQueue>(this); scene.RegisterModuleInterface<IEventQueue>(this);
scene.EventManager.OnClientClosed += ClientClosed; scene.EventManager.OnClientClosed += ClientClosed;
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
scene.EventManager.OnRegisterCaps += OnRegisterCaps; scene.EventManager.OnRegisterCaps += OnRegisterCaps;
MainConsole.Instance.Commands.AddCommand( MainConsole.Instance.Commands.AddCommand(
@ -120,7 +119,6 @@ namespace OpenSim.Region.ClientStack.Linden
return; return;
scene.EventManager.OnClientClosed -= ClientClosed; scene.EventManager.OnClientClosed -= ClientClosed;
scene.EventManager.OnMakeChildAgent -= MakeChildAgent;
scene.EventManager.OnRegisterCaps -= OnRegisterCaps; scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
scene.UnregisterModuleInterface<IEventQueue>(this); scene.UnregisterModuleInterface<IEventQueue>(this);
@ -189,14 +187,12 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
if (!queues.ContainsKey(agentId)) if (!queues.ContainsKey(agentId))
{ {
/*
m_log.DebugFormat( m_log.DebugFormat(
"[EVENTQUEUE]: Adding new queue for agent {0} in region {1}", "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
agentId, m_scene.RegionInfo.RegionName); agentId, m_scene.RegionInfo.RegionName);
*/
queues[agentId] = new Queue<OSD>(); queues[agentId] = new Queue<OSD>();
} }
return queues[agentId]; return queues[agentId];
} }
} }
@ -228,8 +224,12 @@ namespace OpenSim.Region.ClientStack.Linden
{ {
Queue<OSD> queue = GetQueue(avatarID); Queue<OSD> queue = GetQueue(avatarID);
if (queue != null) if (queue != null)
{
lock (queue) lock (queue)
queue.Enqueue(ev); queue.Enqueue(ev);
}
else
m_log.WarnFormat("[EVENTQUEUE]: (Enqueue) No queue found for agent {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName);
} }
catch (NullReferenceException e) catch (NullReferenceException e)
{ {
@ -244,48 +244,15 @@ namespace OpenSim.Region.ClientStack.Linden
private void ClientClosed(UUID agentID, Scene scene) private void ClientClosed(UUID agentID, Scene scene)
{ {
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
int count = 0;
while (queues.ContainsKey(agentID) && queues[agentID].Count > 0 && count++ < 5)
{
Thread.Sleep(1000);
}
lock (queues) lock (queues)
{
queues.Remove(agentID); queues.Remove(agentID);
}
List<UUID> removeitems = new List<UUID>(); List<UUID> removeitems = new List<UUID>();
lock (m_AvatarQueueUUIDMapping) lock (m_AvatarQueueUUIDMapping)
m_AvatarQueueUUIDMapping.Remove(agentID); m_AvatarQueueUUIDMapping.Remove(agentID);
// lock (m_AvatarQueueUUIDMapping)
// {
// foreach (UUID ky in m_AvatarQueueUUIDMapping.Keys)
// {
//// m_log.DebugFormat("[EVENTQUEUE]: Found key {0} in m_AvatarQueueUUIDMapping while looking for {1}", ky, AgentID);
// if (ky == agentID)
// {
// removeitems.Add(ky);
// }
// }
//
// foreach (UUID ky in removeitems)
// {
// UUID eventQueueGetUuid = m_AvatarQueueUUIDMapping[ky];
// m_AvatarQueueUUIDMapping.Remove(ky);
//
// string eqgPath = GenerateEqgCapPath(eventQueueGetUuid);
// MainServer.Instance.RemovePollServiceHTTPHandler("", eqgPath);
//
//// m_log.DebugFormat(
//// "[EVENT QUEUE GET MODULE]: Removed EQG handler {0} for {1} in {2}",
//// eqgPath, agentID, m_scene.RegionInfo.RegionName);
// }
// }
UUID searchval = UUID.Zero; UUID searchval = UUID.Zero;
removeitems.Clear(); removeitems.Clear();
@ -305,19 +272,9 @@ namespace OpenSim.Region.ClientStack.Linden
foreach (UUID ky in removeitems) foreach (UUID ky in removeitems)
m_QueueUUIDAvatarMapping.Remove(ky); m_QueueUUIDAvatarMapping.Remove(ky);
} }
}
private void MakeChildAgent(ScenePresence avatar) // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
{
//m_log.DebugFormat("[EVENTQUEUE]: Make Child agent {0} in region {1}.", avatar.UUID, m_scene.RegionInfo.RegionName);
//lock (m_ids)
// {
//if (m_ids.ContainsKey(avatar.UUID))
//{
// close the event queue.
//m_ids[avatar.UUID] = -1;
//}
//}
} }
/// <summary> /// <summary>
@ -417,7 +374,12 @@ namespace OpenSim.Region.ClientStack.Linden
if (DebugLevel >= 2) if (DebugLevel >= 2)
m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName); m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
Queue<OSD> queue = TryGetQueue(pAgentId); Queue<OSD> queue = GetQueue(pAgentId);
if (queue == null)
{
return NoEvents(requestID, pAgentId);
}
OSD element; OSD element;
lock (queue) lock (queue)
{ {
@ -788,12 +750,12 @@ namespace OpenSim.Region.ClientStack.Linden
} }
public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
bool isModerator, bool textMute) bool isModerator, bool textMute)
{ {
OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat, OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
isModerator, textMute); isModerator, textMute);
Enqueue(item, toAgent); Enqueue(item, fromAgent);
//m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item); //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
} }

View File

@ -38,6 +38,8 @@ using NUnit.Framework;
using OpenMetaverse; using OpenMetaverse;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Communications; using OpenSim.Framework.Communications;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using OpenSim.Region.CoreModules.Avatar.Attachments; using OpenSim.Region.CoreModules.Avatar.Attachments;
using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.CoreModules.Framework;
using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.CoreModules.Framework.EntityTransfer;
@ -802,6 +804,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
// TestHelpers.EnableLogging(); // TestHelpers.EnableLogging();
BaseHttpServer httpServer = new BaseHttpServer(99999);
MainServer.AddHttpServer(httpServer);
MainServer.Instance = httpServer;
AttachmentsModule attModA = new AttachmentsModule(); AttachmentsModule attModA = new AttachmentsModule();
AttachmentsModule attModB = new AttachmentsModule(); AttachmentsModule attModB = new AttachmentsModule();
EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmA = new EntityTransferModule();
@ -830,6 +836,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
SceneHelpers.SetupSceneModules( SceneHelpers.SetupSceneModules(
sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule()); sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
// FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
lscm.ServiceVersion = "SIMULATION/0.1";
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID); AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);

View File

@ -392,7 +392,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
gim.fromAgentName = fromAgentName; gim.fromAgentName = fromAgentName;
gim.fromGroup = fromGroup; gim.fromGroup = fromGroup;
gim.imSessionID = imSessionID.Guid; gim.imSessionID = imSessionID.Guid;
gim.RegionID = UUID.Zero.Guid; // RegionID.Guid; gim.RegionID = RegionID.Guid;
gim.timestamp = timestamp; gim.timestamp = timestamp;
gim.toAgentID = toAgentID.Guid; gim.toAgentID = toAgentID.Guid;
gim.message = message; gim.message = message;
@ -728,7 +728,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
gim["position_x"] = msg.Position.X.ToString(); gim["position_x"] = msg.Position.X.ToString();
gim["position_y"] = msg.Position.Y.ToString(); gim["position_y"] = msg.Position.Y.ToString();
gim["position_z"] = msg.Position.Z.ToString(); gim["position_z"] = msg.Position.Z.ToString();
gim["region_id"] = msg.RegionID.ToString(); gim["region_id"] = new UUID(msg.RegionID).ToString();
gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None); gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
if (m_MessageKey != String.Empty) if (m_MessageKey != String.Empty)
gim["message_key"] = m_MessageKey; gim["message_key"] = m_MessageKey;

View File

@ -133,13 +133,9 @@ namespace OpenSim.Region.CoreModules.Framework
{ {
Caps oldCaps = m_capsObjects[circuitCode]; Caps oldCaps = m_capsObjects[circuitCode];
m_log.DebugFormat( //m_log.WarnFormat(
"[CAPS]: Recreating caps for agent {0}. Old caps path {1}, new caps path {2}. ", // "[CAPS]: Recreating caps for agent {0} in region {1}. Old caps path {2}, new caps path {3}. ",
agentId, oldCaps.CapsObjectPath, capsObjectPath); // agentId, m_scene.RegionInfo.RegionName, oldCaps.CapsObjectPath, capsObjectPath);
// This should not happen. The caller code is confused. We need to fix that.
// CAPs can never be reregistered, or the client will be confused.
// Hence this return here.
//return;
} }
caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName, caps = new Caps(MainServer.Instance, m_scene.RegionInfo.ExternalHostName,
@ -153,6 +149,7 @@ namespace OpenSim.Region.CoreModules.Framework
public void RemoveCaps(UUID agentId, uint circuitCode) public void RemoveCaps(UUID agentId, uint circuitCode)
{ {
m_log.DebugFormat("[CAPS]: Remove caps for agent {0} in region {1}", agentId, m_scene.RegionInfo.RegionName);
lock (m_childrenSeeds) lock (m_childrenSeeds)
{ {
if (m_childrenSeeds.ContainsKey(agentId)) if (m_childrenSeeds.ContainsKey(agentId))

View File

@ -316,7 +316,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
m_log.DebugFormat( m_log.DebugFormat(
"[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
sp.Name, sp.UUID, position, regionHandle); sp.Name, sp.UUID, position, regionHandle);
sp.ControllingClient.SendTeleportFailed("Slow down!");
return; return;
} }
@ -921,13 +922,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
{ {
// RED ALERT!!!! // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
// PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. // they regard the new region as the current region after receiving the AgentMovementComplete
// THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion // response. If close is sent before then, it will cause the viewer to quit instead.
// BEFORE THEY SETTLE IN THE NEW REGION. //
// DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR // This sleep can be increased if necessary. However, whilst it's active,
// IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. // an agent cannot teleport back to this region if it has teleported away.
Thread.Sleep(5000); Thread.Sleep(2000);
sp.Scene.IncomingCloseAgent(sp.UUID, false); sp.Scene.IncomingCloseAgent(sp.UUID, false);
} }
@ -1045,21 +1046,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
// Now let's make it officially a child agent // Now let's make it officially a child agent
sp.MakeChildAgent(); sp.MakeChildAgent();
// OK, it got this agent. Let's close some child agents
sp.CloseChildAgents(newRegionX, newRegionY);
// Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
{ {
sp.DoNotCloseAfterTeleport = false;
// RED ALERT!!!! // RED ALERT!!!!
// PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
// THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
// BEFORE THEY SETTLE IN THE NEW REGION. // BEFORE THEY SETTLE IN THE NEW REGION.
// DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
// IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
Thread.Sleep(5000); Thread.Sleep(15000);
sp.Scene.IncomingCloseAgent(sp.UUID, false);
if (!sp.DoNotCloseAfterTeleport)
{
// OK, it got this agent. Let's close everything
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Closing in agent {0} in region {1}", sp.Name, Scene.RegionInfo.RegionName);
sp.CloseChildAgents(newRegionX, newRegionY);
sp.Scene.IncomingCloseAgent(sp.UUID, false);
}
else
{
m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Not closing agent {0}, user is back in {0}", sp.Name, Scene.RegionInfo.RegionName);
sp.DoNotCloseAfterTeleport = false;
}
} }
else else
// now we have a child agent in this region. // now we have a child agent in this region.

View File

@ -0,0 +1,197 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.ClientStack.LindenUDP;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using OpenSim.Services.Connectors.Hypergrid;
using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net;
using Nini.Config;
using Mono.Addins;
using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
namespace OpenSim.Region.CoreModules.Framework.Search
{
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BasicSearchModule")]
public class BasicSearchModule : ISharedRegionModule
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected bool m_Enabled;
protected List<Scene> m_Scenes = new List<Scene>();
private IGroupsModule m_GroupsService = null;
#region ISharedRegionModule
public void Initialise(IConfigSource config)
{
string umanmod = config.Configs["Modules"].GetString("SearchModule", Name);
if (umanmod == Name)
{
m_Enabled = true;
m_log.DebugFormat("[BASIC SEARCH MODULE]: {0} is enabled", Name);
}
}
public bool IsSharedModule
{
get { return true; }
}
public virtual string Name
{
get { return "BasicSearchModule"; }
}
public Type ReplaceableInterface
{
get { return null; }
}
public void AddRegion(Scene scene)
{
if (m_Enabled)
{
m_Scenes.Add(scene);
scene.EventManager.OnMakeRootAgent += new Action<ScenePresence>(EventManager_OnMakeRootAgent);
scene.EventManager.OnMakeChildAgent += new EventManager.OnMakeChildAgentDelegate(EventManager_OnMakeChildAgent);
}
}
public void RemoveRegion(Scene scene)
{
if (m_Enabled)
{
m_Scenes.Remove(scene);
scene.EventManager.OnMakeRootAgent -= new Action<ScenePresence>(EventManager_OnMakeRootAgent);
scene.EventManager.OnMakeChildAgent -= new EventManager.OnMakeChildAgentDelegate(EventManager_OnMakeChildAgent);
}
}
public void RegionLoaded(Scene s)
{
if (!m_Enabled)
return;
if (m_GroupsService == null)
{
m_GroupsService = s.RequestModuleInterface<IGroupsModule>();
// No Groups Service Connector, then group search won't work...
if (m_GroupsService == null)
m_log.Warn("[BASIC SEARCH MODULE]: Could not get IGroupsModule");
}
}
public void PostInitialise()
{
}
public void Close()
{
m_Scenes.Clear();
}
#endregion ISharedRegionModule
#region Event Handlers
void EventManager_OnMakeRootAgent(ScenePresence sp)
{
sp.ControllingClient.OnDirFindQuery += OnDirFindQuery;
}
void EventManager_OnMakeChildAgent(ScenePresence sp)
{
sp.ControllingClient.OnDirFindQuery -= OnDirFindQuery;
}
void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
{
if (((DirFindFlags)queryFlags & DirFindFlags.People) == DirFindFlags.People)
{
if (string.IsNullOrEmpty(queryText))
remoteClient.SendDirPeopleReply(queryID, new DirPeopleReplyData[0]);
List<UserAccount> accounts = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, queryText);
DirPeopleReplyData[] hits = new DirPeopleReplyData[accounts.Count];
int i = 0;
foreach (UserAccount acc in accounts)
{
DirPeopleReplyData d = new DirPeopleReplyData();
d.agentID = acc.PrincipalID;
d.firstName = acc.FirstName;
d.lastName = acc.LastName;
d.online = false;
hits[i++] = d;
}
// TODO: This currently ignores pretty much all the query flags including Mature and sort order
remoteClient.SendDirPeopleReply(queryID, hits);
}
else if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
{
if (m_GroupsService == null)
{
m_log.Warn("[BASIC SEARCH MODULE]: Groups service is not available. Unable to search groups.");
remoteClient.SendAlertMessage("Groups search is not enabled");
return;
}
if (string.IsNullOrEmpty(queryText))
remoteClient.SendDirGroupsReply(queryID, new DirGroupsReplyData[0]);
// TODO: This currently ignores pretty much all the query flags including Mature and sort order
remoteClient.SendDirGroupsReply(queryID, m_GroupsService.FindGroups(remoteClient, queryText).ToArray());
}
}
#endregion Event Handlers
}
}

View File

@ -46,6 +46,8 @@ using log4net;
using Nini.Config; using Nini.Config;
using Mono.Addins; using Mono.Addins;
using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags;
namespace OpenSim.Region.CoreModules.Framework.UserManagement namespace OpenSim.Region.CoreModules.Framework.UserManagement
{ {
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")] [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UserManagementModule")]

View File

@ -46,9 +46,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
/// <summary> /// <summary>
/// Version of this service /// Version of this service.
/// </summary> /// </summary>
private const string m_Version = "SIMULATION/0.2"; /// <remarks>
/// Currently valid versions are "SIMULATION/0.1" and "SIMULATION/0.2"
/// </remarks>
public string ServiceVersion { get; set; }
/// <summary> /// <summary>
/// Map region ID to scene. /// Map region ID to scene.
@ -60,6 +63,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
/// </summary> /// </summary>
private bool m_ModuleEnabled = false; private bool m_ModuleEnabled = false;
public LocalSimulationConnectorModule()
{
ServiceVersion = "SIMULATION/0.2";
}
#region Region Module interface #region Region Module interface
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
@ -253,7 +261,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
{ {
reason = "Communications failure"; reason = "Communications failure";
version = m_Version; version = ServiceVersion;
if (destination == null) if (destination == null)
return false; return false;
@ -358,4 +366,4 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation
#endregion #endregion
} }
} }

View File

@ -53,7 +53,7 @@ namespace OpenSim.Region.Framework.Interfaces
UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
uint timeStamp, bool offline, int parentEstateID, Vector3 position, uint timeStamp, bool offline, int parentEstateID, Vector3 position,
uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket); uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket);
void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID toAgent, bool canVoiceChat, void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
bool isModerator, bool textMute); bool isModerator, bool textMute);
void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID); void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID);
void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID); void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID);

View File

@ -97,5 +97,7 @@ namespace OpenSim.Region.Framework.Interfaces
void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InviteeID, UUID RoleID); void InviteGroupRequest(IClientAPI remoteClient, UUID GroupID, UUID InviteeID, UUID RoleID);
void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID GroupID, UUID InviteeID, UUID RoleID); void InviteGroup(IClientAPI remoteClient, UUID agentID, UUID GroupID, UUID InviteeID, UUID RoleID);
void NotifyChange(UUID GroupID); void NotifyChange(UUID GroupID);
List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query);
} }
} }

View File

@ -2955,6 +2955,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
ScenePresence sp; ScenePresence sp;
bool vialogin; bool vialogin;
bool reallyNew = true;
// Validation occurs in LLUDPServer // Validation occurs in LLUDPServer
// //
@ -3013,6 +3014,7 @@ namespace OpenSim.Region.Framework.Scenes
m_log.WarnFormat( m_log.WarnFormat(
"[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
reallyNew = false;
} }
// We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
@ -3024,7 +3026,9 @@ namespace OpenSim.Region.Framework.Scenes
// places. However, we still need to do it here for NPCs. // places. However, we still need to do it here for NPCs.
CacheUserName(sp, aCircuit); CacheUserName(sp, aCircuit);
EventManager.TriggerOnNewClient(client); if (reallyNew)
EventManager.TriggerOnNewClient(client);
if (vialogin) if (vialogin)
EventManager.TriggerOnClientLogin(client); EventManager.TriggerOnClientLogin(client);
} }
@ -3583,15 +3587,8 @@ namespace OpenSim.Region.Framework.Scenes
if (closeChildAgents && isChildAgent) if (closeChildAgents && isChildAgent)
{ {
// Tell a single agent to disconnect from the region. // Tell a single agent to disconnect from the region.
IEventQueue eq = RequestModuleInterface<IEventQueue>(); // Let's do this via UDP
if (eq != null) avatar.ControllingClient.SendShutdownConnectionNotice();
{
eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
}
else
{
avatar.ControllingClient.SendShutdownConnectionNotice();
}
} }
// Only applies to root agents. // Only applies to root agents.
@ -3834,42 +3831,40 @@ namespace OpenSim.Region.Framework.Scenes
return false; return false;
} }
ScenePresence sp = GetScenePresence(agent.AgentID);
// If we have noo presence here or if that presence is a zombie root
// presence that will be kicled, we need a new CAPS object.
if (sp == null || (sp != null && !sp.IsChildAgent))
{
if (CapsModule != null)
{
lock (agent)
{
CapsModule.SetAgentCapsSeeds(agent);
CapsModule.CreateCaps(agent.AgentID, agent.circuitcode);
}
}
}
if (sp != null)
{
if (!sp.IsChildAgent)
{
// We have a zombie from a crashed session.
// Or the same user is trying to be root twice here, won't work.
// Kill it.
m_log.WarnFormat(
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
sp.Name, sp.UUID, RegionInfo.RegionName);
if (sp.ControllingClient != null)
sp.ControllingClient.Close(true, true);
sp = null;
}
}
lock (agent) lock (agent)
{ {
ScenePresence sp = GetScenePresence(agent.AgentID);
if (sp != null)
{
if (!sp.IsChildAgent)
{
// We have a root agent. Is it in transit?
if (!EntityTransferModule.IsInTransit(sp.UUID))
{
// We have a zombie from a crashed session.
// Or the same user is trying to be root twice here, won't work.
// Kill it.
m_log.WarnFormat(
"[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
sp.Name, sp.UUID, RegionInfo.RegionName);
if (sp.ControllingClient != null)
sp.ControllingClient.Close(true, true);
sp = null;
}
//else
// m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName);
}
else
{
// We have a child agent here
sp.DoNotCloseAfterTeleport = true;
//m_log.WarnFormat("[SCENE]: Existing child scene presence for {0} {1} in {2}", sp.Name, sp.UUID, RegionInfo.RegionName);
}
}
// Optimistic: add or update the circuit data with the new agent circuit data and teleport flags. // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags.
// We need the circuit data here for some of the subsequent checks. (groups, for example) // We need the circuit data here for some of the subsequent checks. (groups, for example)
// If the checks fail, we remove the circuit. // If the checks fail, we remove the circuit.
@ -3950,7 +3945,10 @@ namespace OpenSim.Region.Framework.Scenes
sp.AdjustKnownSeeds(); sp.AdjustKnownSeeds();
if (CapsModule != null) if (CapsModule != null)
{
CapsModule.SetAgentCapsSeeds(agent); CapsModule.SetAgentCapsSeeds(agent);
CapsModule.CreateCaps(agent.AgentID, agent.circuitcode);
}
} }
} }
@ -5829,17 +5827,6 @@ Environment.Exit(1);
{ {
reason = "You are banned from the region"; reason = "You are banned from the region";
if (EntityTransferModule.IsInTransit(agentID))
{
reason = "Agent is still in transit from this region";
m_log.WarnFormat(
"[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit",
agentID, RegionInfo.RegionName);
return false;
}
if (Permissions.IsGod(agentID)) if (Permissions.IsGod(agentID))
{ {
reason = String.Empty; reason = String.Empty;

View File

@ -764,6 +764,13 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
/// <summary>
/// Used by the entity transfer module to signal when the presence should not be closed because a subsequent
/// teleport is reusing the connection.
/// </summary>
/// <remarks>May be refactored or move somewhere else soon.</remarks>
public bool DoNotCloseAfterTeleport { get; set; }
private float m_speedModifier = 1.0f; private float m_speedModifier = 1.0f;
public float SpeedModifier public float SpeedModifier
@ -1541,11 +1548,13 @@ namespace OpenSim.Region.Framework.Scenes
client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); client.Name, Scene.RegionInfo.RegionName, AbsolutePosition);
// Make sure it's not a login agent. We don't want to wait for updates during login // Make sure it's not a login agent. We don't want to wait for updates during login
if ((m_teleportFlags & TeleportFlags.ViaLogin) == 0) if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
{
// Let's wait until UpdateAgent (called by departing region) is done // Let's wait until UpdateAgent (called by departing region) is done
if (!WaitForUpdateAgent(client)) if (!WaitForUpdateAgent(client))
// The sending region never sent the UpdateAgent data, we have to refuse // The sending region never sent the UpdateAgent data, we have to refuse
return; return;
}
Vector3 look = Velocity; Vector3 look = Velocity;

View File

@ -119,7 +119,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
UUID spUuid = TestHelpers.ParseTail(0x1); UUID spUuid = TestHelpers.ParseTail(0x1);
// The etm is only invoked by this test to check whether an agent is still in transit if there is a dupe
EntityTransferModule etm = new EntityTransferModule();
IConfigSource config = new IniConfigSource();
IConfig modulesConfig = config.AddConfig("Modules");
modulesConfig.Set("EntityTransferModule", etm.Name);
IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
// In order to run a single threaded regression test we do not want the entity transfer module waiting
// for a callback from the destination scene before removing its avatar data.
entityTransferConfig.Set("wait_for_callback", false);
TestScene scene = new SceneHelpers().SetupScene(); TestScene scene = new SceneHelpers().SetupScene();
SceneHelpers.SetupSceneModules(scene, config, etm);
SceneHelpers.AddScenePresence(scene, spUuid); SceneHelpers.AddScenePresence(scene, spUuid);
SceneHelpers.AddScenePresence(scene, spUuid); SceneHelpers.AddScenePresence(scene, spUuid);

View File

@ -136,6 +136,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
SceneHelpers.SetupSceneModules(sceneB, config, etmB); SceneHelpers.SetupSceneModules(sceneB, config, etmB);
SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
// FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
lscm.ServiceVersion = "SIMULATION/0.1";
Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportPosition = new Vector3(10, 11, 12);
Vector3 teleportLookAt = new Vector3(20, 21, 22); Vector3 teleportLookAt = new Vector3(20, 21, 22);
@ -454,6 +457,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests
SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA);
SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB);
// FIXME: Hack - this is here temporarily to revert back to older entity transfer behaviour
lscm.ServiceVersion = "SIMULATION/0.1";
Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportPosition = new Vector3(10, 11, 12);
Vector3 teleportLookAt = new Vector3(20, 21, 22); Vector3 teleportLookAt = new Vector3(20, 21, 22);

View File

@ -326,15 +326,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
"ParcelVoiceInfoRequest", "ParcelVoiceInfoRequest",
agentID.ToString())); agentID.ToString()));
caps.RegisterHandler( //caps.RegisterHandler(
"ChatSessionRequest", // "ChatSessionRequest",
new RestStreamHandler( // new RestStreamHandler(
"POST", // "POST",
capsBase + m_chatSessionRequestPath, // capsBase + m_chatSessionRequestPath,
(request, path, param, httpRequest, httpResponse) // (request, path, param, httpRequest, httpResponse)
=> ChatSessionRequest(scene, request, path, param, agentID, caps), // => ChatSessionRequest(scene, request, path, param, agentID, caps),
"ChatSessionRequest", // "ChatSessionRequest",
agentID.ToString())); // agentID.ToString()));
} }
/// <summary> /// <summary>

View File

@ -433,15 +433,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
"ParcelVoiceInfoRequest", "ParcelVoiceInfoRequest",
agentID.ToString())); agentID.ToString()));
caps.RegisterHandler( //caps.RegisterHandler(
"ChatSessionRequest", // "ChatSessionRequest",
new RestStreamHandler( // new RestStreamHandler(
"POST", // "POST",
capsBase + m_chatSessionRequestPath, // capsBase + m_chatSessionRequestPath,
(request, path, param, httpRequest, httpResponse) // (request, path, param, httpRequest, httpResponse)
=> ChatSessionRequest(scene, request, path, param, agentID, caps), // => ChatSessionRequest(scene, request, path, param, agentID, caps),
"ChatSessionRequest", // "ChatSessionRequest",
agentID.ToString())); // agentID.ToString()));
} }
/// <summary> /// <summary>

View File

@ -250,7 +250,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
client.OnDirFindQuery += OnDirFindQuery;
client.OnRequestAvatarProperties += OnRequestAvatarProperties; client.OnRequestAvatarProperties += OnRequestAvatarProperties;
// Used for Notices and Group Invites/Accept/Reject // Used for Notices and Group Invites/Accept/Reject
@ -303,21 +302,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
} }
*/ */
void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart)
{
if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups)
{
if (m_debugEnabled)
m_log.DebugFormat(
"[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})",
System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart);
// TODO: This currently ignores pretty much all the query flags including Mature and sort order
remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray());
}
}
private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
{ {
if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@ -1178,6 +1162,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
} }
} }
public List<DirGroupsReplyData> FindGroups(IClientAPI remoteClient, string query)
{
return m_groupData.FindGroups(GetRequestingAgentID(remoteClient), query);
}
#endregion #endregion
#region Client/Update Tools #region Client/Update Tools

View File

@ -155,7 +155,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
public void TestCreateWithAttachments() public void TestCreateWithAttachments()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // TestHelpers.EnableLogging();
UUID userId = TestHelpers.ParseTail(0x1); UUID userId = TestHelpers.ParseTail(0x1);
UserAccountHelpers.CreateUserWithInventory(m_scene, userId); UserAccountHelpers.CreateUserWithInventory(m_scene, userId);

View File

@ -180,6 +180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
public void TestOsNpcLoadAppearance() public void TestOsNpcLoadAppearance()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
//TestHelpers.EnableLogging();
// Store an avatar with a different height from default in a notecard. // Store an avatar with a different height from default in a notecard.
UUID userId = TestHelpers.ParseTail(0x1); UUID userId = TestHelpers.ParseTail(0x1);

View File

@ -123,6 +123,7 @@ namespace OpenSim.Services.Connectors.InstantMessage
gim["position_z"] = msg.Position.Z.ToString(); gim["position_z"] = msg.Position.Z.ToString();
gim["region_id"] = msg.RegionID.ToString(); gim["region_id"] = msg.RegionID.ToString();
gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None); gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None);
gim["region_id"] = new UUID(msg.RegionID).ToString();
return gim; return gim;
} }

View File

@ -86,7 +86,7 @@ namespace OpenSim.Services.MapImageService
{ {
Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH);
FillImage(waterTile, m_Watercolor); FillImage(waterTile, m_Watercolor);
waterTile.Save(m_WaterTileFile); waterTile.Save(m_WaterTileFile, ImageFormat.Jpeg);
} }
} }
} }

View File

@ -27,6 +27,7 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using OpenSim.Framework.Servers;
namespace OpenSim.Tests.Common namespace OpenSim.Tests.Common
{ {
@ -40,7 +41,14 @@ namespace OpenSim.Tests.Common
// Disable logging for each test so that one where logging is enabled doesn't cause all subsequent tests // Disable logging for each test so that one where logging is enabled doesn't cause all subsequent tests
// to have logging on if it failed with an exception. // to have logging on if it failed with an exception.
TestHelpers.DisableLogging(); TestHelpers.DisableLogging();
// This is an unfortunate bit of clean up we have to do because MainServer manages things through static
// variables and the VM is not restarted between tests.
if (MainServer.Instance != null)
{
MainServer.RemoveHttpServer(MainServer.Instance.Port);
// MainServer.Instance = null;
}
} }
} }
} }

View File

@ -575,9 +575,9 @@
;; must be set to allow offline messaging to work. ;; must be set to allow offline messaging to work.
; MuteListURL = http://yourserver/Mute.php ; MuteListURL = http://yourserver/Mute.php
;; Control whether group messages are forwarded to offline users. ;; Control whether group invites and notices are stored for offline users.
;; Default is true. ;; Default is true.
;; This applies to the core groups module (Flotsam) only. ;; This applies to both core groups module.
; ForwardOfflineGroupMessages = true ; ForwardOfflineGroupMessages = true
@ -953,7 +953,7 @@
;# {LevelGroupCreate} {Enabled:true} {User level for creating groups} {} 0 ;# {LevelGroupCreate} {Enabled:true} {User level for creating groups} {} 0
;; Minimum user level required to create groups ;; Minimum user level required to create groups
;LevelGroupCreate = 0 ; LevelGroupCreate = 0
;# {Module} {Enabled:true} {Groups module to use? (Use GroupsModule to use Flotsam/Simian)} {Default "Groups Module V2"} Default ;# {Module} {Enabled:true} {Groups module to use? (Use GroupsModule to use Flotsam/Simian)} {Default "Groups Module V2"} Default
;; The default module can use a PHP XmlRpc server from the Flotsam project at ;; The default module can use a PHP XmlRpc server from the Flotsam project at
@ -1006,6 +1006,12 @@
;; Enable Group Notices ;; Enable Group Notices
; NoticesEnabled = true ; NoticesEnabled = true
;# {MessageOnlineUsersOnly} {Module:GroupsModule Module} {Message online users only?} {true false} false
; Experimental option to only message online users rather than all users
; Should make large groups with few online members messaging faster, as the expense of more calls to presence service
; Applies Flotsam Group only. V2 has this always on, no other option
; MessageOnlineUsersOnly = false
;; This makes the Groups modules very chatty on the console. ;; This makes the Groups modules very chatty on the console.
; DebugEnabled = false ; DebugEnabled = false

View File

@ -1612,7 +1612,7 @@
; Experimental option to only message cached online users rather than all users ; Experimental option to only message cached online users rather than all users
; Should make large group with few online members messaging faster, as the expense of more calls to ROBUST presence service ; Should make large group with few online members messaging faster, as the expense of more calls to ROBUST presence service
; This currently only applies to the Flotsam XmlRpc backend ; (Flotsam groups only; in V2 this is always on)
MessageOnlineUsersOnly = false MessageOnlineUsersOnly = false
; Service connectors to the Groups Service. Select one depending on whether you're using a Flotsam XmlRpc backend or a SimianGrid backend ; Service connectors to the Groups Service. Select one depending on whether you're using a Flotsam XmlRpc backend or a SimianGrid backend

View File

@ -23,6 +23,7 @@
InventoryAccessModule = "BasicInventoryAccessModule" InventoryAccessModule = "BasicInventoryAccessModule"
LandServices = "RemoteLandServicesConnector" LandServices = "RemoteLandServicesConnector"
MapImageService = "MapImageServiceModule" MapImageService = "MapImageServiceModule"
SearchModule = "BasicSearchModule"
LandServiceInConnector = true LandServiceInConnector = true
NeighbourServiceInConnector = true NeighbourServiceInConnector = true

View File

@ -28,6 +28,7 @@
FriendsModule = "HGFriendsModule" FriendsModule = "HGFriendsModule"
MapImageService = "MapImageServiceModule" MapImageService = "MapImageServiceModule"
UserManagementModule = "HGUserManagementModule" UserManagementModule = "HGUserManagementModule"
SearchModule = "BasicSearchModule"
LandServiceInConnector = true LandServiceInConnector = true
NeighbourServiceInConnector = true NeighbourServiceInConnector = true

View File

@ -19,6 +19,7 @@
EntityTransferModule = "BasicEntityTransferModule" EntityTransferModule = "BasicEntityTransferModule"
InventoryAccessModule = "BasicInventoryAccessModule" InventoryAccessModule = "BasicInventoryAccessModule"
MapImageService = "MapImageServiceModule" MapImageService = "MapImageServiceModule"
SearchModule = "BasicSearchModule"
LibraryModule = true LibraryModule = true
LLLoginServiceInConnector = true LLLoginServiceInConnector = true

View File

@ -25,6 +25,7 @@
InventoryAccessModule = "HGInventoryAccessModule" InventoryAccessModule = "HGInventoryAccessModule"
FriendsModule = "HGFriendsModule" FriendsModule = "HGFriendsModule"
UserManagementModule = "HGUserManagementModule" UserManagementModule = "HGUserManagementModule"
SearchModule = "BasicSearchModule"
InventoryServiceInConnector = true InventoryServiceInConnector = true
AssetServiceInConnector = true AssetServiceInConnector = true