diff options
author | Charles Krinke | 2009-04-25 18:58:18 +0000 |
---|---|---|
committer | Charles Krinke | 2009-04-25 18:58:18 +0000 |
commit | c17a12544561de8103e1631c1a23dd225bd39698 (patch) | |
tree | 104af1bbb1dd1724b38731b37cf9b82f8d0b6fab | |
parent | Fix another typo in the ini example (diff) | |
download | opensim-SC_OLD-c17a12544561de8103e1631c1a23dd225bd39698.zip opensim-SC_OLD-c17a12544561de8103e1631c1a23dd225bd39698.tar.gz opensim-SC_OLD-c17a12544561de8103e1631c1a23dd225bd39698.tar.bz2 opensim-SC_OLD-c17a12544561de8103e1631c1a23dd225bd39698.tar.xz |
Thank you kindly, MCortez for a patch that:
The attached patch fixes a few problems that people were
having with the Messaging provided by the XmlRpcGroups
optional module, namely:
* Fixes 2x echo in group messaging
* Fixes problems with cross instance, non-neighbor, messaging
3 files changed, 795 insertions, 505 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs index 2a5a319..27cffd6 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupData.cs | |||
@@ -146,11 +146,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
146 | | GroupPowers.VoteOnProposal; | 146 | | GroupPowers.VoteOnProposal; |
147 | param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); | 147 | param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); |
148 | 148 | ||
149 | |||
150 | |||
151 | |||
149 | Hashtable respData = XmlRpcCall("groups.createGroup", param); | 152 | Hashtable respData = XmlRpcCall("groups.createGroup", param); |
150 | 153 | ||
151 | if (respData.Contains("error")) | 154 | if (respData.Contains("error")) |
152 | { | 155 | { |
153 | // UUID is not nullable | 156 | // UUID is not nullable |
157 | |||
154 | return UUID.Zero; | 158 | return UUID.Zero; |
155 | } | 159 | } |
156 | 160 | ||
@@ -224,7 +228,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
224 | public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) | 228 | public GroupRecord GetGroupRecord(UUID GroupID, string GroupName) |
225 | { | 229 | { |
226 | Hashtable param = new Hashtable(); | 230 | Hashtable param = new Hashtable(); |
227 | if (GroupID != UUID.Zero) | 231 | if ((GroupID != null) && (GroupID != UUID.Zero)) |
228 | { | 232 | { |
229 | param["GroupID"] = GroupID.ToString(); | 233 | param["GroupID"] = GroupID.ToString(); |
230 | } | 234 | } |
@@ -233,6 +237,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
233 | param["Name"] = GroupName.ToString(); | 237 | param["Name"] = GroupName.ToString(); |
234 | } | 238 | } |
235 | 239 | ||
240 | |||
236 | Hashtable respData = XmlRpcCall("groups.getGroup", param); | 241 | Hashtable respData = XmlRpcCall("groups.getGroup", param); |
237 | 242 | ||
238 | if (respData.Contains("error")) | 243 | if (respData.Contains("error")) |
@@ -249,6 +254,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
249 | Hashtable param = new Hashtable(); | 254 | Hashtable param = new Hashtable(); |
250 | param["GroupID"] = GroupID.ToString(); | 255 | param["GroupID"] = GroupID.ToString(); |
251 | 256 | ||
257 | |||
252 | Hashtable respData = XmlRpcCall("groups.getGroup", param); | 258 | Hashtable respData = XmlRpcCall("groups.getGroup", param); |
253 | 259 | ||
254 | if (respData.Contains("error")) | 260 | if (respData.Contains("error")) |
@@ -264,6 +270,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
264 | MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; | 270 | MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; |
265 | 271 | ||
266 | return MemberGroupProfile; | 272 | return MemberGroupProfile; |
273 | |||
267 | } | 274 | } |
268 | 275 | ||
269 | private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) | 276 | private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) |
@@ -294,6 +301,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
294 | 301 | ||
295 | private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) | 302 | private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) |
296 | { | 303 | { |
304 | |||
297 | GroupRecord group = new GroupRecord(); | 305 | GroupRecord group = new GroupRecord(); |
298 | group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); | 306 | group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); |
299 | group.GroupName = groupProfile["Name"].ToString(); | 307 | group.GroupName = groupProfile["Name"].ToString(); |
@@ -313,6 +321,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
313 | return group; | 321 | return group; |
314 | } | 322 | } |
315 | 323 | ||
324 | |||
316 | public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) | 325 | public void SetAgentActiveGroup(UUID AgentID, UUID GroupID) |
317 | { | 326 | { |
318 | Hashtable param = new Hashtable(); | 327 | Hashtable param = new Hashtable(); |
@@ -341,6 +350,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
341 | param["ListInProfile"] = ListInProfile ? "1" : "0"; | 350 | param["ListInProfile"] = ListInProfile ? "1" : "0"; |
342 | 351 | ||
343 | XmlRpcCall("groups.setAgentGroupInfo", param); | 352 | XmlRpcCall("groups.setAgentGroupInfo", param); |
353 | |||
344 | } | 354 | } |
345 | 355 | ||
346 | public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) | 356 | public void AddAgentToGroupInvite(UUID inviteID, UUID groupID, UUID roleID, UUID agentID) |
@@ -352,6 +362,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
352 | param["GroupID"] = groupID.ToString(); | 362 | param["GroupID"] = groupID.ToString(); |
353 | 363 | ||
354 | XmlRpcCall("groups.addAgentToGroupInvite", param); | 364 | XmlRpcCall("groups.addAgentToGroupInvite", param); |
365 | |||
355 | } | 366 | } |
356 | 367 | ||
357 | public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) | 368 | public GroupInviteInfo GetAgentToGroupInvite(UUID inviteID) |
@@ -400,6 +411,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
400 | param["GroupID"] = GroupID.ToString(); | 411 | param["GroupID"] = GroupID.ToString(); |
401 | 412 | ||
402 | XmlRpcCall("groups.removeAgentFromGroup", param); | 413 | XmlRpcCall("groups.removeAgentFromGroup", param); |
414 | |||
403 | } | 415 | } |
404 | 416 | ||
405 | public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) | 417 | public void AddAgentToGroupRole(UUID AgentID, UUID GroupID, UUID RoleID) |
@@ -422,6 +434,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
422 | XmlRpcCall("groups.removeAgentFromGroupRole", param); | 434 | XmlRpcCall("groups.removeAgentFromGroupRole", param); |
423 | } | 435 | } |
424 | 436 | ||
437 | |||
425 | public List<DirGroupsReplyData> FindGroups(string search) | 438 | public List<DirGroupsReplyData> FindGroups(string search) |
426 | { | 439 | { |
427 | Hashtable param = new Hashtable(); | 440 | Hashtable param = new Hashtable(); |
@@ -482,6 +495,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
482 | return HashTableToGroupMembershipData(respData); | 495 | return HashTableToGroupMembershipData(respData); |
483 | } | 496 | } |
484 | 497 | ||
498 | |||
485 | public List<GroupMembershipData> GetAgentGroupMemberships(UUID AgentID) | 499 | public List<GroupMembershipData> GetAgentGroupMemberships(UUID AgentID) |
486 | { | 500 | { |
487 | Hashtable param = new Hashtable(); | 501 | Hashtable param = new Hashtable(); |
@@ -529,6 +543,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
529 | } | 543 | } |
530 | 544 | ||
531 | return Roles; | 545 | return Roles; |
546 | |||
547 | |||
532 | } | 548 | } |
533 | 549 | ||
534 | public List<GroupRolesData> GetGroupRoles(UUID GroupID) | 550 | public List<GroupRolesData> GetGroupRoles(UUID GroupID) |
@@ -559,6 +575,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
559 | } | 575 | } |
560 | 576 | ||
561 | return Roles; | 577 | return Roles; |
578 | |||
562 | } | 579 | } |
563 | 580 | ||
564 | private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) | 581 | private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) |
@@ -583,7 +600,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
583 | data.AllowPublish = ((string)respData["AllowPublish"] == "1"); | 600 | data.AllowPublish = ((string)respData["AllowPublish"] == "1"); |
584 | if (respData["Charter"] != null) | 601 | if (respData["Charter"] != null) |
585 | { | 602 | { |
586 | data.Charter = (string)respData["Charter"]; | 603 | data.Charter = (string)respData["Charter"]; |
587 | } | 604 | } |
588 | data.FounderID = new UUID((string)respData["FounderID"]); | 605 | data.FounderID = new UUID((string)respData["FounderID"]); |
589 | data.GroupID = new UUID((string)respData["GroupID"]); | 606 | data.GroupID = new UUID((string)respData["GroupID"]); |
@@ -626,6 +643,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
626 | } | 643 | } |
627 | 644 | ||
628 | return members; | 645 | return members; |
646 | |||
629 | } | 647 | } |
630 | 648 | ||
631 | public List<GroupRoleMembersData> GetGroupRoleMembers(UUID GroupID) | 649 | public List<GroupRoleMembersData> GetGroupRoleMembers(UUID GroupID) |
@@ -642,10 +660,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
642 | foreach (Hashtable membership in respData.Values) | 660 | foreach (Hashtable membership in respData.Values) |
643 | { | 661 | { |
644 | GroupRoleMembersData data = new GroupRoleMembersData(); | 662 | GroupRoleMembersData data = new GroupRoleMembersData(); |
645 | 663 | ||
646 | data.MemberID = new UUID((string)membership["AgentID"]); | 664 | data.MemberID = new UUID((string)membership["AgentID"]); |
647 | data.RoleID = new UUID((string)membership["RoleID"]); | 665 | data.RoleID = new UUID((string)membership["RoleID"]); |
648 | 666 | ||
649 | members.Add(data); | 667 | members.Add(data); |
650 | } | 668 | } |
651 | } | 669 | } |
@@ -685,9 +703,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
685 | param["NoticeID"] = noticeID.ToString(); | 703 | param["NoticeID"] = noticeID.ToString(); |
686 | 704 | ||
687 | Hashtable respData = XmlRpcCall("groups.getGroupNotice", param); | 705 | Hashtable respData = XmlRpcCall("groups.getGroupNotice", param); |
688 | |||
689 | 706 | ||
690 | if (!respData.Contains("error")) | 707 | |
708 | if (respData.Contains("error")) | ||
691 | { | 709 | { |
692 | return null; | 710 | return null; |
693 | } | 711 | } |
@@ -775,7 +793,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
775 | Hashtable error = new Hashtable(); | 793 | Hashtable error = new Hashtable(); |
776 | error.Add("error", "invalid return value"); | 794 | error.Add("error", "invalid return value"); |
777 | return error; | 795 | return error; |
778 | } | 796 | } |
779 | 797 | ||
780 | private void LogRespDataToConsoleError(Hashtable respData) | 798 | private void LogRespDataToConsoleError(Hashtable respData) |
781 | { | 799 | { |
@@ -785,15 +803,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
785 | { | 803 | { |
786 | m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); | 804 | m_log.ErrorFormat("[GROUPDATA] Key: {0}", key); |
787 | 805 | ||
788 | // object o = respData[key]; | ||
789 | |||
790 | string[] lines = respData[key].ToString().Split(new char[] { '\n' }); | 806 | string[] lines = respData[key].ToString().Split(new char[] { '\n' }); |
791 | foreach (string line in lines) | 807 | foreach (string line in lines) |
792 | { | 808 | { |
793 | m_log.ErrorFormat("[GROUPDATA] {0}", line); | 809 | m_log.ErrorFormat("[GROUPDATA] {0}", line); |
794 | } | 810 | } |
811 | |||
795 | } | 812 | } |
796 | } | 813 | } |
814 | |||
797 | } | 815 | } |
798 | 816 | ||
799 | public class GroupNoticeInfo | 817 | public class GroupNoticeInfo |
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs index b1b25aa..b1322ab 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsMessaging.cs | |||
@@ -26,7 +26,6 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | //using System.Collections; | ||
30 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
31 | using System.Reflection; | 30 | using System.Reflection; |
32 | 31 | ||
@@ -47,25 +46,27 @@ using Caps = OpenSim.Framework.Communications.Capabilities.Caps; | |||
47 | 46 | ||
48 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | 47 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups |
49 | { | 48 | { |
50 | public class XmlRpcGroupsMessaging : INonSharedRegionModule | 49 | public class XmlRpcGroupsMessaging : ISharedRegionModule |
51 | { | 50 | { |
52 | 51 | ||
53 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
54 | 53 | ||
55 | private List<Scene> m_SceneList = new List<Scene>(); | 54 | private List<Scene> m_sceneList = new List<Scene>(); |
56 | 55 | ||
57 | // must be NonShared for this to work, otherewise we may actually get multiple active clients | 56 | private IMessageTransferModule m_msgTransferModule = null; |
58 | private Dictionary<Guid, IClientAPI> m_ActiveClients = new Dictionary<Guid, IClientAPI>(); | ||
59 | 57 | ||
60 | private IMessageTransferModule m_MsgTransferModule = null; | 58 | private IGroupsModule m_groupsModule = null; |
59 | |||
60 | // TODO: Move this off to the xmlrpc server | ||
61 | public Dictionary<Guid, List<Guid>> m_agentsInGroupSession = new Dictionary<Guid, List<Guid>>(); | ||
62 | public Dictionary<Guid, List<Guid>> m_agentsDroppedSession = new Dictionary<Guid, List<Guid>>(); | ||
61 | 63 | ||
62 | private IGroupsModule m_GroupsModule = null; | ||
63 | 64 | ||
64 | // Config Options | 65 | // Config Options |
65 | private bool m_GroupMessagingEnabled = true; | 66 | private bool m_groupMessagingEnabled = true; |
66 | private bool m_debugEnabled = true; | 67 | private bool m_debugEnabled = true; |
67 | 68 | ||
68 | #region IRegionModule Members | 69 | #region IRegionModuleBase Members |
69 | 70 | ||
70 | public void Initialise(IConfigSource config) | 71 | public void Initialise(IConfigSource config) |
71 | { | 72 | { |
@@ -90,14 +91,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
90 | if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") | 91 | if (groupsConfig.GetString("Module", "Default") != "XmlRpcGroups") |
91 | { | 92 | { |
92 | m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); | 93 | m_log.Info("[GROUPS-MESSAGING]: Config Groups Module not set to XmlRpcGroups"); |
93 | m_GroupMessagingEnabled = false; | 94 | m_groupMessagingEnabled = false; |
94 | 95 | ||
95 | return; | 96 | return; |
96 | } | 97 | } |
97 | 98 | ||
98 | m_GroupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); | 99 | m_groupMessagingEnabled = groupsConfig.GetBoolean("XmlRpcMessagingEnabled", true); |
99 | 100 | ||
100 | if (!m_GroupMessagingEnabled) | 101 | if (!m_groupMessagingEnabled) |
101 | { | 102 | { |
102 | m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled."); | 103 | m_log.Info("[GROUPS-MESSAGING]: XmlRpcGroups Messaging disabled."); |
103 | return; | 104 | return; |
@@ -113,76 +114,74 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
113 | 114 | ||
114 | public void AddRegion(Scene scene) | 115 | public void AddRegion(Scene scene) |
115 | { | 116 | { |
117 | // NoOp | ||
116 | } | 118 | } |
117 | public void RegionLoaded(Scene scene) | 119 | public void RegionLoaded(Scene scene) |
118 | { | 120 | { |
119 | if (!m_GroupMessagingEnabled) | 121 | if (!m_groupMessagingEnabled) |
120 | return; | 122 | return; |
121 | 123 | ||
122 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 124 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
123 | 125 | ||
124 | 126 | ||
125 | m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); | 127 | m_groupsModule = scene.RequestModuleInterface<IGroupsModule>(); |
126 | 128 | ||
127 | // No groups module, no groups messaging | 129 | // No groups module, no groups messaging |
128 | if (m_GroupsModule == null) | 130 | if (m_groupsModule == null) |
129 | { | 131 | { |
130 | m_GroupMessagingEnabled = false; | 132 | m_groupMessagingEnabled = false; |
131 | m_log.Info("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); | 133 | m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, XmlRpcGroupsMessaging is now disabled."); |
132 | Close(); | 134 | Close(); |
133 | return; | 135 | return; |
134 | } | 136 | } |
135 | 137 | ||
136 | m_MsgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>(); | 138 | m_msgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>(); |
137 | 139 | ||
138 | // No message transfer module, no groups messaging | 140 | // No message transfer module, no groups messaging |
139 | if (m_MsgTransferModule == null) | 141 | if (m_msgTransferModule == null) |
140 | { | 142 | { |
141 | m_GroupMessagingEnabled = false; | 143 | m_groupMessagingEnabled = false; |
142 | m_log.Info("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); | 144 | m_log.Error("[GROUPS-MESSAGING]: Could not get MessageTransferModule"); |
143 | Close(); | 145 | Close(); |
144 | return; | 146 | return; |
145 | } | 147 | } |
146 | 148 | ||
147 | 149 | ||
148 | m_SceneList.Add(scene); | 150 | m_sceneList.Add(scene); |
149 | 151 | ||
150 | scene.EventManager.OnNewClient += OnNewClient; | 152 | scene.EventManager.OnNewClient += OnNewClient; |
151 | scene.EventManager.OnClientClosed += OnClientClosed; | ||
152 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; | 153 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; |
153 | 154 | ||
154 | } | 155 | } |
155 | 156 | ||
156 | public void RemoveRegion(Scene scene) | 157 | public void RemoveRegion(Scene scene) |
157 | { | 158 | { |
158 | if (!m_GroupMessagingEnabled) | 159 | if (!m_groupMessagingEnabled) |
159 | return; | 160 | return; |
160 | 161 | ||
161 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 162 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
162 | 163 | ||
163 | m_SceneList.Remove(scene); | 164 | m_sceneList.Remove(scene); |
164 | } | 165 | } |
165 | 166 | ||
166 | 167 | ||
167 | public void Close() | 168 | public void Close() |
168 | { | 169 | { |
169 | if (!m_GroupMessagingEnabled) | 170 | if (!m_groupMessagingEnabled) |
170 | return; | 171 | return; |
171 | 172 | ||
172 | m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); | 173 | if(m_debugEnabled) m_log.Debug("[GROUPS-MESSAGING]: Shutting down XmlRpcGroupsMessaging module."); |
173 | |||
174 | 174 | ||
175 | foreach (Scene scene in m_SceneList) | 175 | foreach (Scene scene in m_sceneList) |
176 | { | 176 | { |
177 | scene.EventManager.OnNewClient -= OnNewClient; | 177 | scene.EventManager.OnNewClient -= OnNewClient; |
178 | scene.EventManager.OnClientClosed -= OnClientClosed; | ||
179 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; | 178 | scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; |
180 | } | 179 | } |
181 | 180 | ||
182 | m_SceneList.Clear(); | 181 | m_sceneList.Clear(); |
183 | 182 | ||
184 | m_GroupsModule = null; | 183 | m_groupsModule = null; |
185 | m_MsgTransferModule = null; | 184 | m_msgTransferModule = null; |
186 | } | 185 | } |
187 | 186 | ||
188 | public string Name | 187 | public string Name |
@@ -192,195 +191,293 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
192 | 191 | ||
193 | #endregion | 192 | #endregion |
194 | 193 | ||
195 | #region SimGridEventHandlers | 194 | #region ISharedRegionModule Members |
196 | 195 | ||
197 | private void OnNewClient(IClientAPI client) | 196 | public void PostInitialise() |
198 | { | 197 | { |
199 | RegisterClientAgent(client); | 198 | // NoOp |
200 | } | 199 | } |
201 | private void OnClientClosed(UUID AgentId) | 200 | |
201 | #endregion | ||
202 | |||
203 | #region SimGridEventHandlers | ||
204 | |||
205 | private void OnNewClient(IClientAPI client) | ||
202 | { | 206 | { |
203 | UnregisterClientAgent(AgentId); | 207 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); |
208 | |||
209 | client.OnInstantMessage += OnInstantMessage; | ||
204 | } | 210 | } |
205 | 211 | ||
206 | private void OnGridInstantMessage(GridInstantMessage msg) | 212 | private void OnGridInstantMessage(GridInstantMessage msg) |
207 | { | 213 | { |
208 | m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 214 | // The instant message module will only deliver messages of dialog types: |
215 | // MessageFromAgent, StartTyping, StopTyping, MessageFromObject | ||
216 | // | ||
217 | // Any other message type will not be delivered to a client by the | ||
218 | // Instant Message Module | ||
219 | |||
220 | |||
221 | if (m_debugEnabled) | ||
222 | { | ||
223 | m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | ||
209 | 224 | ||
210 | DebugGridInstantMessage(msg); | 225 | DebugGridInstantMessage(msg); |
226 | } | ||
211 | 227 | ||
212 | // Incoming message from a group | 228 | // Incoming message from a group |
213 | if ((msg.dialog == (byte)InstantMessageDialog.SessionSend) && (msg.fromGroup == true)) | 229 | if ((msg.fromGroup == true) && |
230 | ( (msg.dialog == (byte)InstantMessageDialog.SessionSend) | ||
231 | || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) | ||
232 | || (msg.dialog == (byte)InstantMessageDialog.SessionDrop) | ||
233 | )) | ||
234 | { | ||
235 | ProcessMessageFromGroupSession(msg); | ||
236 | } | ||
237 | |||
238 | } | ||
239 | |||
240 | private void ProcessMessageFromGroupSession(GridInstantMessage msg) | ||
241 | { | ||
242 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); | ||
243 | |||
244 | switch (msg.dialog) | ||
245 | { | ||
246 | case (byte)InstantMessageDialog.SessionAdd: | ||
247 | AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); | ||
248 | break; | ||
249 | |||
250 | case (byte)InstantMessageDialog.SessionDrop: | ||
251 | RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); | ||
252 | break; | ||
253 | |||
254 | case (byte)InstantMessageDialog.SessionSend: | ||
255 | if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) | ||
256 | && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) | ||
214 | { | 257 | { |
215 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnGridInstantMessage from group session {0} going to agent {1}", msg.fromAgentID, msg.toAgentID); | 258 | // Agent not in session and hasn't dropped from session |
259 | // Add them to the session for now, and Invite them | ||
260 | AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); | ||
216 | 261 | ||
217 | if (m_ActiveClients.ContainsKey(msg.toAgentID)) | 262 | UUID toAgentID = new UUID(msg.toAgentID); |
263 | IClientAPI activeClient = GetActiveClient(toAgentID); | ||
264 | if (activeClient != null) | ||
218 | { | 265 | { |
219 | UUID GroupID = new UUID(msg.fromAgentID); | 266 | UUID groupID = new UUID(msg.fromAgentID); |
220 | // SendMessageToGroup(im); | ||
221 | 267 | ||
222 | GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); | 268 | GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); |
223 | if (GroupInfo != null) | 269 | if (groupInfo != null) |
224 | { | 270 | { |
225 | // TODO: Check to see if already a member of session, if so, do not send chatterbox, just forward message | 271 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); |
226 | |||
227 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Sending chatterbox invite instant message"); | ||
228 | 272 | ||
229 | // Force? open the group session dialog??? | 273 | // Force? open the group session dialog??? |
230 | IEventQueue eq = m_ActiveClients[msg.toAgentID].Scene.RequestModuleInterface<IEventQueue>(); | 274 | IEventQueue eq = activeClient.Scene.RequestModuleInterface<IEventQueue>(); |
231 | eq.ChatterboxInvitation( | 275 | eq.ChatterboxInvitation( |
232 | GroupID, | 276 | groupID |
233 | GroupInfo.GroupName, | 277 | , groupInfo.GroupName |
234 | new UUID(msg.fromAgentID), | 278 | , new UUID(msg.fromAgentID) |
235 | msg.message, new UUID(msg.toAgentID), | 279 | , msg.message, new UUID(msg.toAgentID) |
236 | msg.fromAgentName, | 280 | , msg.fromAgentName |
237 | msg.dialog, | 281 | , msg.dialog |
238 | msg.timestamp, | 282 | , msg.timestamp |
239 | msg.offline == 1, | 283 | , msg.offline == 1 |
240 | (int)msg.ParentEstateID, | 284 | , (int)msg.ParentEstateID |
241 | msg.Position, | 285 | , msg.Position |
242 | 1, | 286 | , 1 |
243 | new UUID(msg.imSessionID), | 287 | , new UUID(msg.imSessionID) |
244 | msg.fromGroup, | 288 | , msg.fromGroup |
245 | Utils.StringToBytes(GroupInfo.GroupName)); | 289 | , Utils.StringToBytes(groupInfo.GroupName) |
290 | ); | ||
246 | 291 | ||
247 | eq.ChatterBoxSessionAgentListUpdates( | 292 | eq.ChatterBoxSessionAgentListUpdates( |
248 | new UUID(GroupID), | 293 | new UUID(groupID) |
249 | new UUID(msg.fromAgentID), | 294 | , new UUID(msg.fromAgentID) |
250 | new UUID(msg.toAgentID), | 295 | , new UUID(msg.toAgentID) |
251 | false, //canVoiceChat | 296 | , false //canVoiceChat |
252 | false, //isModerator | 297 | , false //isModerator |
253 | false); //text mute | 298 | , false //text mute |
299 | ); | ||
300 | |||
254 | } | 301 | } |
255 | } | 302 | } |
256 | } | 303 | } |
304 | else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) | ||
305 | { | ||
306 | // User hasn't dropped, so they're in the session, | ||
307 | // maybe we should deliver it. | ||
308 | IClientAPI client = GetActiveClient(new UUID(msg.toAgentID)); | ||
309 | if (client != null) | ||
310 | { | ||
311 | // Deliver locally, directly | ||
312 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} locally", client.Name); | ||
313 | client.SendInstantMessage(msg); | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | m_log.WarnFormat("[GROUPS-MESSAGING] Received a message over the grid for a client that isn't here: {0}", msg.toAgentID); | ||
318 | } | ||
319 | } | ||
320 | break; | ||
257 | 321 | ||
322 | default: | ||
323 | m_log.WarnFormat("[GROUPS-MESSAGING] I don't know how to proccess a {0} message.", ((InstantMessageDialog)msg.dialog).ToString()); | ||
324 | break; | ||
325 | } | ||
258 | } | 326 | } |
259 | 327 | ||
328 | |||
329 | |||
260 | #endregion | 330 | #endregion |
261 | 331 | ||
262 | #region ClientEvents | 332 | #region ClientEvents |
263 | private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) | ||
264 | { | ||
265 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | ||
266 | |||
267 | DebugGridInstantMessage(im); | ||
268 | 333 | ||
269 | // Start group IM session | 334 | private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) |
270 | if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) | 335 | { |
336 | if( m_agentsInGroupSession.ContainsKey(sessionID) ) | ||
271 | { | 337 | { |
272 | UUID GroupID = new UUID(im.toAgentID); | 338 | // If in session remove |
273 | 339 | if( m_agentsInGroupSession[sessionID].Contains(agentID) ) | |
274 | GroupRecord GroupInfo = m_GroupsModule.GetGroupRecord(GroupID); | ||
275 | if (GroupInfo != null) | ||
276 | { | 340 | { |
277 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Start Group Session for {0}", GroupInfo.GroupName); | 341 | m_agentsInGroupSession[sessionID].Remove(agentID); |
278 | 342 | } | |
279 | // remoteClient.SendInstantMessage(new GridInstantMessage(remoteClient.Scene, GroupID, GroupProfile.Name, remoteClient.AgentId, (byte)OpenMetaverse.InstantMessageDialog.SessionSend, true, "Welcome", GroupID, false, new Vector3(), new byte[0])); | ||
280 | |||
281 | ChatterBoxSessionStartReplyViaCaps(remoteClient, GroupInfo.GroupName, GroupID); | ||
282 | 343 | ||
283 | IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); | 344 | // If not in dropped list, add |
284 | queue.ChatterBoxSessionAgentListUpdates( | 345 | if( !m_agentsDroppedSession[sessionID].Contains(agentID) ) |
285 | new UUID(GroupID), | 346 | { |
286 | new UUID(im.fromAgentID), | 347 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Dropped {1} from session {0}", sessionID, agentID); |
287 | new UUID(im.toAgentID), | 348 | m_agentsDroppedSession[sessionID].Add(agentID); |
288 | false, //canVoiceChat | ||
289 | false, //isModerator | ||
290 | false); //text mute | ||
291 | } | 349 | } |
292 | } | 350 | } |
351 | } | ||
293 | 352 | ||
294 | // Send a message to a group | 353 | private void AddAgentToGroupSession(Guid agentID, Guid sessionID) |
295 | if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) | 354 | { |
296 | { | 355 | // Add Session Status if it doesn't exist for this session |
297 | UUID GroupID = new UUID(im.toAgentID); | 356 | CreateGroupSessionTracking(sessionID); |
298 | 357 | ||
299 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Send message to session for group {0}", GroupID); | 358 | // If nessesary, remove from dropped list |
359 | if( m_agentsDroppedSession[sessionID].Contains(agentID) ) | ||
360 | { | ||
361 | m_agentsDroppedSession[sessionID].Remove(agentID); | ||
362 | } | ||
300 | 363 | ||
301 | SendMessageToGroup(im, GroupID); | 364 | // If nessesary, add to in session list |
365 | if( !m_agentsInGroupSession[sessionID].Contains(agentID) ) | ||
366 | { | ||
367 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Added {1} to session {0}", sessionID, agentID); | ||
368 | m_agentsInGroupSession[sessionID].Add(agentID); | ||
302 | } | 369 | } |
370 | } | ||
303 | 371 | ||
304 | // Incoming message from a group | 372 | private void CreateGroupSessionTracking(Guid sessionID) |
305 | if ((im.dialog == (byte)InstantMessageDialog.SessionSend) && (im.fromGroup == true)) | 373 | { |
374 | if (!m_agentsInGroupSession.ContainsKey(sessionID)) | ||
306 | { | 375 | { |
307 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] Message from group session {0} going to agent {1}", im.fromAgentID, im.toAgentID); | 376 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Creating session tracking for : {0}", sessionID); |
377 | m_agentsInGroupSession.Add(sessionID, new List<Guid>()); | ||
378 | m_agentsDroppedSession.Add(sessionID, new List<Guid>()); | ||
308 | } | 379 | } |
309 | } | 380 | } |
310 | #endregion | ||
311 | 381 | ||
312 | private void RegisterClientAgent(IClientAPI client) | 382 | private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) |
313 | { | 383 | { |
314 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 384 | if (m_debugEnabled) |
385 | { | ||
386 | m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | ||
315 | 387 | ||
316 | lock (m_ActiveClients) | 388 | DebugGridInstantMessage(im); |
389 | } | ||
390 | |||
391 | // Start group IM session | ||
392 | if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) | ||
317 | { | 393 | { |
318 | if (!m_ActiveClients.ContainsKey(client.AgentId.Guid)) | 394 | UUID groupID = new UUID(im.toAgentID); |
395 | |||
396 | GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); | ||
397 | if (groupInfo != null) | ||
319 | { | 398 | { |
320 | client.OnInstantMessage += OnInstantMessage; | 399 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Start Group Session for {0}", groupInfo.GroupName); |
321 | 400 | ||
322 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage registered for {0}", client.Name); | 401 | AddAgentToGroupSession(im.fromAgentID, im.imSessionID); |
323 | 402 | ||
324 | m_ActiveClients.Add(client.AgentId.Guid, client); | 403 | ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); |
325 | } | ||
326 | else | ||
327 | { | ||
328 | // Remove old client connection for this agent | ||
329 | UnregisterClientAgent(client.AgentId); | ||
330 | 404 | ||
331 | // Add new client connection | 405 | IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); |
332 | RegisterClientAgent(client); | 406 | queue.ChatterBoxSessionAgentListUpdates( |
407 | new UUID(groupID) | ||
408 | , new UUID(im.fromAgentID) | ||
409 | , new UUID(im.toAgentID) | ||
410 | , false //canVoiceChat | ||
411 | , false //isModerator | ||
412 | , false //text mute | ||
413 | ); | ||
333 | } | 414 | } |
334 | } | 415 | } |
335 | } | 416 | |
336 | private void UnregisterClientAgent(UUID agentID) | 417 | // Send a message from locally connected client to a group |
337 | { | 418 | if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) |
338 | lock (m_ActiveClients) | ||
339 | { | 419 | { |
340 | if (m_ActiveClients.ContainsKey(agentID.Guid)) | 420 | UUID groupID = new UUID(im.toAgentID); |
341 | { | ||
342 | IClientAPI client = m_ActiveClients[agentID.Guid]; | ||
343 | client.OnInstantMessage -= OnInstantMessage; | ||
344 | 421 | ||
345 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] OnInstantMessage unregistered for {0}", client.Name); | 422 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); |
346 | 423 | ||
347 | m_ActiveClients.Remove(agentID.Guid); | 424 | SendMessageToGroup(im, groupID); |
348 | } | ||
349 | else | ||
350 | { | ||
351 | m_log.InfoFormat("[GROUPS-MESSAGING] Client closed that wasn't registered here."); | ||
352 | } | ||
353 | } | 425 | } |
354 | } | 426 | } |
427 | #endregion | ||
355 | 428 | ||
356 | private void SendMessageToGroup(GridInstantMessage im, UUID groupID) | 429 | private void SendMessageToGroup(GridInstantMessage im, UUID groupID) |
357 | { | 430 | { |
358 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 431 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
432 | |||
359 | 433 | ||
434 | foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) | ||
435 | { | ||
436 | if (m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) | ||
437 | { | ||
438 | // Don't deliver messages to people who have dropped this session | ||
439 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} has dropped session, not delivering to them", member.AgentID); | ||
440 | continue; | ||
441 | } | ||
442 | |||
443 | // Copy Message | ||
360 | GridInstantMessage msg = new GridInstantMessage(); | 444 | GridInstantMessage msg = new GridInstantMessage(); |
361 | msg.imSessionID = im.imSessionID; | 445 | msg.imSessionID = im.imSessionID; |
362 | msg.fromAgentID = im.imSessionID; // GroupID | ||
363 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | ||
364 | msg.fromAgentName = im.fromAgentName; | 446 | msg.fromAgentName = im.fromAgentName; |
365 | msg.message = im.message; | 447 | msg.message = im.message; |
366 | msg.dialog = im.dialog; | 448 | msg.dialog = im.dialog; |
367 | msg.fromGroup = true; | 449 | msg.offline = im.offline; |
368 | msg.offline = (byte)0; | ||
369 | msg.ParentEstateID = im.ParentEstateID; | 450 | msg.ParentEstateID = im.ParentEstateID; |
370 | msg.Position = im.Position; | 451 | msg.Position = im.Position; |
371 | msg.RegionID = im.RegionID; | 452 | msg.RegionID = im.RegionID; |
372 | msg.binaryBucket = new byte[1]{0}; | 453 | msg.binaryBucket = im.binaryBucket; |
454 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | ||
455 | |||
456 | // Updat Pertinate fields to make it a "group message" | ||
457 | msg.fromAgentID = groupID.Guid; | ||
458 | msg.fromGroup = true; | ||
373 | 459 | ||
374 | foreach (GroupMembersData member in m_GroupsModule.GroupMembersRequest(null, groupID)) | ||
375 | { | ||
376 | msg.toAgentID = member.AgentID.Guid; | 460 | msg.toAgentID = member.AgentID.Guid; |
377 | m_MsgTransferModule.SendInstantMessage(msg, delegate(bool success) {}); | 461 | |
462 | IClientAPI client = GetActiveClient(member.AgentID); | ||
463 | if (client == null) | ||
464 | { | ||
465 | // If they're not local, forward across the grid | ||
466 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Delivering to {0} via Grid", member.AgentID); | ||
467 | m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); | ||
468 | } | ||
469 | else | ||
470 | { | ||
471 | // Deliver locally, directly | ||
472 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); | ||
473 | ProcessMessageFromGroupSession(msg); | ||
474 | } | ||
378 | } | 475 | } |
379 | } | 476 | } |
380 | 477 | ||
381 | void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) | 478 | void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) |
382 | { | 479 | { |
383 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 480 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
384 | 481 | ||
385 | OSDMap moderatedMap = new OSDMap(4); | 482 | OSDMap moderatedMap = new OSDMap(4); |
386 | moderatedMap.Add("voice", OSD.FromBoolean(false)); | 483 | moderatedMap.Add("voice", OSD.FromBoolean(false)); |
@@ -398,12 +495,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
398 | bodyMap.Add("success", OSD.FromBoolean(true)); | 495 | bodyMap.Add("success", OSD.FromBoolean(true)); |
399 | bodyMap.Add("session_info", sessionMap); | 496 | bodyMap.Add("session_info", sessionMap); |
400 | 497 | ||
498 | |||
401 | IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); | 499 | IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); |
402 | 500 | ||
403 | if (queue != null) | 501 | if (queue != null) |
404 | { | 502 | { |
405 | queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); | 503 | queue.Enqueue(EventQueueHelper.buildEvent("ChatterBoxSessionStartReply", bodyMap), remoteClient.AgentId); |
406 | } | 504 | } |
505 | |||
407 | } | 506 | } |
408 | 507 | ||
409 | 508 | ||
@@ -422,5 +521,39 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
422 | m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); | 521 | m_log.WarnFormat("[GROUPS-MESSAGING] IM: binaryBucket({0})", OpenMetaverse.Utils.BytesToHexString(im.binaryBucket, "BinaryBucket")); |
423 | } | 522 | } |
424 | } | 523 | } |
524 | |||
525 | #region Client Tools | ||
526 | |||
527 | /// <summary> | ||
528 | /// Try to find an active IClientAPI reference for agentID giving preference to root connections | ||
529 | /// </summary> | ||
530 | private IClientAPI GetActiveClient(UUID agentID) | ||
531 | { | ||
532 | IClientAPI child = null; | ||
533 | |||
534 | // Try root avatar first | ||
535 | foreach (Scene scene in m_sceneList) | ||
536 | { | ||
537 | if (scene.Entities.ContainsKey(agentID) && | ||
538 | scene.Entities[agentID] is ScenePresence) | ||
539 | { | ||
540 | ScenePresence user = (ScenePresence)scene.Entities[agentID]; | ||
541 | if (!user.IsChildAgent) | ||
542 | { | ||
543 | return user.ControllingClient; | ||
544 | } | ||
545 | else | ||
546 | { | ||
547 | child = user.ControllingClient; | ||
548 | } | ||
549 | } | ||
550 | } | ||
551 | |||
552 | // If we didn't find a root, then just return whichever child we found, or null if none | ||
553 | return child; | ||
554 | } | ||
555 | |||
556 | #endregion | ||
425 | } | 557 | } |
558 | |||
426 | } | 559 | } |
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs index 69c7258..d5cd7e2 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsModule.cs | |||
@@ -30,7 +30,6 @@ using System.Collections.Generic; | |||
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | 31 | ||
32 | using System.Collections; | 32 | using System.Collections; |
33 | //using Nwc.XmlRpc; | ||
34 | 33 | ||
35 | using log4net; | 34 | using log4net; |
36 | using Nini.Config; | 35 | using Nini.Config; |
@@ -39,6 +38,7 @@ using OpenMetaverse; | |||
39 | using OpenMetaverse.StructuredData; | 38 | using OpenMetaverse.StructuredData; |
40 | 39 | ||
41 | using OpenSim.Framework; | 40 | using OpenSim.Framework; |
41 | using OpenSim.Framework.Communications; | ||
42 | using OpenSim.Region.CoreModules.Framework.EventQueue; | 42 | using OpenSim.Region.CoreModules.Framework.EventQueue; |
43 | using OpenSim.Region.Framework.Interfaces; | 43 | using OpenSim.Region.Framework.Interfaces; |
44 | using OpenSim.Region.Framework.Scenes; | 44 | using OpenSim.Region.Framework.Scenes; |
@@ -50,7 +50,7 @@ using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; | |||
50 | 50 | ||
51 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | 51 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups |
52 | { | 52 | { |
53 | public class XmlRpcGroupsModule : INonSharedRegionModule, IGroupsModule | 53 | public class XmlRpcGroupsModule : ISharedRegionModule, IGroupsModule |
54 | { | 54 | { |
55 | /// <summary> | 55 | /// <summary> |
56 | /// ; To use this module, you must specify the following in your OpenSim.ini | 56 | /// ; To use this module, you must specify the following in your OpenSim.ini |
@@ -75,11 +75,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
75 | 75 | ||
76 | private List<Scene> m_sceneList = new List<Scene>(); | 76 | private List<Scene> m_sceneList = new List<Scene>(); |
77 | 77 | ||
78 | // This only works when running as non-Shared, in shared, there may be multiple IClientAPIs for a single client | ||
79 | private Dictionary<UUID, IClientAPI> m_activeClients = new Dictionary<UUID, IClientAPI>(); | ||
80 | |||
81 | private IMessageTransferModule m_msgTransferModule = null; | 78 | private IMessageTransferModule m_msgTransferModule = null; |
82 | 79 | ||
83 | private IGroupDataProvider m_groupData = null; | 80 | private IGroupDataProvider m_groupData = null; |
84 | 81 | ||
85 | // Configuration settings | 82 | // Configuration settings |
@@ -88,7 +85,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
88 | private bool m_groupNoticesEnabled = true; | 85 | private bool m_groupNoticesEnabled = true; |
89 | private bool m_debugEnabled = true; | 86 | private bool m_debugEnabled = true; |
90 | 87 | ||
91 | #region IRegionModule Members | 88 | #region IRegionModuleBase Members |
92 | 89 | ||
93 | public void Initialise(IConfigSource config) | 90 | public void Initialise(IConfigSource config) |
94 | { | 91 | { |
@@ -142,24 +139,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
142 | if (!m_groupsEnabled) | 139 | if (!m_groupsEnabled) |
143 | return; | 140 | return; |
144 | 141 | ||
145 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 142 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
146 | 143 | ||
147 | m_msgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>(); | ||
148 | |||
149 | // No message transfer module, no notices, group invites, rejects, ejects, etc | ||
150 | if (m_msgTransferModule == null) | 144 | if (m_msgTransferModule == null) |
151 | { | 145 | { |
152 | m_groupsEnabled = false; | 146 | m_msgTransferModule = scene.RequestModuleInterface<IMessageTransferModule>(); |
153 | m_log.Info("[GROUPS]: Could not get MessageTransferModule"); | 147 | |
154 | Close(); | 148 | // No message transfer module, no notices, group invites, rejects, ejects, etc |
155 | return; | 149 | if (m_msgTransferModule == null) |
150 | { | ||
151 | m_groupsEnabled = false; | ||
152 | m_log.Error("[GROUPS]: Could not get MessageTransferModule"); | ||
153 | Close(); | ||
154 | return; | ||
155 | } | ||
156 | } | 156 | } |
157 | 157 | ||
158 | m_sceneList.Add(scene); | 158 | lock (m_sceneList) |
159 | { | ||
160 | m_sceneList.Add(scene); | ||
161 | } | ||
159 | 162 | ||
160 | scene.EventManager.OnNewClient += OnNewClient; | 163 | scene.EventManager.OnNewClient += OnNewClient; |
161 | scene.EventManager.OnClientClosed += OnClientClosed; | ||
162 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; | 164 | scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; |
165 | |||
166 | // The InstantMessageModule itself doesn't do this, | ||
167 | // so lets see if things explode if we don't do it | ||
168 | // scene.EventManager.OnClientClosed += OnClientClosed; | ||
169 | |||
163 | } | 170 | } |
164 | 171 | ||
165 | public void RemoveRegion(Scene scene) | 172 | public void RemoveRegion(Scene scene) |
@@ -167,117 +174,117 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
167 | if (!m_groupsEnabled) | 174 | if (!m_groupsEnabled) |
168 | return; | 175 | return; |
169 | 176 | ||
170 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 177 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
171 | 178 | ||
172 | m_sceneList.Remove(scene); | 179 | lock (m_sceneList) |
180 | { | ||
181 | m_sceneList.Remove(scene); | ||
182 | } | ||
173 | } | 183 | } |
174 | 184 | ||
175 | public void Close() | 185 | public void Close() |
176 | { | 186 | { |
177 | if (!m_groupsEnabled) | 187 | if (!m_groupsEnabled) |
178 | return; | 188 | return; |
179 | m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); | 189 | |
190 | if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down XmlRpcGroups module."); | ||
180 | } | 191 | } |
181 | 192 | ||
182 | public string Name | 193 | public string Name |
183 | { | 194 | { |
184 | get { return "XmlRpcGroupsModule"; } | 195 | get { return "XmlRpcGroupsModule"; } |
185 | } | 196 | } |
197 | |||
186 | #endregion | 198 | #endregion |
187 | 199 | ||
188 | private void UpdateAllClientsWithGroupInfo() | 200 | #region ISharedRegionModule Members |
189 | { | ||
190 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | ||
191 | foreach (IClientAPI client in m_activeClients.Values) | ||
192 | { | ||
193 | UpdateClientWithGroupInfo(client); | ||
194 | } | ||
195 | } | ||
196 | 201 | ||
197 | private void UpdateClientWithGroupInfo(IClientAPI client) | 202 | public void PostInitialise() |
198 | { | 203 | { |
199 | m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); | 204 | // NoOp |
200 | OnAgentDataUpdateRequest(client, client.AgentId, UUID.Zero); | ||
201 | |||
202 | |||
203 | // Need to send a group membership update to the client | ||
204 | // UDP version doesn't seem to behave nicely | ||
205 | // client.SendGroupMembership(GetMembershipData(client.AgentId)); | ||
206 | |||
207 | GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(client.AgentId).ToArray(); | ||
208 | |||
209 | SendGroupMembershipInfoViaCaps(client, membershipData); | ||
210 | client.SendAvatarGroupsReply(client.AgentId, membershipData); | ||
211 | |||
212 | } | 205 | } |
213 | 206 | ||
207 | #endregion | ||
208 | |||
214 | #region EventHandlers | 209 | #region EventHandlers |
215 | private void OnNewClient(IClientAPI client) | 210 | private void OnNewClient(IClientAPI client) |
216 | { | 211 | { |
217 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 212 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
218 | 213 | ||
219 | 214 | client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; | |
220 | lock (m_activeClients) | 215 | client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; |
221 | { | 216 | client.OnDirFindQuery += OnDirFindQuery; |
222 | if (!m_activeClients.ContainsKey(client.AgentId)) | 217 | client.OnRequestAvatarProperties += OnRequestAvatarProperties; |
223 | { | ||
224 | client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest; | ||
225 | client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; | ||
226 | client.OnDirFindQuery += OnDirFindQuery; | ||
227 | client.OnInstantMessage += OnInstantMessage; | ||
228 | 218 | ||
229 | m_activeClients.Add(client.AgentId, client); | 219 | // Used for Notices and Group Invites/Accept/Reject |
230 | } | 220 | client.OnInstantMessage += OnInstantMessage; |
231 | } | 221 | |
222 | SendAgentGroupDataUpdate(client, client.AgentId); | ||
223 | } | ||
232 | 224 | ||
233 | UpdateClientWithGroupInfo(client); | 225 | private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) |
226 | { | ||
227 | GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(avatarID).ToArray(); | ||
228 | remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); | ||
234 | } | 229 | } |
235 | 230 | ||
236 | private void OnClientClosed(UUID agentId) | 231 | /* |
232 | * This becomes very problematic in a shared module. In a shared module you may have more then one | ||
233 | * reference to IClientAPI's, one for 0 or 1 root connections, and 0 or more child connections. | ||
234 | * The OnClientClosed event does not provide anything to indicate which one of those should be closed | ||
235 | * nor does it provide what scene it was from so that the specific reference can be looked up. | ||
236 | * The InstantMessageModule.cs does not currently worry about unregistering the handles, | ||
237 | * and it should be an issue, since it's the client that references us not the other way around | ||
238 | * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed | ||
239 | private void OnClientClosed(UUID AgentId) | ||
237 | { | 240 | { |
238 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 241 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
239 | 242 | ||
240 | lock (m_activeClients) | 243 | lock (m_ActiveClients) |
241 | { | 244 | { |
242 | if (m_activeClients.ContainsKey(agentId)) | 245 | if (m_ActiveClients.ContainsKey(AgentId)) |
243 | { | 246 | { |
244 | IClientAPI client = m_activeClients[agentId]; | 247 | IClientAPI client = m_ActiveClients[AgentId]; |
245 | client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; | 248 | client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; |
246 | client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; | 249 | client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; |
247 | client.OnDirFindQuery -= OnDirFindQuery; | 250 | client.OnDirFindQuery -= OnDirFindQuery; |
248 | client.OnInstantMessage -= OnInstantMessage; | 251 | client.OnInstantMessage -= OnInstantMessage; |
249 | 252 | ||
250 | m_activeClients.Remove(agentId); | 253 | m_ActiveClients.Remove(AgentId); |
251 | } | 254 | } |
252 | else | 255 | else |
253 | { | 256 | { |
254 | m_log.InfoFormat("[GROUPS] Client closed that wasn't registered here."); | 257 | if (m_debugEnabled) m_log.WarnFormat("[GROUPS] Client closed that wasn't registered here."); |
255 | } | 258 | } |
259 | |||
260 | |||
256 | } | 261 | } |
257 | } | 262 | } |
263 | */ | ||
258 | 264 | ||
259 | 265 | ||
260 | void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) | 266 | void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) |
261 | { | 267 | { |
262 | if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) | 268 | if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) |
263 | { | 269 | { |
264 | m_log.InfoFormat("[GROUPS] {0} called with queryText({1}) queryFlags({2}) queryStart({3})", | 270 | 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); |
265 | System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); | ||
266 | 271 | ||
272 | // TODO: This currently ignores pretty much all the query flags including Mature and sort order | ||
267 | remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); | 273 | remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(queryText).ToArray()); |
268 | } | 274 | } |
275 | |||
269 | } | 276 | } |
270 | 277 | ||
271 | private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID agentID, UUID sessionID) | 278 | private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) |
272 | { | 279 | { |
273 | m_log.InfoFormat("[GROUPS] {0} called with SessionID :: {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, sessionID); | 280 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
274 | 281 | ||
275 | UUID activeGroupID = UUID.Zero; | 282 | UUID activeGroupID = UUID.Zero; |
276 | string activeGroupTitle = string.Empty; | 283 | string activeGroupTitle = string.Empty; |
277 | string activeGroupName = string.Empty; | 284 | string activeGroupName = string.Empty; |
278 | ulong activeGroupPowers = (ulong)GroupPowers.None; | 285 | ulong activeGroupPowers = (ulong)GroupPowers.None; |
279 | 286 | ||
280 | GroupMembershipData membership = m_groupData.GetAgentActiveMembership(agentID); | 287 | GroupMembershipData membership = m_groupData.GetAgentActiveMembership(dataForAgentID); |
281 | if (membership != null) | 288 | if (membership != null) |
282 | { | 289 | { |
283 | activeGroupID = membership.GroupID; | 290 | activeGroupID = membership.GroupID; |
@@ -285,59 +292,44 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
285 | activeGroupPowers = membership.GroupPowers; | 292 | activeGroupPowers = membership.GroupPowers; |
286 | } | 293 | } |
287 | 294 | ||
288 | string firstname, lastname; | 295 | SendAgentDataUpdate(remoteClient, dataForAgentID, activeGroupID, activeGroupName, activeGroupPowers, activeGroupTitle); |
289 | IClientAPI agent; | ||
290 | if (m_activeClients.TryGetValue(agentID, out agent)) | ||
291 | { | ||
292 | firstname = agent.FirstName; | ||
293 | lastname = agent.LastName; | ||
294 | } else { | ||
295 | firstname = "Unknown"; | ||
296 | lastname = "Unknown"; | ||
297 | } | ||
298 | |||
299 | UpdateScenePresenceWithTitle(agentID, activeGroupTitle); | ||
300 | 296 | ||
301 | remoteClient.SendAgentDataUpdate(agentID, activeGroupID, firstname, | 297 | SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); |
302 | lastname, activeGroupPowers, activeGroupName, | ||
303 | activeGroupTitle); | ||
304 | } | 298 | } |
305 | 299 | ||
306 | private void HandleUUIDGroupNameRequest(UUID groupID, IClientAPI remoteClient) | 300 | private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remote_client) |
307 | { | 301 | { |
308 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 302 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
309 | 303 | ||
310 | string groupName; | 304 | string GroupName; |
311 | 305 | ||
312 | GroupRecord group = m_groupData.GetGroupRecord(groupID, null); | 306 | GroupRecord group = m_groupData.GetGroupRecord(GroupID, null); |
313 | if (group != null) | 307 | if (group != null) |
314 | { | 308 | { |
315 | groupName = group.GroupName; | 309 | GroupName = group.GroupName; |
316 | } | 310 | } |
317 | else | 311 | else |
318 | { | 312 | { |
319 | groupName = "Unknown"; | 313 | GroupName = "Unknown"; |
320 | } | 314 | } |
321 | 315 | ||
322 | remoteClient.SendGroupNameReply(groupID, groupName); | 316 | |
317 | remote_client.SendGroupNameReply(GroupID, GroupName); | ||
323 | } | 318 | } |
324 | 319 | ||
325 | 320 | ||
326 | private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) | 321 | private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) |
327 | { | 322 | { |
328 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 323 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
329 | 324 | ||
330 | 325 | ||
331 | // Group invitations | 326 | // Group invitations |
332 | if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || | 327 | if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) |
333 | (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) | ||
334 | { | 328 | { |
335 | m_log.WarnFormat("[GROUPS] Received an IIM for {0}.", ((InstantMessageDialog)im.dialog).ToString()); | ||
336 | |||
337 | UUID inviteID = new UUID(im.imSessionID); | 329 | UUID inviteID = new UUID(im.imSessionID); |
338 | GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); | 330 | GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(inviteID); |
339 | 331 | ||
340 | m_log.WarnFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); | 332 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); |
341 | 333 | ||
342 | UUID fromAgentID = new UUID(im.fromAgentID); | 334 | UUID fromAgentID = new UUID(im.fromAgentID); |
343 | if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) | 335 | if ((inviteInfo != null) && (fromAgentID == inviteInfo.AgentID)) |
@@ -346,32 +338,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
346 | // Accept | 338 | // Accept |
347 | if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) | 339 | if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) |
348 | { | 340 | { |
349 | m_log.WarnFormat("[GROUPS] Received an accept invite notice."); | 341 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Received an accept invite notice."); |
350 | 342 | ||
351 | // and the sessionid is the role | 343 | // and the sessionid is the role |
352 | m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); | 344 | m_groupData.AddAgentToGroup(inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); |
353 | 345 | ||
354 | if (m_msgTransferModule != null) | 346 | GridInstantMessage msg = new GridInstantMessage(); |
355 | { | 347 | msg.imSessionID = UUID.Zero.Guid; |
356 | GridInstantMessage msg = new GridInstantMessage(); | 348 | msg.fromAgentID = UUID.Zero.Guid; |
357 | msg.imSessionID = UUID.Zero.Guid; | 349 | msg.toAgentID = inviteInfo.AgentID.Guid; |
358 | msg.fromAgentID = UUID.Zero.Guid; | 350 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
359 | msg.toAgentID = inviteInfo.AgentID.Guid; | 351 | msg.fromAgentName = "Groups"; |
360 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | 352 | msg.message = string.Format("You have been added to the group."); |
361 | msg.fromAgentName = "Groups"; | 353 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; |
362 | msg.message = string.Format("You have been added to the group."); | 354 | msg.fromGroup = false; |
363 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; | 355 | msg.offline = (byte)0; |
364 | msg.fromGroup = false; | 356 | msg.ParentEstateID = 0; |
365 | msg.offline = (byte)0; | 357 | msg.Position = Vector3.Zero; |
366 | msg.ParentEstateID = 0; | 358 | msg.RegionID = UUID.Zero.Guid; |
367 | msg.Position = Vector3.Zero; | 359 | msg.binaryBucket = new byte[0]; |
368 | msg.RegionID = UUID.Zero.Guid; | 360 | |
369 | msg.binaryBucket = new byte[0]; | 361 | OutgoingInstantMessage(msg, inviteInfo.AgentID); |
370 | |||
371 | m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); | ||
372 | } | ||
373 | 362 | ||
374 | UpdateAllClientsWithGroupInfo(); | 363 | UpdateAllClientsWithGroupInfo(inviteInfo.AgentID); |
364 | |||
365 | // TODO: If the inviter is still online, they need an agent dataupdate | ||
366 | // and maybe group membership updates for the invitee | ||
375 | 367 | ||
376 | m_groupData.RemoveAgentToGroupInvite(inviteID); | 368 | m_groupData.RemoveAgentToGroupInvite(inviteID); |
377 | } | 369 | } |
@@ -379,10 +371,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
379 | // Reject | 371 | // Reject |
380 | if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) | 372 | if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) |
381 | { | 373 | { |
382 | m_log.WarnFormat("[GROUPS] Received a reject invite notice."); | 374 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Received a reject invite notice."); |
383 | m_groupData.RemoveAgentToGroupInvite(inviteID); | 375 | m_groupData.RemoveAgentToGroupInvite(inviteID); |
384 | 376 | ||
385 | } | 377 | } |
378 | |||
379 | |||
386 | } | 380 | } |
387 | } | 381 | } |
388 | 382 | ||
@@ -394,12 +388,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
394 | return; | 388 | return; |
395 | } | 389 | } |
396 | 390 | ||
397 | UUID groupID = new UUID(im.toAgentID); | 391 | UUID GroupID = new UUID(im.toAgentID); |
398 | if (m_groupData.GetGroupRecord(groupID, null) != null) | 392 | if (m_groupData.GetGroupRecord(GroupID, null) != null) |
399 | { | 393 | { |
400 | UUID noticeID = UUID.Random(); | 394 | UUID NoticeID = UUID.Random(); |
401 | string subject = im.message.Substring(0, im.message.IndexOf('|')); | 395 | string Subject = im.message.Substring(0, im.message.IndexOf('|')); |
402 | string message = im.message.Substring(subject.Length + 1); | 396 | string Message = im.message.Substring(Subject.Length + 1); |
403 | 397 | ||
404 | byte[] bucket; | 398 | byte[] bucket; |
405 | 399 | ||
@@ -408,50 +402,56 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
408 | bucket = new byte[19]; | 402 | bucket = new byte[19]; |
409 | bucket[0] = 0; //dunno | 403 | bucket[0] = 0; //dunno |
410 | bucket[1] = 0; //dunno | 404 | bucket[1] = 0; //dunno |
411 | groupID.ToBytes(bucket, 2); | 405 | GroupID.ToBytes(bucket, 2); |
412 | bucket[18] = 0; //dunno | 406 | bucket[18] = 0; //dunno |
413 | } | 407 | } |
414 | else | 408 | else |
415 | { | 409 | { |
416 | string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); | 410 | string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); |
417 | binBucket = binBucket.Remove(0, 14).Trim(); | 411 | binBucket = binBucket.Remove(0, 14).Trim(); |
418 | m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); | 412 | if (m_debugEnabled) |
419 | |||
420 | OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); | ||
421 | |||
422 | foreach (string key in binBucketOSD.Keys) | ||
423 | { | 413 | { |
424 | m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); | 414 | m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); |
425 | } | 415 | |
416 | OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); | ||
417 | |||
418 | foreach (string key in binBucketOSD.Keys) | ||
419 | { | ||
420 | m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); | ||
421 | } | ||
422 | } | ||
426 | 423 | ||
427 | // treat as if no attachment | 424 | // treat as if no attachment |
428 | bucket = new byte[19]; | 425 | bucket = new byte[19]; |
429 | bucket[0] = 0; //dunno | 426 | bucket[0] = 0; //dunno |
430 | bucket[1] = 0; //dunno | 427 | bucket[1] = 0; //dunno |
431 | groupID.ToBytes(bucket, 2); | 428 | GroupID.ToBytes(bucket, 2); |
432 | bucket[18] = 0; //dunno | 429 | bucket[18] = 0; //dunno |
433 | } | 430 | } |
434 | 431 | ||
435 | 432 | ||
436 | m_groupData.AddGroupNotice(groupID, noticeID, im.fromAgentName, subject, message, bucket); | 433 | m_groupData.AddGroupNotice(GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); |
437 | if (OnNewGroupNotice != null) | 434 | if (OnNewGroupNotice != null) |
438 | { | 435 | { |
439 | OnNewGroupNotice(groupID, noticeID); | 436 | OnNewGroupNotice(GroupID, NoticeID); |
440 | } | 437 | } |
441 | 438 | ||
442 | // Build notice IIM | 439 | // Build notice IIM |
443 | GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, noticeID, | 440 | GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); |
444 | (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); | ||
445 | 441 | ||
446 | // Send notice out to everyone that wants notices | 442 | // Send notice out to everyone that wants notices |
447 | foreach (GroupMembersData member in m_groupData.GetGroupMembers(groupID)) | 443 | foreach (GroupMembersData member in m_groupData.GetGroupMembers(GroupID)) |
448 | { | 444 | { |
449 | if (member.AcceptNotices) | 445 | if (member.AcceptNotices) |
450 | { | 446 | { |
451 | msg.toAgentID = member.AgentID.Guid; | 447 | msg.toAgentID = member.AgentID.Guid; |
452 | m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) {}); | 448 | OutgoingInstantMessage(msg, member.AgentID); |
449 | |||
453 | } | 450 | } |
454 | } | 451 | } |
452 | |||
453 | |||
454 | |||
455 | } | 455 | } |
456 | } | 456 | } |
457 | 457 | ||
@@ -460,24 +460,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
460 | // TODO:FIXME: Use a presense server of some kind to find out where the | 460 | // TODO:FIXME: Use a presense server of some kind to find out where the |
461 | // client actually is, and try contacting that region directly to notify them, | 461 | // client actually is, and try contacting that region directly to notify them, |
462 | // or provide the notification via xmlrpc update queue | 462 | // or provide the notification via xmlrpc update queue |
463 | if (im.dialog == 210) | 463 | if ((im.dialog == 210)) |
464 | { | 464 | { |
465 | // This is sent from the region that the ejectee was ejected from | 465 | // This is sent from the region that the ejectee was ejected from |
466 | // if it's being delivered here, then the ejectee is here | 466 | // if it's being delivered here, then the ejectee is here |
467 | // so we need to send local updates to the agent. | 467 | // so we need to send local updates to the agent. |
468 | if (m_msgTransferModule != null) | ||
469 | { | ||
470 | im.dialog = (byte)InstantMessageDialog.MessageFromAgent; | ||
471 | m_msgTransferModule.SendInstantMessage(im, delegate(bool success) {}); | ||
472 | } | ||
473 | 468 | ||
474 | UUID ejecteeID = new UUID(im.toAgentID); | 469 | UUID ejecteeID = new UUID(im.toAgentID); |
475 | UUID groupID = new UUID(im.toAgentID); | 470 | |
476 | if (m_activeClients.ContainsKey(ejecteeID)) | 471 | im.dialog = (byte)InstantMessageDialog.MessageFromAgent; |
472 | OutgoingInstantMessage(im, ejecteeID); | ||
473 | |||
474 | IClientAPI ejectee = GetActiveClient(ejecteeID); | ||
475 | if (ejectee != null) | ||
477 | { | 476 | { |
478 | m_activeClients[ejecteeID].SendAgentDropGroup(groupID); | 477 | UUID groupID = new UUID(im.fromAgentID); |
478 | ejectee.SendAgentDropGroup(groupID); | ||
479 | } | 479 | } |
480 | |||
480 | } | 481 | } |
482 | |||
483 | |||
484 | |||
481 | } | 485 | } |
482 | 486 | ||
483 | private void OnGridInstantMessage(GridInstantMessage msg) | 487 | private void OnGridInstantMessage(GridInstantMessage msg) |
@@ -487,6 +491,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
487 | // Trigger the above event handler | 491 | // Trigger the above event handler |
488 | OnInstantMessage(null, msg); | 492 | OnInstantMessage(null, msg); |
489 | 493 | ||
494 | |||
490 | // If a message from a group arrives here, it may need to be forwarded to a local client | 495 | // If a message from a group arrives here, it may need to be forwarded to a local client |
491 | if (msg.fromGroup == true) | 496 | if (msg.fromGroup == true) |
492 | { | 497 | { |
@@ -495,56 +500,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
495 | case (byte)InstantMessageDialog.GroupInvitation: | 500 | case (byte)InstantMessageDialog.GroupInvitation: |
496 | case (byte)InstantMessageDialog.GroupNotice: | 501 | case (byte)InstantMessageDialog.GroupNotice: |
497 | UUID toAgentID = new UUID(msg.toAgentID); | 502 | UUID toAgentID = new UUID(msg.toAgentID); |
498 | if (m_activeClients.ContainsKey(toAgentID)) | 503 | IClientAPI localClient = GetActiveClient(toAgentID); |
504 | if( localClient != null ) | ||
499 | { | 505 | { |
500 | m_activeClients[toAgentID].SendInstantMessage(msg); | 506 | localClient.SendInstantMessage(msg); |
501 | } | 507 | } |
502 | break; | 508 | break; |
503 | } | 509 | } |
504 | } | 510 | } |
505 | 511 | ||
506 | } | 512 | } |
507 | #endregion | ||
508 | 513 | ||
509 | private void UpdateScenePresenceWithTitle(UUID agentID, string title) | ||
510 | { | ||
511 | m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", agentID, title); | ||
512 | |||
513 | ScenePresence presence = null; | ||
514 | lock (m_sceneList) | ||
515 | { | ||
516 | foreach (Scene scene in m_sceneList) | ||
517 | { | ||
518 | presence = scene.GetScenePresence(agentID); | ||
519 | if (presence != null) | ||
520 | { | ||
521 | presence.Grouptitle = title; | ||
522 | |||
523 | // FixMe: Ter suggests a "Schedule" method that I can't find. | ||
524 | presence.SendFullUpdateToAllClients(); | ||
525 | } | ||
526 | } | ||
527 | } | ||
528 | } | ||
529 | 514 | ||
515 | #endregion | ||
530 | 516 | ||
531 | #region IGroupsModule Members | 517 | #region IGroupsModule Members |
532 | 518 | ||
533 | public event NewGroupNotice OnNewGroupNotice; | 519 | public event NewGroupNotice OnNewGroupNotice; |
534 | 520 | ||
535 | public GroupRecord GetGroupRecord(UUID groupID) | 521 | public GroupRecord GetGroupRecord(UUID GroupID) |
536 | { | 522 | { |
537 | return m_groupData.GetGroupRecord(groupID, null); | 523 | return m_groupData.GetGroupRecord(GroupID, null); |
538 | } | 524 | } |
539 | 525 | ||
540 | public void ActivateGroup(IClientAPI remoteClient, UUID groupID) | 526 | public void ActivateGroup(IClientAPI remoteClient, UUID groupID) |
541 | { | 527 | { |
542 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 528 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
543 | 529 | ||
544 | m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID); | 530 | m_groupData.SetAgentActiveGroup(remoteClient.AgentId, groupID); |
545 | 531 | ||
546 | // UpdateClientWithGroupInfo(remoteClient); | 532 | // Changing active group changes title, active powers, all kinds of things |
547 | UpdateAllClientsWithGroupInfo(); | 533 | // anyone who is in any region that can see this client, should probably be |
534 | // updated with new group info. At a minimum, they should get ScenePresence | ||
535 | // updated with new title. | ||
536 | UpdateAllClientsWithGroupInfo(remoteClient.AgentId); | ||
548 | } | 537 | } |
549 | 538 | ||
550 | /// <summary> | 539 | /// <summary> |
@@ -552,7 +541,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
552 | /// </summary> | 541 | /// </summary> |
553 | public List<GroupTitlesData> GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) | 542 | public List<GroupTitlesData> GroupTitlesRequest(IClientAPI remoteClient, UUID groupID) |
554 | { | 543 | { |
555 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 544 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
556 | 545 | ||
557 | List<GroupRolesData> agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID); | 546 | List<GroupRolesData> agentRoles = m_groupData.GetAgentGroupRoles(remoteClient.AgentId, groupID); |
558 | GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); | 547 | GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(remoteClient.AgentId, groupID); |
@@ -576,49 +565,61 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
576 | 565 | ||
577 | public List<GroupMembersData> GroupMembersRequest(IClientAPI remoteClient, UUID groupID) | 566 | public List<GroupMembersData> GroupMembersRequest(IClientAPI remoteClient, UUID groupID) |
578 | { | 567 | { |
579 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 568 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
580 | 569 | ||
581 | List<GroupMembersData> data = m_groupData.GetGroupMembers(groupID); | 570 | List<GroupMembersData> data = m_groupData.GetGroupMembers(groupID); |
582 | 571 | if (m_debugEnabled) | |
583 | foreach (GroupMembersData member in data) | ||
584 | { | 572 | { |
585 | m_log.InfoFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); | 573 | foreach (GroupMembersData member in data) |
574 | { | ||
575 | m_log.DebugFormat("[GROUPS] {0} {1}", member.AgentID, member.Title); | ||
576 | } | ||
586 | } | 577 | } |
587 | 578 | ||
588 | return data; | 579 | return data; |
580 | |||
589 | } | 581 | } |
590 | 582 | ||
591 | public List<GroupRolesData> GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) | 583 | public List<GroupRolesData> GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) |
592 | { | 584 | { |
593 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 585 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
594 | 586 | ||
595 | List<GroupRolesData> data = m_groupData.GetGroupRoles(groupID); | 587 | List<GroupRolesData> data = m_groupData.GetGroupRoles(groupID); |
596 | 588 | ||
597 | foreach (GroupRolesData member in data) | 589 | if (m_debugEnabled) |
598 | { | 590 | { |
599 | m_log.InfoFormat("[GROUPS] {0} {1}", member.Title, member.Members); | 591 | foreach (GroupRolesData member in data) |
592 | { | ||
593 | m_log.DebugFormat("[GROUPS] {0} {1}", member.Title, member.Members); | ||
594 | } | ||
600 | } | 595 | } |
601 | 596 | ||
602 | return data; | 597 | return data; |
598 | |||
603 | } | 599 | } |
604 | 600 | ||
605 | public List<GroupRoleMembersData> GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) | 601 | public List<GroupRoleMembersData> GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) |
606 | { | 602 | { |
607 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 603 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
608 | 604 | ||
609 | List<GroupRoleMembersData> data = m_groupData.GetGroupRoleMembers(groupID); | 605 | List<GroupRoleMembersData> data = m_groupData.GetGroupRoleMembers(groupID); |
610 | 606 | ||
611 | foreach (GroupRoleMembersData member in data) | 607 | if (m_debugEnabled) |
612 | { | 608 | { |
613 | m_log.InfoFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); | 609 | foreach (GroupRoleMembersData member in data) |
610 | { | ||
611 | m_log.DebugFormat("[GROUPS] Av: {0} Role: {1}", member.MemberID, member.RoleID); | ||
612 | } | ||
614 | } | 613 | } |
615 | 614 | ||
616 | return data; | 615 | return data; |
616 | |||
617 | |||
617 | } | 618 | } |
618 | 619 | ||
619 | public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) | 620 | public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) |
620 | { | 621 | { |
621 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 622 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
622 | 623 | ||
623 | GroupProfileData profile = new GroupProfileData(); | 624 | GroupProfileData profile = new GroupProfileData(); |
624 | 625 | ||
@@ -651,45 +652,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
651 | return profile; | 652 | return profile; |
652 | } | 653 | } |
653 | 654 | ||
654 | public GroupMembershipData[] GetMembershipData(UUID userID) | 655 | public GroupMembershipData[] GetMembershipData(UUID agentID) |
655 | { | 656 | { |
656 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 657 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
657 | 658 | ||
658 | return m_groupData.GetAgentGroupMemberships(userID).ToArray(); | 659 | return m_groupData.GetAgentGroupMemberships(agentID).ToArray(); |
659 | } | 660 | } |
660 | 661 | ||
661 | public GroupMembershipData GetMembershipData(UUID groupID, UUID userID) | 662 | public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) |
662 | { | 663 | { |
663 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 664 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
664 | 665 | ||
665 | return m_groupData.GetAgentGroupMembership(userID, groupID); | 666 | return m_groupData.GetAgentGroupMembership(agentID, groupID); |
666 | } | 667 | } |
667 | 668 | ||
668 | public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, | 669 | public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) |
669 | bool showInList, UUID insigniaID, int membershipFee, | ||
670 | bool openEnrollment, bool allowPublish, bool maturePublish) | ||
671 | { | 670 | { |
672 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 671 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
673 | 672 | ||
674 | // TODO: Security Check? | 673 | // TODO: Security Check? |
675 | 674 | ||
676 | m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, | 675 | m_groupData.UpdateGroup(groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); |
677 | openEnrollment, allowPublish, maturePublish); | ||
678 | } | 676 | } |
679 | 677 | ||
680 | public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) | 678 | public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) |
681 | { | 679 | { |
682 | // TODO: Security Check? | 680 | // TODO: Security Check? |
683 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 681 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
684 | 682 | ||
685 | m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); | 683 | m_groupData.SetAgentGroupInfo(remoteClient.AgentId, groupID, acceptNotices, listInProfile); |
686 | } | 684 | } |
687 | 685 | ||
688 | public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, | 686 | public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) |
689 | bool showInList, UUID insigniaID, int membershipFee, | ||
690 | bool openEnrollment, bool allowPublish, bool maturePublish) | ||
691 | { | 687 | { |
692 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 688 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
693 | 689 | ||
694 | if (m_groupData.GetGroupRecord(UUID.Zero, name) != null) | 690 | if (m_groupData.GetGroupRecord(UUID.Zero, name) != null) |
695 | { | 691 | { |
@@ -697,19 +693,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
697 | return UUID.Zero; | 693 | return UUID.Zero; |
698 | } | 694 | } |
699 | 695 | ||
700 | UUID groupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, | 696 | UUID groupID = m_groupData.CreateGroup(name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); |
701 | openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); | ||
702 | 697 | ||
703 | remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); | 698 | remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); |
704 | 699 | ||
705 | UpdateClientWithGroupInfo(remoteClient); | 700 | // Update the founder with new group information. |
701 | SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); | ||
706 | 702 | ||
707 | return groupID; | 703 | return groupID; |
708 | } | 704 | } |
709 | 705 | ||
710 | public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) | 706 | public GroupNoticeData[] GroupNoticesListRequest(IClientAPI remoteClient, UUID groupID) |
711 | { | 707 | { |
712 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 708 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
713 | 709 | ||
714 | // ToDo: check if agent is a member of group and is allowed to see notices? | 710 | // ToDo: check if agent is a member of group and is allowed to see notices? |
715 | 711 | ||
@@ -721,7 +717,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
721 | /// </summary> | 717 | /// </summary> |
722 | public string GetGroupTitle(UUID avatarID) | 718 | public string GetGroupTitle(UUID avatarID) |
723 | { | 719 | { |
724 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 720 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
725 | 721 | ||
726 | GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID); | 722 | GroupMembershipData membership = m_groupData.GetAgentActiveMembership(avatarID); |
727 | if (membership != null) | 723 | if (membership != null) |
@@ -736,18 +732,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
736 | /// </summary> | 732 | /// </summary> |
737 | public void GroupTitleUpdate(IClientAPI remoteClient, UUID groupID, UUID titleRoleID) | 733 | public void GroupTitleUpdate(IClientAPI remoteClient, UUID groupID, UUID titleRoleID) |
738 | { | 734 | { |
739 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 735 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
740 | 736 | ||
741 | m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, groupID, titleRoleID); | 737 | m_groupData.SetAgentActiveGroupRole(remoteClient.AgentId, groupID, titleRoleID); |
742 | 738 | ||
743 | UpdateAllClientsWithGroupInfo(); | 739 | // TODO: Not sure what all is needed here, but if the active group role change is for the group |
740 | // the client currently has set active, then we need to do a scene presence update too | ||
741 | // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) | ||
742 | |||
743 | UpdateAllClientsWithGroupInfo(remoteClient.AgentId); | ||
744 | } | 744 | } |
745 | 745 | ||
746 | 746 | ||
747 | public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, | 747 | public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) |
748 | string name, string description, string title, ulong powers, byte updateType) | ||
749 | { | 748 | { |
750 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 749 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
751 | 750 | ||
752 | // TODO: Security Checks? | 751 | // TODO: Security Checks? |
753 | 752 | ||
@@ -774,12 +773,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
774 | 773 | ||
775 | } | 774 | } |
776 | 775 | ||
777 | UpdateClientWithGroupInfo(remoteClient); | 776 | // TODO: This update really should send out updates for everyone in the role that just got changed. |
777 | SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); | ||
778 | } | 778 | } |
779 | 779 | ||
780 | public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) | 780 | public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) |
781 | { | 781 | { |
782 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 782 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
783 | // Todo: Security check | 783 | // Todo: Security check |
784 | 784 | ||
785 | switch (changes) | 785 | switch (changes) |
@@ -798,44 +798,45 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
798 | m_log.ErrorFormat("[GROUPS] {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); | 798 | m_log.ErrorFormat("[GROUPS] {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); |
799 | break; | 799 | break; |
800 | } | 800 | } |
801 | UpdateClientWithGroupInfo(remoteClient); | 801 | |
802 | // TODO: This update really should send out updates for everyone in the role that just got changed. | ||
803 | SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); | ||
802 | } | 804 | } |
803 | 805 | ||
804 | public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) | 806 | public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) |
805 | { | 807 | { |
806 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 808 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
807 | 809 | ||
808 | 810 | ||
809 | GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID); | 811 | GroupNoticeInfo data = m_groupData.GetGroupNotice(groupNoticeID); |
810 | 812 | ||
811 | if (data != null) | 813 | if (data != null) |
812 | { | 814 | { |
813 | if (m_msgTransferModule != null) | 815 | GroupRecord groupInfo = m_groupData.GetGroupRecord(data.GroupID, null); |
814 | { | 816 | |
815 | GridInstantMessage msg = new GridInstantMessage(); | 817 | GridInstantMessage msg = new GridInstantMessage(); |
816 | msg.imSessionID = UUID.Zero.Guid; | 818 | msg.imSessionID = UUID.Zero.Guid; |
817 | msg.fromAgentID = data.GroupID.Guid; | 819 | msg.fromAgentID = data.GroupID.Guid; |
818 | msg.toAgentID = remoteClient.AgentId.Guid; | 820 | msg.toAgentID = remoteClient.AgentId.Guid; |
819 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | 821 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
820 | msg.fromAgentName = "Group Notice From"; | 822 | msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; |
821 | msg.message = data.noticeData.Subject + "|" + data.Message; | 823 | msg.message = data.noticeData.Subject + "|" + data.Message; |
822 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; | 824 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; |
823 | msg.fromGroup = true; | 825 | msg.fromGroup = true; |
824 | msg.offline = (byte)0; | 826 | msg.offline = (byte)0; |
825 | msg.ParentEstateID = 0; | 827 | msg.ParentEstateID = 0; |
826 | msg.Position = Vector3.Zero; | 828 | msg.Position = Vector3.Zero; |
827 | msg.RegionID = UUID.Zero.Guid; | 829 | msg.RegionID = UUID.Zero.Guid; |
828 | msg.binaryBucket = data.BinaryBucket; | 830 | msg.binaryBucket = data.BinaryBucket; |
829 | 831 | ||
830 | m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); | 832 | OutgoingInstantMessage(msg, remoteClient.AgentId); |
831 | } | ||
832 | } | 833 | } |
833 | 834 | ||
834 | } | 835 | } |
835 | 836 | ||
836 | public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) | 837 | public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) |
837 | { | 838 | { |
838 | m_log.WarnFormat("[GROUPS] {0} is probably not properly implemented", System.Reflection.MethodBase.GetCurrentMethod().Name); | 839 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
839 | 840 | ||
840 | GridInstantMessage msg = new GridInstantMessage(); | 841 | GridInstantMessage msg = new GridInstantMessage(); |
841 | msg.imSessionID = UUID.Zero.Guid; | 842 | msg.imSessionID = UUID.Zero.Guid; |
@@ -857,32 +858,43 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
857 | msg.message = info.noticeData.Subject + "|" + info.Message; | 858 | msg.message = info.noticeData.Subject + "|" + info.Message; |
858 | msg.binaryBucket = info.BinaryBucket; | 859 | msg.binaryBucket = info.BinaryBucket; |
859 | } | 860 | } |
861 | else | ||
862 | { | ||
863 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Group Notice {0} not found, composing empty message.", groupNoticeID); | ||
864 | msg.fromAgentID = UUID.Zero.Guid; | ||
865 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; | ||
866 | msg.fromAgentName = string.Empty; | ||
867 | msg.message = string.Empty; | ||
868 | msg.binaryBucket = new byte[0]; | ||
869 | } | ||
860 | 870 | ||
861 | return msg; | 871 | return msg; |
862 | } | 872 | } |
863 | 873 | ||
864 | public void SendAgentGroupDataUpdate(IClientAPI remoteClient) | 874 | public void SendAgentGroupDataUpdate(IClientAPI remoteClient) |
865 | { | 875 | { |
866 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 876 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
867 | 877 | ||
868 | UpdateClientWithGroupInfo(remoteClient); | 878 | // Send agent information about his groups |
879 | SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); | ||
869 | } | 880 | } |
870 | 881 | ||
871 | public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) | 882 | public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) |
872 | { | 883 | { |
873 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 884 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
874 | 885 | ||
875 | // Should check to see if OpenEnrollment, or if there's an outstanding invitation | 886 | // Should check to see if OpenEnrollment, or if there's an outstanding invitation |
876 | m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero); | 887 | m_groupData.AddAgentToGroup(remoteClient.AgentId, groupID, UUID.Zero); |
877 | 888 | ||
878 | remoteClient.SendJoinGroupReply(groupID, true); | 889 | remoteClient.SendJoinGroupReply(groupID, true); |
879 | 890 | ||
880 | UpdateClientWithGroupInfo(remoteClient); | 891 | // Should this send updates to everyone in the group? |
892 | SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); | ||
881 | } | 893 | } |
882 | 894 | ||
883 | public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) | 895 | public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) |
884 | { | 896 | { |
885 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 897 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
886 | 898 | ||
887 | m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, groupID); | 899 | m_groupData.RemoveAgentFromGroup(remoteClient.AgentId, groupID); |
888 | 900 | ||
@@ -890,107 +902,97 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
890 | 902 | ||
891 | remoteClient.SendAgentDropGroup(groupID); | 903 | remoteClient.SendAgentDropGroup(groupID); |
892 | 904 | ||
893 | UpdateClientWithGroupInfo(remoteClient); | 905 | // SL sends out notifcations to the group messaging session that the person has left |
906 | // Should this also update everyone who is in the group? | ||
907 | SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); | ||
894 | } | 908 | } |
895 | 909 | ||
896 | public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) | 910 | public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) |
897 | { | 911 | { |
898 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 912 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
899 | 913 | ||
900 | // Todo: Security check? | 914 | // Todo: Security check? |
901 | m_groupData.RemoveAgentFromGroup(ejecteeID, groupID); | 915 | m_groupData.RemoveAgentFromGroup(ejecteeID, groupID); |
902 | 916 | ||
903 | remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); | 917 | remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); |
904 | 918 | ||
905 | if (m_msgTransferModule != null) | 919 | GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); |
906 | { | 920 | UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); |
907 | GroupRecord groupInfo = m_groupData.GetGroupRecord(groupID, null); | ||
908 | UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); | ||
909 | 921 | ||
910 | if ((groupInfo == null) || (userProfile == null)) | 922 | if ((groupInfo == null) || (userProfile == null)) |
911 | { | 923 | { |
912 | return; | 924 | return; |
913 | } | 925 | } |
914 | 926 | ||
915 | 927 | ||
916 | // Send Message to Ejectee | 928 | // Send Message to Ejectee |
917 | GridInstantMessage msg = new GridInstantMessage(); | 929 | GridInstantMessage msg = new GridInstantMessage(); |
918 | 930 | ||
919 | msg.imSessionID = UUID.Zero.Guid; | 931 | msg.imSessionID = UUID.Zero.Guid; |
920 | msg.fromAgentID = remoteClient.AgentId.Guid; | 932 | msg.fromAgentID = remoteClient.AgentId.Guid; |
921 | // msg.fromAgentID = info.GroupID; | 933 | // msg.fromAgentID = info.GroupID; |
922 | msg.toAgentID = ejecteeID.Guid; | 934 | msg.toAgentID = ejecteeID.Guid; |
923 | //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | 935 | //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
924 | msg.timestamp = 0; | 936 | msg.timestamp = 0; |
925 | msg.fromAgentName = remoteClient.Name; | 937 | msg.fromAgentName = remoteClient.Name; |
926 | msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); | 938 | msg.message = string.Format("You have been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName); |
927 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; | 939 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; |
928 | msg.fromGroup = false; | 940 | msg.fromGroup = false; |
929 | msg.offline = (byte)0; | 941 | msg.offline = (byte)0; |
930 | msg.ParentEstateID = 0; | 942 | msg.ParentEstateID = 0; |
931 | msg.Position = Vector3.Zero; | 943 | msg.Position = Vector3.Zero; |
932 | msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; | 944 | msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; |
933 | msg.binaryBucket = new byte[0]; | 945 | msg.binaryBucket = new byte[0]; |
934 | m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) | 946 | OutgoingInstantMessage(msg, ejecteeID); |
935 | { | ||
936 | m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", | ||
937 | success,ToString()); | ||
938 | }); | ||
939 | 947 | ||
940 | 948 | ||
941 | // Message to ejector | 949 | // Message to ejector |
942 | // Interop, received special 210 code for ejecting a group member | 950 | // Interop, received special 210 code for ejecting a group member |
943 | // this only works within the comms servers domain, and won't work hypergrid | 951 | // this only works within the comms servers domain, and won't work hypergrid |
944 | // TODO:FIXME: Use a presense server of some kind to find out where the | 952 | // TODO:FIXME: Use a presense server of some kind to find out where the |
945 | // client actually is, and try contacting that region directly to notify them, | 953 | // client actually is, and try contacting that region directly to notify them, |
946 | // or provide the notification via xmlrpc update queue | 954 | // or provide the notification via xmlrpc update queue |
947 | 955 | ||
948 | msg = new GridInstantMessage(); | 956 | msg = new GridInstantMessage(); |
949 | msg.imSessionID = UUID.Zero.Guid; | 957 | msg.imSessionID = UUID.Zero.Guid; |
950 | msg.fromAgentID = remoteClient.AgentId.Guid; | 958 | msg.fromAgentID = remoteClient.AgentId.Guid; |
951 | msg.toAgentID = remoteClient.AgentId.Guid; | 959 | msg.toAgentID = remoteClient.AgentId.Guid; |
952 | msg.timestamp = 0; | 960 | msg.timestamp = 0; |
953 | msg.fromAgentName = remoteClient.Name; | 961 | msg.fromAgentName = remoteClient.Name; |
954 | if (userProfile != null) | 962 | if (userProfile != null) |
955 | { | 963 | { |
956 | msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", | 964 | msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); |
957 | remoteClient.Name, groupInfo.GroupName, userProfile.Name); | ||
958 | } | ||
959 | else | ||
960 | { | ||
961 | msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", | ||
962 | remoteClient.Name, groupInfo.GroupName, "Unknown member"); | ||
963 | } | ||
964 | msg.dialog = (byte)210; //interop | ||
965 | msg.fromGroup = false; | ||
966 | msg.offline = (byte)0; | ||
967 | msg.ParentEstateID = 0; | ||
968 | msg.Position = Vector3.Zero; | ||
969 | msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; | ||
970 | msg.binaryBucket = new byte[0]; | ||
971 | m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) | ||
972 | { | ||
973 | m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", | ||
974 | success, ToString()); | ||
975 | }); | ||
976 | } | 965 | } |
966 | else | ||
967 | { | ||
968 | msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, "Unknown member"); | ||
969 | } | ||
970 | msg.dialog = (byte)210; //interop | ||
971 | msg.fromGroup = false; | ||
972 | msg.offline = (byte)0; | ||
973 | msg.ParentEstateID = 0; | ||
974 | msg.Position = Vector3.Zero; | ||
975 | msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; | ||
976 | msg.binaryBucket = new byte[0]; | ||
977 | OutgoingInstantMessage(msg, remoteClient.AgentId); | ||
977 | 978 | ||
978 | UpdateAllClientsWithGroupInfo(); | 979 | |
980 | // SL sends out messages to everyone in the group | ||
981 | // Who all should receive updates and what should they be updated with? | ||
982 | UpdateAllClientsWithGroupInfo(ejecteeID); | ||
979 | } | 983 | } |
980 | 984 | ||
981 | public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) | 985 | public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) |
982 | { | 986 | { |
983 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 987 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
984 | m_log.WarnFormat("[GROUPS] GID {0}, AID {1}, RID {2} ", groupID, invitedAgentID, roleID); | ||
985 | 988 | ||
986 | // Todo: Security check, probably also want to send some kind of notification | 989 | // Todo: Security check, probably also want to send some kind of notification |
987 | UUID inviteID = UUID.Random(); | 990 | UUID InviteID = UUID.Random(); |
988 | m_log.WarnFormat("[GROUPS] Invite ID: {0}", inviteID); | 991 | m_groupData.AddAgentToGroupInvite(InviteID, groupID, roleID, invitedAgentID); |
989 | m_groupData.AddAgentToGroupInvite(inviteID, groupID, roleID, invitedAgentID); | ||
990 | 992 | ||
991 | if (m_msgTransferModule != null) | 993 | if (m_msgTransferModule != null) |
992 | { | 994 | { |
993 | Guid inviteUUID = inviteID.Guid; | 995 | Guid inviteUUID = InviteID.Guid; |
994 | 996 | ||
995 | GridInstantMessage msg = new GridInstantMessage(); | 997 | GridInstantMessage msg = new GridInstantMessage(); |
996 | 998 | ||
@@ -1002,8 +1004,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1002 | //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | 1004 | //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
1003 | msg.timestamp = 0; | 1005 | msg.timestamp = 0; |
1004 | msg.fromAgentName = remoteClient.Name; | 1006 | msg.fromAgentName = remoteClient.Name; |
1005 | msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", | 1007 | msg.message = string.Format("{0} has invited you to join a group. There is no cost to join this group.", remoteClient.Name); |
1006 | remoteClient.Name); | ||
1007 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; | 1008 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupInvitation; |
1008 | msg.fromGroup = true; | 1009 | msg.fromGroup = true; |
1009 | msg.offline = (byte)0; | 1010 | msg.offline = (byte)0; |
@@ -1011,60 +1012,198 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1011 | msg.Position = Vector3.Zero; | 1012 | msg.Position = Vector3.Zero; |
1012 | msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; | 1013 | msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; |
1013 | msg.binaryBucket = new byte[20]; | 1014 | msg.binaryBucket = new byte[20]; |
1014 | 1015 | ||
1015 | m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) | 1016 | OutgoingInstantMessage(msg, invitedAgentID); |
1016 | { | ||
1017 | m_log.DebugFormat("[GROUPS] Message Sent Success: {0}", success,ToString()); | ||
1018 | }); | ||
1019 | } | 1017 | } |
1020 | } | 1018 | } |
1021 | 1019 | ||
1022 | #endregion | 1020 | #endregion |
1023 | 1021 | ||
1024 | void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, GroupMembershipData[] data) | 1022 | #region Client/Update Tools |
1023 | |||
1024 | /// <summary> | ||
1025 | /// Try to find an active IClientAPI reference for agentID giving preference to root connections | ||
1026 | /// </summary> | ||
1027 | private IClientAPI GetActiveClient(UUID agentID) | ||
1028 | { | ||
1029 | IClientAPI child = null; | ||
1030 | |||
1031 | // Try root avatar first | ||
1032 | foreach (Scene scene in m_sceneList) | ||
1033 | { | ||
1034 | if (scene.Entities.ContainsKey(agentID) && | ||
1035 | scene.Entities[agentID] is ScenePresence) | ||
1036 | { | ||
1037 | ScenePresence user = (ScenePresence)scene.Entities[agentID]; | ||
1038 | if (!user.IsChildAgent) | ||
1039 | { | ||
1040 | return user.ControllingClient; | ||
1041 | } | ||
1042 | else | ||
1043 | { | ||
1044 | child = user.ControllingClient; | ||
1045 | } | ||
1046 | } | ||
1047 | } | ||
1048 | |||
1049 | // If we didn't find a root, then just return whichever child we found, or null if none | ||
1050 | return child; | ||
1051 | } | ||
1052 | |||
1053 | /// <summary> | ||
1054 | /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. | ||
1055 | /// </summary> | ||
1056 | private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data) | ||
1025 | { | 1057 | { |
1026 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 1058 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
1027 | 1059 | ||
1028 | OSDArray agentData = new OSDArray(1); | 1060 | OSDArray AgentData = new OSDArray(1); |
1029 | OSDMap agentDataMap = new OSDMap(1); | 1061 | OSDMap AgentDataMap = new OSDMap(1); |
1030 | agentDataMap.Add("AgentID", OSD.FromUUID(remoteClient.AgentId)); | 1062 | AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID)); |
1031 | agentData.Add(agentDataMap); | 1063 | AgentData.Add(AgentDataMap); |
1032 | 1064 | ||
1033 | 1065 | ||
1034 | OSDArray groupData = new OSDArray(data.Length); | 1066 | OSDArray GroupData = new OSDArray(data.Length); |
1035 | OSDArray newGroupData = new OSDArray(data.Length); | 1067 | OSDArray NewGroupData = new OSDArray(data.Length); |
1036 | 1068 | ||
1037 | foreach (GroupMembershipData membership in data) | 1069 | foreach (GroupMembershipData membership in data) |
1038 | { | 1070 | { |
1039 | OSDMap groupDataMap = new OSDMap(6); | 1071 | OSDMap GroupDataMap = new OSDMap(6); |
1040 | OSDMap newGroupDataMap = new OSDMap(1); | 1072 | OSDMap NewGroupDataMap = new OSDMap(1); |
1041 | 1073 | ||
1042 | groupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); | 1074 | GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID)); |
1043 | groupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); | 1075 | GroupDataMap.Add("GroupPowers", OSD.FromBinary(membership.GroupPowers)); |
1044 | groupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); | 1076 | GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices)); |
1045 | groupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); | 1077 | GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture)); |
1046 | groupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); | 1078 | GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution)); |
1047 | groupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); | 1079 | GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName)); |
1048 | newGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); | 1080 | NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile)); |
1049 | 1081 | ||
1050 | groupData.Add(groupDataMap); | 1082 | GroupData.Add(GroupDataMap); |
1051 | newGroupData.Add(newGroupDataMap); | 1083 | NewGroupData.Add(NewGroupDataMap); |
1052 | } | 1084 | } |
1053 | 1085 | ||
1054 | OSDMap llDataStruct = new OSDMap(3); | 1086 | OSDMap llDataStruct = new OSDMap(3); |
1055 | llDataStruct.Add("AgentData", agentData); | 1087 | llDataStruct.Add("AgentData", AgentData); |
1056 | llDataStruct.Add("GroupData", groupData); | 1088 | llDataStruct.Add("GroupData", GroupData); |
1057 | llDataStruct.Add("NewGroupData", newGroupData); | 1089 | llDataStruct.Add("NewGroupData", NewGroupData); |
1058 | 1090 | ||
1059 | IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); | 1091 | IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); |
1060 | 1092 | ||
1061 | if (queue != null) | 1093 | if (queue != null) |
1062 | { | 1094 | { |
1063 | queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), | 1095 | queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); |
1064 | remoteClient.AgentId); | ||
1065 | } | 1096 | } |
1066 | 1097 | ||
1067 | } | 1098 | } |
1099 | |||
1100 | private void SendScenePresenceUpdate(UUID AgentID, string Title) | ||
1101 | { | ||
1102 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Updating scene title for {0} with title: {1}", AgentID, Title); | ||
1103 | |||
1104 | ScenePresence presence = null; | ||
1105 | lock (m_sceneList) | ||
1106 | { | ||
1107 | foreach (Scene scene in m_sceneList) | ||
1108 | { | ||
1109 | presence = scene.GetScenePresence(AgentID); | ||
1110 | if (presence != null) | ||
1111 | { | ||
1112 | presence.Grouptitle = Title; | ||
1113 | |||
1114 | // FixMe: Ter suggests a "Schedule" method that I can't find. | ||
1115 | presence.SendFullUpdateToAllClients(); | ||
1116 | } | ||
1117 | } | ||
1118 | } | ||
1119 | } | ||
1120 | |||
1121 | /// <summary> | ||
1122 | /// Send updates to all clients who might be interested in groups data for dataForClientID | ||
1123 | /// </summary> | ||
1124 | private void UpdateAllClientsWithGroupInfo(UUID dataForClientID) | ||
1125 | { | ||
1126 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | ||
1127 | |||
1128 | // TODO: Probably isn't nessesary to update every client in every scene. | ||
1129 | // Need to examine client updates and do only what's nessesary. | ||
1130 | lock (m_sceneList) | ||
1131 | { | ||
1132 | foreach (Scene scene in m_sceneList) | ||
1133 | { | ||
1134 | scene.ForEachClient(delegate(IClientAPI client) { SendAgentGroupDataUpdate(client, dataForClientID); }); | ||
1135 | } | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | /// <summary> | ||
1140 | /// Update remoteClient with group information about dataForAgentID | ||
1141 | /// </summary> | ||
1142 | private void SendAgentGroupDataUpdate(IClientAPI client, UUID dataForAgentID) | ||
1143 | { | ||
1144 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, client.Name); | ||
1145 | |||
1146 | // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff | ||
1147 | |||
1148 | OnAgentDataUpdateRequest(client, dataForAgentID, UUID.Zero); | ||
1149 | |||
1150 | |||
1151 | // Need to send a group membership update to the client | ||
1152 | // UDP version doesn't seem to behave nicely | ||
1153 | // client.SendGroupMembership(GetMembershipData(client.AgentId)); | ||
1154 | |||
1155 | GroupMembershipData[] membershipData = m_groupData.GetAgentGroupMemberships(dataForAgentID).ToArray(); | ||
1156 | |||
1157 | SendGroupMembershipInfoViaCaps(client, dataForAgentID, membershipData); | ||
1158 | client.SendAvatarGroupsReply(dataForAgentID, membershipData); | ||
1159 | |||
1160 | } | ||
1161 | |||
1162 | private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) | ||
1163 | { | ||
1164 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | ||
1165 | |||
1166 | // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff | ||
1167 | UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(dataForAgentID); | ||
1168 | string firstname, lastname; | ||
1169 | if (userProfile != null) | ||
1170 | { | ||
1171 | firstname = userProfile.FirstName; | ||
1172 | lastname = userProfile.SurName; | ||
1173 | } | ||
1174 | else | ||
1175 | { | ||
1176 | firstname = "Unknown"; | ||
1177 | lastname = "Unknown"; | ||
1178 | } | ||
1179 | |||
1180 | remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, | ||
1181 | lastname, activeGroupPowers, activeGroupName, | ||
1182 | activeGroupTitle); | ||
1183 | } | ||
1184 | |||
1185 | #endregion | ||
1186 | |||
1187 | #region IM Backed Processes | ||
1188 | |||
1189 | private void OutgoingInstantMessage(GridInstantMessage msg, UUID msgTo) | ||
1190 | { | ||
1191 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | ||
1192 | |||
1193 | IClientAPI localClient = GetActiveClient(msgTo); | ||
1194 | if (localClient != null) | ||
1195 | { | ||
1196 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] MsgTo ({0}) is local, delivering directly", localClient.Name); | ||
1197 | localClient.SendInstantMessage(msg); | ||
1198 | } | ||
1199 | else | ||
1200 | { | ||
1201 | if (m_debugEnabled) m_log.InfoFormat("[GROUPS] MsgTo ({0}) is not local, delivering via TransferModule", msgTo); | ||
1202 | m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS] Message Sent: {0}", success?"Succeeded":"Failed"); }); | ||
1203 | } | ||
1204 | } | ||
1205 | |||
1206 | #endregion | ||
1068 | } | 1207 | } |
1069 | 1208 | ||
1070 | } | 1209 | } |