aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs31
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs42
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs43
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs29
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs27
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs4
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs58
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs43
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs87
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs20
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs22
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs64
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs183
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs237
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs517
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs7
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs95
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs23
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs86
19 files changed, 841 insertions, 777 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs
index 84211a9..0698cec 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Animations/AnimationsCommandModule.cs
@@ -42,6 +42,7 @@ using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
43using OpenSim.Region.Framework.Scenes.Animation; 43using OpenSim.Region.Framework.Scenes.Animation;
44using OpenSim.Services.Interfaces; 44using OpenSim.Services.Interfaces;
45using AnimationSet = OpenSim.Region.Framework.Scenes.Animation.AnimationSet;
45 46
46namespace OpenSim.Region.OptionalModules.Avatar.Animations 47namespace OpenSim.Region.OptionalModules.Avatar.Animations
47{ 48{
@@ -56,41 +57,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations
56 private List<Scene> m_scenes = new List<Scene>(); 57 private List<Scene> m_scenes = new List<Scene>();
57 58
58 public string Name { get { return "Animations Command Module"; } } 59 public string Name { get { return "Animations Command Module"; } }
59 60
60 public Type ReplaceableInterface { get { return null; } } 61 public Type ReplaceableInterface { get { return null; } }
61 62
62 public void Initialise(IConfigSource source) 63 public void Initialise(IConfigSource source)
63 { 64 {
64// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE"); 65// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE");
65 } 66 }
66 67
67 public void PostInitialise() 68 public void PostInitialise()
68 { 69 {
69// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE"); 70// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE");
70 } 71 }
71 72
72 public void Close() 73 public void Close()
73 { 74 {
74// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE"); 75// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE");
75 } 76 }
76 77
77 public void AddRegion(Scene scene) 78 public void AddRegion(Scene scene)
78 { 79 {
79// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); 80// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
80 } 81 }
81 82
82 public void RemoveRegion(Scene scene) 83 public void RemoveRegion(Scene scene)
83 { 84 {
84// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); 85// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
85 86
86 lock (m_scenes) 87 lock (m_scenes)
87 m_scenes.Remove(scene); 88 m_scenes.Remove(scene);
88 } 89 }
89 90
90 public void RegionLoaded(Scene scene) 91 public void RegionLoaded(Scene scene)
91 { 92 {
92// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); 93// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
93 94
94 lock (m_scenes) 95 lock (m_scenes)
95 m_scenes.Add(scene); 96 m_scenes.Add(scene);
96 97
@@ -155,18 +156,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations
155 156
156 string cma = spa.CurrentMovementAnimation; 157 string cma = spa.CurrentMovementAnimation;
157 cdl.AddRow( 158 cdl.AddRow(
158 "Current movement anim", 159 "Current movement anim",
159 string.Format("{0}, {1}", DefaultAvatarAnimations.GetDefaultAnimation(cma), cma)); 160 string.Format("{0}, {1}", DefaultAvatarAnimations.GetDefaultAnimation(cma), cma));
160 161
161 UUID defaultAnimId = anims.DefaultAnimation.AnimID; 162 UUID defaultAnimId = anims.DefaultAnimation.AnimID;
162 cdl.AddRow( 163 cdl.AddRow(
163 "Default anim", 164 "Default anim",
164 string.Format("{0}, {1}", defaultAnimId, sp.Animator.GetAnimName(defaultAnimId))); 165 string.Format("{0}, {1}", defaultAnimId, sp.Animator.GetAnimName(defaultAnimId)));
165 166
166 UUID implicitDefaultAnimId = anims.ImplicitDefaultAnimation.AnimID; 167 UUID implicitDefaultAnimId = anims.ImplicitDefaultAnimation.AnimID;
167 cdl.AddRow( 168 cdl.AddRow(
168 "Implicit default anim", 169 "Implicit default anim",
169 string.Format("{0}, {1}", 170 string.Format("{0}, {1}",
170 implicitDefaultAnimId, sp.Animator.GetAnimName(implicitDefaultAnimId))); 171 implicitDefaultAnimId, sp.Animator.GetAnimName(implicitDefaultAnimId)));
171 172
172 cdl.AddToStringBuilder(sb); 173 cdl.AddToStringBuilder(sb);
@@ -197,4 +198,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Animations
197 sb.Append("\n"); 198 sb.Append("\n");
198 } 199 }
199 } 200 }
200} \ No newline at end of file 201}
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
index 2f9bb1e..60ae0cb 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -54,43 +54,43 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
54 private List<Scene> m_scenes = new List<Scene>(); 54 private List<Scene> m_scenes = new List<Scene>();
55 55
56// private IAvatarFactoryModule m_avatarFactory; 56// private IAvatarFactoryModule m_avatarFactory;
57 57
58 public string Name { get { return "Appearance Information Module"; } } 58 public string Name { get { return "Appearance Information Module"; } }
59 59
60 public Type ReplaceableInterface { get { return null; } } 60 public Type ReplaceableInterface { get { return null; } }
61 61
62 public void Initialise(IConfigSource source) 62 public void Initialise(IConfigSource source)
63 { 63 {
64// m_log.DebugFormat("[APPEARANCE INFO MODULE]: INITIALIZED MODULE"); 64// m_log.DebugFormat("[APPEARANCE INFO MODULE]: INITIALIZED MODULE");
65 } 65 }
66 66
67 public void PostInitialise() 67 public void PostInitialise()
68 { 68 {
69// m_log.DebugFormat("[APPEARANCE INFO MODULE]: POST INITIALIZED MODULE"); 69// m_log.DebugFormat("[APPEARANCE INFO MODULE]: POST INITIALIZED MODULE");
70 } 70 }
71 71
72 public void Close() 72 public void Close()
73 { 73 {
74// m_log.DebugFormat("[APPEARANCE INFO MODULE]: CLOSED MODULE"); 74// m_log.DebugFormat("[APPEARANCE INFO MODULE]: CLOSED MODULE");
75 } 75 }
76 76
77 public void AddRegion(Scene scene) 77 public void AddRegion(Scene scene)
78 { 78 {
79// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); 79// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
80 } 80 }
81 81
82 public void RemoveRegion(Scene scene) 82 public void RemoveRegion(Scene scene)
83 { 83 {
84// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); 84// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
85 85
86 lock (m_scenes) 86 lock (m_scenes)
87 m_scenes.Remove(scene); 87 m_scenes.Remove(scene);
88 } 88 }
89 89
90 public void RegionLoaded(Scene scene) 90 public void RegionLoaded(Scene scene)
91 { 91 {
92// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); 92// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
93 93
94 lock (m_scenes) 94 lock (m_scenes)
95 m_scenes.Add(scene); 95 m_scenes.Add(scene);
96 96
@@ -99,7 +99,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
99 "show appearance [<first-name> <last-name>]", 99 "show appearance [<first-name> <last-name>]",
100 "Synonym for 'appearance show'", 100 "Synonym for 'appearance show'",
101 HandleShowAppearanceCommand); 101 HandleShowAppearanceCommand);
102 102
103 scene.AddCommand( 103 scene.AddCommand(
104 "Users", this, "appearance show", 104 "Users", this, "appearance show",
105 "appearance show [<first-name> <last-name>]", 105 "appearance show [<first-name> <last-name>]",
@@ -222,7 +222,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
222 } 222 }
223 223
224 lock (m_scenes) 224 lock (m_scenes)
225 { 225 {
226 foreach (Scene scene in m_scenes) 226 foreach (Scene scene in m_scenes)
227 { 227 {
228 if (targetNameSupplied) 228 if (targetNameSupplied)
@@ -344,7 +344,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
344 344
345 if (targetNameSupplied) 345 if (targetNameSupplied)
346 { 346 {
347 lock (m_scenes) 347 lock (m_scenes)
348 { 348 {
349 foreach (Scene scene in m_scenes) 349 foreach (Scene scene in m_scenes)
350 { 350 {
@@ -360,12 +360,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
360 cdt.AddColumn("Name", ConsoleDisplayUtil.UserNameSize); 360 cdt.AddColumn("Name", ConsoleDisplayUtil.UserNameSize);
361 cdt.AddColumn("Wearables", 2); 361 cdt.AddColumn("Wearables", 2);
362 362
363 lock (m_scenes) 363 lock (m_scenes)
364 { 364 {
365 foreach (Scene scene in m_scenes) 365 foreach (Scene scene in m_scenes)
366 { 366 {
367 scene.ForEachRootScenePresence( 367 scene.ForEachRootScenePresence(
368 sp => 368 sp =>
369 { 369 {
370 int count = 0; 370 int count = 0;
371 371
@@ -428,7 +428,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
428 428
429 uuidGatherer.AddForInspection(wi.AssetID); 429 uuidGatherer.AddForInspection(wi.AssetID);
430 uuidGatherer.GatherAll(); 430 uuidGatherer.GatherAll();
431 string[] assetStrings 431 string[] assetStrings
432 = Array.ConvertAll<UUID, string>(uuidGatherer.GatheredUuids.Keys.ToArray(), u => u.ToString()); 432 = Array.ConvertAll<UUID, string>(uuidGatherer.GatheredUuids.Keys.ToArray(), u => u.ToString());
433 433
434 bool[] existChecks = scene.AssetService.AssetsExist(assetStrings); 434 bool[] existChecks = scene.AssetService.AssetsExist(assetStrings);
@@ -438,10 +438,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance
438 cdt.AddColumn("Type", 10); 438 cdt.AddColumn("Type", 10);
439 cdt.AddColumn("UUID", ConsoleDisplayUtil.UuidSize); 439 cdt.AddColumn("UUID", ConsoleDisplayUtil.UuidSize);
440 cdt.AddColumn("Found", 5); 440 cdt.AddColumn("Found", 5);
441 441
442 for (int k = 0; k < existChecks.Length; k++) 442 for (int k = 0; k < existChecks.Length; k++)
443 cdt.AddRow( 443 cdt.AddRow(
444 (AssetType)uuidGatherer.GatheredUuids[new UUID(assetStrings[k])], 444 (AssetType)uuidGatherer.GatheredUuids[new UUID(assetStrings[k])],
445 assetStrings[k], existChecks[k] ? "yes" : "no"); 445 assetStrings[k], existChecks[k] ? "yes" : "no");
446 446
447 sb.Append(cdt.ToString()); 447 sb.Append(cdt.ToString());
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
index 0333747..3685041 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs
@@ -55,41 +55,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
55// private IAvatarFactoryModule m_avatarFactory; 55// private IAvatarFactoryModule m_avatarFactory;
56 56
57 public string Name { get { return "Attachments Command Module"; } } 57 public string Name { get { return "Attachments Command Module"; } }
58 58
59 public Type ReplaceableInterface { get { return null; } } 59 public Type ReplaceableInterface { get { return null; } }
60 60
61 public void Initialise(IConfigSource source) 61 public void Initialise(IConfigSource source)
62 { 62 {
63// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: INITIALIZED MODULE"); 63// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: INITIALIZED MODULE");
64 } 64 }
65 65
66 public void PostInitialise() 66 public void PostInitialise()
67 { 67 {
68// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: POST INITIALIZED MODULE"); 68// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: POST INITIALIZED MODULE");
69 } 69 }
70 70
71 public void Close() 71 public void Close()
72 { 72 {
73// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: CLOSED MODULE"); 73// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: CLOSED MODULE");
74 } 74 }
75 75
76 public void AddRegion(Scene scene) 76 public void AddRegion(Scene scene)
77 { 77 {
78// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); 78// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
79 } 79 }
80 80
81 public void RemoveRegion(Scene scene) 81 public void RemoveRegion(Scene scene)
82 { 82 {
83// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); 83// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
84 84
85 lock (m_scenes) 85 lock (m_scenes)
86 m_scenes.Remove(scene); 86 m_scenes.Remove(scene);
87 } 87 }
88 88
89 public void RegionLoaded(Scene scene) 89 public void RegionLoaded(Scene scene)
90 { 90 {
91// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); 91// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
92 92
93 lock (m_scenes) 93 lock (m_scenes)
94 m_scenes.Add(scene); 94 m_scenes.Add(scene);
95 95
@@ -144,14 +144,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
144 144
145 private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb) 145 private void GetAttachmentsReport(ScenePresence sp, StringBuilder sb)
146 { 146 {
147 sb.AppendFormat("Attachments for {0}\n", sp.Name); 147 sb.AppendFormat("Attachments for {0}\n\n", sp.Name);
148 148
149 ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; 149 ConsoleDisplayList ct = new ConsoleDisplayList();
150 ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 50));
151 ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10));
152 ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36));
153 ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14));
154 ct.Columns.Add(new ConsoleDisplayTableColumn("Position", 15));
155 150
156// sb.AppendFormat( 151// sb.AppendFormat(
157// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", 152// " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n",
@@ -177,17 +172,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
177// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, 172// attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID,
178// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); 173// (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos);
179 174
180 ct.AddRow( 175 ct.Indent = 2;
181 attachmentObject.Name, 176 ct.AddRow("Attachment Name", attachmentObject.Name);
182 attachmentObject.LocalId, 177 ct.AddRow("Local ID", attachmentObject.LocalId);
183 attachmentObject.FromItemID, 178 ct.AddRow("Item ID", attachmentObject.UUID);
184 ((AttachmentPoint)attachmentObject.AttachmentPoint), 179 ct.AddRow("From Item ID", attachmentObject.FromItemID);
185 attachmentObject.RootPart.AttachedPos); 180 ct.AddRow("Attach Point", ((AttachmentPoint)attachmentObject.AttachmentPoint));
181 ct.AddRow("Position", attachmentObject.RootPart.AttachedPos + "\n\n");
186// } 182// }
187 } 183 }
188 184
189 ct.AddToStringBuilder(sb); 185 ct.AddToStringBuilder(sb);
190 sb.Append("\n");
191 } 186 }
192 } 187 }
193} \ No newline at end of file 188} \ No newline at end of file
diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs
index 535bf67..c3f3851 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/TempAttachmentsModule.cs
@@ -125,7 +125,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
125 SendConsoleOutput(agentID, "Command parameter error"); 125 SendConsoleOutput(agentID, "Command parameter error");
126 return; 126 return;
127 } 127 }
128 128
129 m_scene.StoreExtraSetting("auto_grant_attach_perms", val); 129 m_scene.StoreExtraSetting("auto_grant_attach_perms", val);
130 130
131 SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val)); 131 SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val));
@@ -134,11 +134,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
134 private int llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint) 134 private int llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint)
135 { 135 {
136 SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host); 136 SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host);
137
138 if (hostPart == null) 137 if (hostPart == null)
139 return 0; 138 return 0;
140 139
141 if (hostPart.ParentGroup.IsAttachment) 140 SceneObjectGroup hostgroup = hostPart.ParentGroup;
141
142 if (hostgroup== null || hostgroup.IsAttachment)
142 return 0; 143 return 0;
143 144
144 IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface<IAttachmentsModule>(); 145 IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface<IAttachmentsModule>();
@@ -155,33 +156,33 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
155 ScenePresence target; 156 ScenePresence target;
156 if (!m_scene.TryGetScenePresence(item.PermsGranter, out target)) 157 if (!m_scene.TryGetScenePresence(item.PermsGranter, out target))
157 return 0; 158 return 0;
158 159
159 if (target.UUID != hostPart.ParentGroup.OwnerID) 160 if (target.UUID != hostgroup.OwnerID)
160 { 161 {
161 uint effectivePerms = hostPart.ParentGroup.GetEffectivePermissions(); 162 uint effectivePerms = hostgroup.EffectiveOwnerPerms;
162 163
163 if ((effectivePerms & (uint)PermissionMask.Transfer) == 0) 164 if ((effectivePerms & (uint)PermissionMask.Transfer) == 0)
164 return 0; 165 return 0;
165 166
166 hostPart.ParentGroup.SetOwnerId(target.UUID); 167 hostgroup.SetOwner(target.UUID, target.ControllingClient.ActiveGroupId);
167 hostPart.ParentGroup.SetRootPartOwner(hostPart.ParentGroup.RootPart, target.UUID, target.ControllingClient.ActiveGroupId);
168 168
169 if (m_scene.Permissions.PropagatePermissions()) 169 if (m_scene.Permissions.PropagatePermissions())
170 { 170 {
171 foreach (SceneObjectPart child in hostPart.ParentGroup.Parts) 171 foreach (SceneObjectPart child in hostgroup.Parts)
172 { 172 {
173 child.Inventory.ChangeInventoryOwner(target.UUID); 173 child.Inventory.ChangeInventoryOwner(target.UUID);
174 child.TriggerScriptChangedEvent(Changed.OWNER); 174 child.TriggerScriptChangedEvent(Changed.OWNER);
175 child.ApplyNextOwnerPermissions(); 175 child.ApplyNextOwnerPermissions();
176 } 176 }
177 hostgroup.InvalidateEffectivePerms();
177 } 178 }
178 179
179 hostPart.ParentGroup.RootPart.ObjectSaleType = 0; 180 hostgroup.RootPart.ObjectSaleType = 0;
180 hostPart.ParentGroup.RootPart.SalePrice = 10; 181 hostgroup.RootPart.SalePrice = 10;
181 182
182 hostPart.ParentGroup.HasGroupChanged = true; 183 hostgroup.HasGroupChanged = true;
183 hostPart.ParentGroup.RootPart.SendPropertiesToClient(target.ControllingClient); 184 hostgroup.RootPart.SendPropertiesToClient(target.ControllingClient);
184 hostPart.ParentGroup.RootPart.ScheduleFullUpdate(); 185 hostgroup.RootPart.ScheduleFullUpdate();
185 } 186 }
186 187
187 return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, false, true) ? 1 : 0; 188 return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, false, true) ? 1 : 0;
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs
index b5d9fda..27ab32f 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/ChannelState.cs
@@ -38,7 +38,7 @@ using OpenSim.Region.Framework.Scenes;
38namespace OpenSim.Region.OptionalModules.Avatar.Chat 38namespace OpenSim.Region.OptionalModules.Avatar.Chat
39{ 39{
40 40
41 // An instance of this class exists for each unique combination of 41 // An instance of this class exists for each unique combination of
42 // IRC chat interface characteristics, as determined by the supplied 42 // IRC chat interface characteristics, as determined by the supplied
43 // configuration file. 43 // configuration file.
44 44
@@ -48,7 +48,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
48 private static readonly ILog m_log = 48 private static readonly ILog m_log =
49 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 private static Regex arg = new Regex(@"\[[^\[\]]*\]"); 51 private static Regex arg = new Regex(@"(?<!\\)\[[^\[\]]*(?<!\\)\]");
52 private static int _idk_ = 0; 52 private static int _idk_ = 0;
53 private static int DEBUG_CHANNEL = 2147483647; 53 private static int DEBUG_CHANNEL = 2147483647;
54 54
@@ -266,11 +266,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
266 ChannelState cs = p_cs; 266 ChannelState cs = p_cs;
267 267
268 // Check to see if we have an existing server/channel setup that can be used 268 // Check to see if we have an existing server/channel setup that can be used
269 // In the absence of variable substitution this will always resolve to the 269 // In the absence of variable substitution this will always resolve to the
270 // same ChannelState instance, and the table will only contains a single 270 // same ChannelState instance, and the table will only contains a single
271 // entry, so the performance considerations for the existing behavior are 271 // entry, so the performance considerations for the existing behavior are
272 // zero. Only the IRC connector is shared, the ChannelState still contains 272 // zero. Only the IRC connector is shared, the ChannelState still contains
273 // values that, while independent of the IRC connetion, do still distinguish 273 // values that, while independent of the IRC connetion, do still distinguish
274 // this region's behavior. 274 // this region's behavior.
275 275
276 lock (IRCBridgeModule.m_channels) 276 lock (IRCBridgeModule.m_channels)
@@ -335,7 +335,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
335 335
336 } 336 }
337 337
338 // These routines allow differentiating changes to 338 // These routines allow differentiating changes to
339 // the underlying channel state. If necessary, a 339 // the underlying channel state. If necessary, a
340 // new channel state will be created. 340 // new channel state will be created.
341 341
@@ -426,7 +426,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
426 } 426 }
427 427
428 // This level of obsessive matching allows us to produce 428 // This level of obsessive matching allows us to produce
429 // a minimal overhead int he case of a server which does 429 // a minimal overhead int he case of a server which does
430 // need to differentiate IRC at a region level. 430 // need to differentiate IRC at a region level.
431 431
432 private bool IsAPerfectMatchFor(ChannelState cs) 432 private bool IsAPerfectMatchFor(ChannelState cs)
@@ -447,8 +447,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
447 ); 447 );
448 } 448 }
449 449
450 // This function implements the variable substitution mechanism 450 // This function implements the variable substitution mechanism
451 // for the configuration values. Each string read from the 451 // for the configuration values. Each string read from the
452 // configuration file is scanned for '[...]' enclosures. Each 452 // configuration file is scanned for '[...]' enclosures. Each
453 // one that is found is replaced by either a runtime variable 453 // one that is found is replaced by either a runtime variable
454 // (%xxx) or an existing configuration key. When no further 454 // (%xxx) or an existing configuration key. When no further
@@ -499,6 +499,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
499 // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result); 499 // m_log.DebugFormat("[IRC-Channel] Parse[2]: {0}", result);
500 } 500 }
501 501
502 // Now we unescape the literal brackets
503 result = result.Replace(@"\[","[").Replace(@"\]","]");
504
502 // m_log.DebugFormat("[IRC-Channel] Parse[3]: {0}", result); 505 // m_log.DebugFormat("[IRC-Channel] Parse[3]: {0}", result);
503 return result; 506 return result;
504 507
@@ -582,7 +585,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
582 585
583 } 586 }
584 587
585 // This function is lifted from the IRCConnector because it 588 // This function is lifted from the IRCConnector because it
586 // contains information that is not differentiating from an 589 // contains information that is not differentiating from an
587 // IRC point-of-view. 590 // IRC point-of-view.
588 591
@@ -595,7 +598,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
595 { 598 {
596 599
597 // Scan through the set of unique channel configuration for those 600 // Scan through the set of unique channel configuration for those
598 // that belong to this connector. And then forward the message to 601 // that belong to this connector. And then forward the message to
599 // all regions known to those channels. 602 // all regions known to those channels.
600 // Note that this code is responsible for completing some of the 603 // Note that this code is responsible for completing some of the
601 // settings for the inbound OSChatMessage 604 // settings for the inbound OSChatMessage
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs
index 351dbfe..d6b6642 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCBridgeModule.cs
@@ -79,6 +79,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
79 if (!m_config.GetBoolean("enabled", false)) 79 if (!m_config.GetBoolean("enabled", false))
80 { 80 {
81 // m_log.InfoFormat("[IRC-Bridge] module disabled in configuration"); 81 // m_log.InfoFormat("[IRC-Bridge] module disabled in configuration");
82 m_config = null;
82 return; 83 return;
83 } 84 }
84 85
@@ -104,7 +105,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
104 MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false); 105 MainServer.Instance.AddXmlRPCHandler("irc_admin", XmlRpcAdminMethod, false);
105 106
106 m_region = new RegionState(scene, m_config); 107 m_region = new RegionState(scene, m_config);
107 lock (m_regions) m_regions.Add(m_region); 108 lock (m_regions)
109 m_regions.Add(m_region);
108 m_region.Open(); 110 m_region.Open();
109 } 111 }
110 catch (Exception e) 112 catch (Exception e)
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
index 6985371..ffbebe7 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/IRCConnector.cs
@@ -97,14 +97,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
97 97
98 // How many regions depend upon this connection 98 // How many regions depend upon this connection
99 // This count is updated by the ChannelState object and reflects the sum 99 // This count is updated by the ChannelState object and reflects the sum
100 // of the region clients associated with the set of associated channel 100 // of the region clients associated with the set of associated channel
101 // state instances. That's why it cannot be managed here. 101 // state instances. That's why it cannot be managed here.
102 102
103 internal int depends = 0; 103 internal int depends = 0;
104 104
105 // This variable counts the number of resets that have been performed 105 // This variable counts the number of resets that have been performed
106 // on the connector. When a listener thread terminates, it checks to 106 // on the connector. When a listener thread terminates, it checks to
107 // see of the reset count has changed before it schedules another 107 // see of the reset count has changed before it schedules another
108 // reset. 108 // reset.
109 109
110 internal int m_resetk = 0; 110 internal int m_resetk = 0;
@@ -270,7 +270,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
270 270
271 public void Close() 271 public void Close()
272 { 272 {
273
274 m_log.InfoFormat("[IRC-Connector-{0}] Closing", idn); 273 m_log.InfoFormat("[IRC-Connector-{0}] Closing", idn);
275 274
276 lock (msyncConnect) 275 lock (msyncConnect)
@@ -295,7 +294,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
295 } 294 }
296 catch (Exception) { } 295 catch (Exception) { }
297 296
298
299 m_connected = false; 297 m_connected = false;
300 298
301 try { m_writer.Close(); } 299 try { m_writer.Close(); }
@@ -308,10 +306,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
308 catch (Exception) { } 306 catch (Exception) { }
309 307
310 } 308 }
311
312 lock (m_connectors) 309 lock (m_connectors)
313 m_connectors.Remove(this); 310 m_connectors.Remove(this);
314
315 } 311 }
316 } 312 }
317 313
@@ -327,25 +323,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
327 323
328 public void Connect() 324 public void Connect()
329 { 325 {
330
331 if (!m_enabled) 326 if (!m_enabled)
332 return; 327 return;
333 328
334 // Delay until next WD cycle if this is too close to the last start attempt 329 // Delay until next WD cycle if this is too close to the last start attempt
335 330 if(_icc_ < ICCD_PERIOD)
336 while (_icc_ < ICCD_PERIOD)
337 return; 331 return;
338 332
339 m_log.DebugFormat("[IRC-Connector-{0}]: Connection request for {1} on {2}:{3}", idn, m_nick, m_server, m_ircChannel); 333 m_log.DebugFormat("[IRC-Connector-{0}]: Connection request for {1} on {2}:{3}", idn, m_nick, m_server, m_ircChannel);
340 334
335 _icc_ = 0;
336
341 lock (msyncConnect) 337 lock (msyncConnect)
342 { 338 {
343
344 _icc_ = 0;
345
346 try 339 try
347 { 340 {
348
349 if (m_connected) return; 341 if (m_connected) return;
350 342
351 m_connected = true; 343 m_connected = true;
@@ -368,11 +360,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
368 m_writer.Flush(); 360 m_writer.Flush();
369 m_writer.WriteLine(m_user); 361 m_writer.WriteLine(m_user);
370 m_writer.Flush(); 362 m_writer.Flush();
371 m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel));
372 m_writer.Flush();
373
374 m_log.InfoFormat("[IRC-Connector-{0}]: {1} has asked to join {2}", idn, m_nick, m_ircChannel);
375
376 } 363 }
377 catch (Exception e) 364 catch (Exception e)
378 { 365 {
@@ -384,11 +371,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
384 // expires. By leaving them as they are, the connection will be retried 371 // expires. By leaving them as they are, the connection will be retried
385 // when the login timeout expires. Which is preferred. 372 // when the login timeout expires. Which is preferred.
386 } 373 }
387
388 } 374 }
389 375
390 return; 376 return;
391
392 } 377 }
393 378
394 // Reconnect is used to force a re-cycle of the IRC connection. Should generally 379 // Reconnect is used to force a re-cycle of the IRC connection. Should generally
@@ -443,7 +428,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
443 public void PrivMsg(string pattern, string from, string region, string msg) 428 public void PrivMsg(string pattern, string from, string region, string msg)
444 { 429 {
445 430
446 // m_log.DebugFormat("[IRC-Connector-{0}] PrivMsg to IRC from {1}: <{2}>", idn, from, 431 // m_log.DebugFormat("[IRC-Connector-{0}] PrivMsg to IRC from {1}: <{2}>", idn, from,
447 // String.Format(pattern, m_ircChannel, from, region, msg)); 432 // String.Format(pattern, m_ircChannel, from, region, msg));
448 433
449 // One message to the IRC server 434 // One message to the IRC server
@@ -521,11 +506,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
521 c.Message = data["msg"]; 506 c.Message = data["msg"];
522 c.Type = ChatTypeEnum.Region; 507 c.Type = ChatTypeEnum.Region;
523 c.Position = CenterOfRegion; 508 c.Position = CenterOfRegion;
524 c.From = data["nick"]; 509 c.From = data["nick"] + "@IRC";
525 c.Sender = null; 510 c.Sender = null;
526 c.SenderUUID = UUID.Zero; 511 c.SenderUUID = UUID.Zero;
527 512
528 // Is message "\001ACTION foo bar\001"? 513 // Is message "\001ACTION foo bar\001"?
529 // Then change to: "/me foo bar" 514 // Then change to: "/me foo bar"
530 515
531 if ((1 == c.Message[0]) && c.Message.Substring(1).StartsWith("ACTION")) 516 if ((1 == c.Message[0]) && c.Message.Substring(1).StartsWith("ACTION"))
@@ -623,8 +608,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
623 string parms = String.Empty; 608 string parms = String.Empty;
624 609
625 // ":" indicates that a prefix is present 610 // ":" indicates that a prefix is present
626 // There are NEVER more than 17 real 611 // There are NEVER more than 17 real
627 // fields. A parameter that starts with 612 // fields. A parameter that starts with
628 // ":" indicates that the remainder of the 613 // ":" indicates that the remainder of the
629 // line is a single parameter value. 614 // line is a single parameter value.
630 615
@@ -659,6 +644,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
659 version = commArgs[2]; 644 version = commArgs[2];
660 usermod = commArgs[3]; 645 usermod = commArgs[3];
661 chanmod = commArgs[4]; 646 chanmod = commArgs[4];
647
648 m_writer.WriteLine(String.Format("JOIN {0}", m_ircChannel));
649 m_writer.Flush();
650 m_log.InfoFormat("[IRC-Connector-{0}]: sent request to join {1} ", idn, m_ircChannel);
651
662 break; 652 break;
663 case "005": // Server information 653 case "005": // Server information
664 break; 654 break;
@@ -721,11 +711,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
721 case "PONG": 711 case "PONG":
722 break; 712 break;
723 case "JOIN": 713 case "JOIN":
724 if (m_pending) 714
725 {
726 m_log.InfoFormat("[IRC-Connector-{0}] [{1}] Connected", idn, cmd);
727 m_pending = false;
728 }
729 m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms); 715 m_log.DebugFormat("[IRC-Connector-{0}] [{1}] parms = <{2}>", idn, cmd, parms);
730 eventIrcJoin(pfx, cmd, parms); 716 eventIrcJoin(pfx, cmd, parms);
731 break; 717 break;
@@ -767,7 +753,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
767 if (IrcChannel.StartsWith(":")) 753 if (IrcChannel.StartsWith(":"))
768 IrcChannel = IrcChannel.Substring(1); 754 IrcChannel = IrcChannel.Substring(1);
769 755
770 m_log.DebugFormat("[IRC-Connector-{0}] Event: IRCJoin {1}:{2}", idn, m_server, m_ircChannel); 756 if(IrcChannel == m_ircChannel)
757 {
758 m_log.InfoFormat("[IRC-Connector-{0}] Joined requested channel {1} at {2}", idn, IrcChannel,m_server);
759 m_pending = false;
760 }
761 else
762 m_log.InfoFormat("[IRC-Connector-{0}] Joined unknown channel {1} at {2}", idn, IrcChannel,m_server);
771 BroadcastSim(IrcUser, "/me joins {0}", IrcChannel); 763 BroadcastSim(IrcUser, "/me joins {0}", IrcChannel);
772 } 764 }
773 765
@@ -881,7 +873,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
881 } 873 }
882 874
883 // Being marked connected is not enough to ping. Socket establishment can sometimes take a long 875 // Being marked connected is not enough to ping. Socket establishment can sometimes take a long
884 // time, in which case the watch dog might try to ping the server before the socket has been 876 // time, in which case the watch dog might try to ping the server before the socket has been
885 // set up, with nasty side-effects. 877 // set up, with nasty side-effects.
886 878
887 else if (_pdk_ == 0) 879 else if (_pdk_ == 0)
diff --git a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
index 6ea542c..a3ef83b 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Chat/RegionState.cs
@@ -389,39 +389,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
389 } 389 }
390 390
391 m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message); 391 m_log.DebugFormat("[IRC-Region {0}] heard on channel {1} : {2}", Region, msg.Channel, msg.Message);
392 string txt = msg.Message;
393 392
394 if (null != avatar) 393 if (null != avatar && cs.RelayChat && (msg.Channel == 0 || msg.Channel == DEBUG_CHANNEL))
395 { 394 {
396 if ((!cs.RelayChat) || (msg.Channel != 0 && msg.Channel != DEBUG_CHANNEL)) 395 string txt = msg.Message;
397 return; 396 if (txt.StartsWith("/me "))
397 txt = String.Format("{0} {1}", fromName, msg.Message.Substring(4));
398
399 cs.irc.PrivMsg(cs.PrivateMessageFormat, fromName, Region, txt);
400 return;
398 } 401 }
399 else 402
403 if (null == avatar && cs.RelayPrivateChannels && null != cs.AccessPassword &&
404 msg.Channel == cs.RelayChannelOut)
400 { 405 {
401 if (cs.RelayPrivateChannels && msg.Channel == cs.RelayChannelOut) 406 Match m = cs.AccessPasswordRegex.Match(msg.Message);
407 if (null != m)
402 { 408 {
403 if (null != cs.AccessPassword) 409 m_log.DebugFormat("[IRC] relaying message from {0}: {1}", m.Groups["avatar"].ToString(),
404 { 410 m.Groups["message"].ToString());
405 Match m = cs.AccessPasswordRegex.Match(msg.Message); 411 cs.irc.PrivMsg(cs.PrivateMessageFormat, m.Groups["avatar"].ToString(),
406 if (null != m) 412 scene.RegionInfo.RegionName, m.Groups["message"].ToString());
407 {
408 if (m.Groups["avatar"].ToString() != "")
409 fromName = m.Groups["avatar"].ToString();
410 if (m.Groups["message"].ToString() != "")
411 txt = m.Groups["message"].ToString();
412 }
413 }
414 } 413 }
415 fromName = "OBJECT: " + fromName;
416 } 414 }
417
418 if (txt.StartsWith("/me "))
419 txt = String.Format("{0} {1}", fromName, msg.Message.Substring(4));
420 m_log.DebugFormat("[IRC] relaying message from {0}: {1}", fromName, txt);
421 cs.irc.PrivMsg(cs.PrivateMessageFormat, fromName, Region, txt);
422 } 415 }
423 416
424 // This method gives the region an opportunity to interfere with 417 // This method gives the region an opportunity to interfere with
425 // message delivery. For now we just enforce the enable/disable 418 // message delivery. For now we just enforce the enable/disable
426 // flag. 419 // flag.
427 420
@@ -435,7 +428,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Chat
435 } 428 }
436 } 429 }
437 430
438 // This supports any local message traffic that might be needed in 431 // This supports any local message traffic that might be needed in
439 // support of command processing. At present there is none. 432 // support of command processing. At present there is none.
440 433
441 internal void LocalChat(string msg) 434 internal void LocalChat(string msg)
diff --git a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
index c48e585..a5dc0ad 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Concierge/ConciergeModule.cs
@@ -53,15 +53,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 55
56 private const int DEBUG_CHANNEL = 2147483647; 56// private const int DEBUG_CHANNEL = 2147483647; use base value
57 57
58 private List<IScene> m_scenes = new List<IScene>(); 58 private new List<IScene> m_scenes = new List<IScene>();
59 private List<IScene> m_conciergedScenes = new List<IScene>(); 59 private List<IScene> m_conciergedScenes = new List<IScene>();
60 60
61 private bool m_replacingChatModule = false; 61 private bool m_replacingChatModule = false;
62 62
63 private IConfig m_config;
64
65 private string m_whoami = "conferencier"; 63 private string m_whoami = "conferencier";
66 private Regex m_regions = null; 64 private Regex m_regions = null;
67 private string m_welcomes = null; 65 private string m_welcomes = null;
@@ -72,63 +70,62 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
72 private string m_brokerURI = String.Empty; 70 private string m_brokerURI = String.Empty;
73 private int m_brokerUpdateTimeout = 300; 71 private int m_brokerUpdateTimeout = 300;
74 72
75 internal object m_syncy = new object(); 73 internal new object m_syncy = new object();
76 74
77 internal bool m_enabled = false; 75 internal new bool m_enabled = false;
78 76
79 #region ISharedRegionModule Members 77 #region ISharedRegionModule Members
80 public override void Initialise(IConfigSource config) 78 public override void Initialise(IConfigSource configSource)
81 { 79 {
82 m_config = config.Configs["Concierge"]; 80 IConfig config = configSource.Configs["Concierge"];
83 81
84 if (null == m_config) 82 if (config == null)
85 return; 83 return;
86 84
87 if (!m_config.GetBoolean("enabled", false)) 85 if (!config.GetBoolean("enabled", false))
88 return; 86 return;
89 87
90 m_enabled = true; 88 m_enabled = true;
91 89
92
93 // check whether ChatModule has been disabled: if yes, 90 // check whether ChatModule has been disabled: if yes,
94 // then we'll "stand in" 91 // then we'll "stand in"
95 try 92 try
96 { 93 {
97 if (config.Configs["Chat"] == null) 94 if (configSource.Configs["Chat"] == null)
98 { 95 {
99 // if Chat module has not been configured it's 96 // if Chat module has not been configured it's
100 // enabled by default, so we are not going to 97 // enabled by default, so we are not going to
101 // replace it. 98 // replace it.
102 m_replacingChatModule = false; 99 m_replacingChatModule = false;
103 } 100 }
104 else 101 else
105 { 102 {
106 m_replacingChatModule = !config.Configs["Chat"].GetBoolean("enabled", true); 103 m_replacingChatModule = !configSource.Configs["Chat"].GetBoolean("enabled", true);
107 } 104 }
108 } 105 }
109 catch (Exception) 106 catch (Exception)
110 { 107 {
111 m_replacingChatModule = false; 108 m_replacingChatModule = false;
112 } 109 }
113 110
114 m_log.InfoFormat("[Concierge] {0} ChatModule", m_replacingChatModule ? "replacing" : "not replacing"); 111 m_log.InfoFormat("[Concierge] {0} ChatModule", m_replacingChatModule ? "replacing" : "not replacing");
115 112
116 // take note of concierge channel and of identity 113 // take note of concierge channel and of identity
117 m_conciergeChannel = config.Configs["Concierge"].GetInt("concierge_channel", m_conciergeChannel); 114 m_conciergeChannel = configSource.Configs["Concierge"].GetInt("concierge_channel", m_conciergeChannel);
118 m_whoami = m_config.GetString("whoami", "conferencier"); 115 m_whoami = config.GetString("whoami", "conferencier");
119 m_welcomes = m_config.GetString("welcomes", m_welcomes); 116 m_welcomes = config.GetString("welcomes", m_welcomes);
120 m_announceEntering = m_config.GetString("announce_entering", m_announceEntering); 117 m_announceEntering = config.GetString("announce_entering", m_announceEntering);
121 m_announceLeaving = m_config.GetString("announce_leaving", m_announceLeaving); 118 m_announceLeaving = config.GetString("announce_leaving", m_announceLeaving);
122 m_xmlRpcPassword = m_config.GetString("password", m_xmlRpcPassword); 119 m_xmlRpcPassword = config.GetString("password", m_xmlRpcPassword);
123 m_brokerURI = m_config.GetString("broker", m_brokerURI); 120 m_brokerURI = config.GetString("broker", m_brokerURI);
124 m_brokerUpdateTimeout = m_config.GetInt("broker_timeout", m_brokerUpdateTimeout); 121 m_brokerUpdateTimeout = config.GetInt("broker_timeout", m_brokerUpdateTimeout);
125 122
126 m_log.InfoFormat("[Concierge] reporting as \"{0}\" to our users", m_whoami); 123 m_log.InfoFormat("[Concierge] reporting as \"{0}\" to our users", m_whoami);
127 124
128 // calculate regions Regex 125 // calculate regions Regex
129 if (m_regions == null) 126 if (m_regions == null)
130 { 127 {
131 string regions = m_config.GetString("regions", String.Empty); 128 string regions = config.GetString("regions", String.Empty);
132 if (!String.IsNullOrEmpty(regions)) 129 if (!String.IsNullOrEmpty(regions))
133 { 130 {
134 m_regions = new Regex(@regions, RegexOptions.Compiled | RegexOptions.IgnoreCase); 131 m_regions = new Regex(@regions, RegexOptions.Compiled | RegexOptions.IgnoreCase);
@@ -136,7 +133,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
136 } 133 }
137 } 134 }
138 135
139
140 public override void AddRegion(Scene scene) 136 public override void AddRegion(Scene scene)
141 { 137 {
142 if (!m_enabled) return; 138 if (!m_enabled) return;
@@ -211,7 +207,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
211 { 207 {
212 } 208 }
213 209
214 new public Type ReplaceableInterface 210 new public Type ReplaceableInterface
215 { 211 {
216 get { return null; } 212 get { return null; }
217 } 213 }
@@ -282,7 +278,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
282 // range of chat to cover the whole 278 // range of chat to cover the whole
283 // region. however, we don't do this for whisper 279 // region. however, we don't do this for whisper
284 // (got to have some privacy) 280 // (got to have some privacy)
285 if (c.Type != ChatTypeEnum.Whisper) 281 if (c.Type != ChatTypeEnum.Whisper)
286 { 282 {
287 base.OnChatBroadcast(sender, c); 283 base.OnChatBroadcast(sender, c);
288 return; 284 return;
@@ -300,17 +296,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
300 { 296 {
301 client.OnLogout += OnClientLoggedOut; 297 client.OnLogout += OnClientLoggedOut;
302 298
303 if (m_replacingChatModule) 299 if (m_replacingChatModule)
304 client.OnChatFromClient += OnChatFromClient; 300 client.OnChatFromClient += OnChatFromClient;
305 } 301 }
306 302
307 303
308 304
309 public void OnClientLoggedOut(IClientAPI client) 305 public void OnClientLoggedOut(IClientAPI client)
310 { 306 {
311 client.OnLogout -= OnClientLoggedOut; 307 client.OnLogout -= OnClientLoggedOut;
312 client.OnConnectionClosed -= OnClientLoggedOut; 308 client.OnConnectionClosed -= OnClientLoggedOut;
313 309
314 if (m_conciergedScenes.Contains(client.Scene)) 310 if (m_conciergedScenes.Contains(client.Scene))
315 { 311 {
316 Scene scene = client.Scene as Scene; 312 Scene scene = client.Scene as Scene;
@@ -328,7 +324,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
328 Scene scene = agent.Scene; 324 Scene scene = agent.Scene;
329 m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, scene.RegionInfo.RegionName); 325 m_log.DebugFormat("[Concierge]: {0} enters {1}", agent.Name, scene.RegionInfo.RegionName);
330 WelcomeAvatar(agent, scene); 326 WelcomeAvatar(agent, scene);
331 AnnounceToAgentsRegion(scene, String.Format(m_announceEntering, agent.Name, 327 AnnounceToAgentsRegion(scene, String.Format(m_announceEntering, agent.Name,
332 scene.RegionInfo.RegionName, scene.GetRootAgentCount())); 328 scene.RegionInfo.RegionName, scene.GetRootAgentCount()));
333 UpdateBroker(scene); 329 UpdateBroker(scene);
334 } 330 }
@@ -341,7 +337,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
341 { 337 {
342 Scene scene = agent.Scene; 338 Scene scene = agent.Scene;
343 m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, scene.RegionInfo.RegionName); 339 m_log.DebugFormat("[Concierge]: {0} leaves {1}", agent.Name, scene.RegionInfo.RegionName);
344 AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, agent.Name, 340 AnnounceToAgentsRegion(scene, String.Format(m_announceLeaving, agent.Name,
345 scene.RegionInfo.RegionName, scene.GetRootAgentCount())); 341 scene.RegionInfo.RegionName, scene.GetRootAgentCount()));
346 UpdateBroker(scene); 342 UpdateBroker(scene);
347 } 343 }
@@ -378,7 +374,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
378 374
379 scene.ForEachRootScenePresence(delegate(ScenePresence sp) 375 scene.ForEachRootScenePresence(delegate(ScenePresence sp)
380 { 376 {
381 list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID)); 377 list.Append(String.Format(" <avatar name=\"{0}\" uuid=\"{1}\" />\n", sp.Name, sp.UUID));
382 }); 378 });
383 379
384 list.Append("</avatars>"); 380 list.Append("</avatars>");
@@ -441,7 +437,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
441 private void UpdateBrokerDone(IAsyncResult result) 437 private void UpdateBrokerDone(IAsyncResult result)
442 { 438 {
443 BrokerState bs = null; 439 BrokerState bs = null;
444 try 440 try
445 { 441 {
446 bs = result.AsyncState as BrokerState; 442 bs = result.AsyncState as BrokerState;
447 HttpWebRequest updatePost = bs.Poster; 443 HttpWebRequest updatePost = bs.Poster;
@@ -454,19 +450,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
454 catch (WebException we) 450 catch (WebException we)
455 { 451 {
456 m_log.ErrorFormat("[Concierge] broker update to {0} failed with status {1}", bs.Uri, we.Status); 452 m_log.ErrorFormat("[Concierge] broker update to {0} failed with status {1}", bs.Uri, we.Status);
457 if (null != we.Response) 453 if (null != we.Response)
458 { 454 {
459 using (HttpWebResponse resp = we.Response as HttpWebResponse) 455 using (HttpWebResponse resp = we.Response as HttpWebResponse)
460 { 456 {
461 m_log.ErrorFormat("[Concierge] response from {0} status code: {1}", bs.Uri, resp.StatusCode); 457 m_log.ErrorFormat("[Concierge] response from {0} status code: {1}", bs.Uri, resp.StatusCode);
462 m_log.ErrorFormat("[Concierge] response from {0} status desc: {1}", bs.Uri, resp.StatusDescription); 458 m_log.ErrorFormat("[Concierge] response from {0} status desc: {1}", bs.Uri, resp.StatusDescription);
463 m_log.ErrorFormat("[Concierge] response from {0} server: {1}", bs.Uri, resp.Server); 459 m_log.ErrorFormat("[Concierge] response from {0} server: {1}", bs.Uri, resp.Server);
464 460
465 if (resp.ContentLength > 0) 461 if (resp.ContentLength > 0)
466 { 462 {
467 StreamReader content = new StreamReader(resp.GetResponseStream()); 463 using(StreamReader content = new StreamReader(resp.GetResponseStream()))
468 m_log.ErrorFormat("[Concierge] response from {0} content: {1}", bs.Uri, content.ReadToEnd()); 464 m_log.ErrorFormat("[Concierge] response from {0} content: {1}", bs.Uri, content.ReadToEnd());
469 content.Close();
470 } 465 }
471 } 466 }
472 } 467 }
@@ -480,12 +475,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
480 // welcome file there: if yes, send it to the agent 475 // welcome file there: if yes, send it to the agent
481 if (!String.IsNullOrEmpty(m_welcomes)) 476 if (!String.IsNullOrEmpty(m_welcomes))
482 { 477 {
483 string[] welcomes = new string[] { 478 string[] welcomes = new string[] {
484 Path.Combine(m_welcomes, agent.Scene.RegionInfo.RegionName), 479 Path.Combine(m_welcomes, agent.Scene.RegionInfo.RegionName),
485 Path.Combine(m_welcomes, "DEFAULT")}; 480 Path.Combine(m_welcomes, "DEFAULT")};
486 foreach (string welcome in welcomes) 481 foreach (string welcome in welcomes)
487 { 482 {
488 if (File.Exists(welcome)) 483 if (File.Exists(welcome))
489 { 484 {
490 try 485 try
491 { 486 {
@@ -504,7 +499,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
504 { 499 {
505 m_log.ErrorFormat("[Concierge]: welcome file {0} is malformed: {1}", welcome, fe); 500 m_log.ErrorFormat("[Concierge]: welcome file {0} is malformed: {1}", welcome, fe);
506 } 501 }
507 } 502 }
508 return; 503 return;
509 } 504 }
510 m_log.DebugFormat("[Concierge]: no welcome message for region {0}", scene.RegionInfo.RegionName); 505 m_log.DebugFormat("[Concierge]: no welcome message for region {0}", scene.RegionInfo.RegionName);
@@ -516,7 +511,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
516 // protected void AnnounceToAgentsRegion(Scene scene, string msg) 511 // protected void AnnounceToAgentsRegion(Scene scene, string msg)
517 // { 512 // {
518 // ScenePresence agent = null; 513 // ScenePresence agent = null;
519 // if ((client.Scene is Scene) && (client.Scene as Scene).TryGetScenePresence(client.AgentId, out agent)) 514 // if ((client.Scene is Scene) && (client.Scene as Scene).TryGetScenePresence(client.AgentId, out agent))
520 // AnnounceToAgentsRegion(agent, msg); 515 // AnnounceToAgentsRegion(agent, msg);
521 // else 516 // else
522 // m_log.DebugFormat("[Concierge]: could not find an agent for client {0}", client.Name); 517 // m_log.DebugFormat("[Concierge]: could not find an agent for client {0}", client.Name);
@@ -591,7 +586,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Concierge
591 586
592 string regionName = (string)requestData["region"]; 587 string regionName = (string)requestData["region"];
593 IScene scene = m_scenes.Find(delegate(IScene s) { return s.RegionInfo.RegionName == regionName; }); 588 IScene scene = m_scenes.Find(delegate(IScene s) { return s.RegionInfo.RegionName == regionName; });
594 if (scene == null) 589 if (scene == null)
595 throw new Exception(String.Format("unknown region \"{0}\"", regionName)); 590 throw new Exception(String.Format("unknown region \"{0}\"", regionName));
596 591
597 if (!m_conciergedScenes.Contains(scene)) 592 if (!m_conciergedScenes.Contains(scene))
diff --git a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
index 4e84364..31fc56a 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Friends/FriendsCommandsModule.cs
@@ -61,31 +61,31 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends
61 private IPresenceService m_presenceService; 61 private IPresenceService m_presenceService;
62 62
63// private IAvatarFactoryModule m_avatarFactory; 63// private IAvatarFactoryModule m_avatarFactory;
64 64
65 public string Name { get { return "Appearance Information Module"; } } 65 public string Name { get { return "Appearance Information Module"; } }
66 66
67 public Type ReplaceableInterface { get { return null; } } 67 public Type ReplaceableInterface { get { return null; } }
68 68
69 public void Initialise(IConfigSource source) 69 public void Initialise(IConfigSource source)
70 { 70 {
71// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: INITIALIZED MODULE"); 71// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: INITIALIZED MODULE");
72 } 72 }
73 73
74 public void PostInitialise() 74 public void PostInitialise()
75 { 75 {
76// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: POST INITIALIZED MODULE"); 76// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: POST INITIALIZED MODULE");
77 } 77 }
78 78
79 public void Close() 79 public void Close()
80 { 80 {
81// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: CLOSED MODULE"); 81// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: CLOSED MODULE");
82 } 82 }
83 83
84 public void AddRegion(Scene scene) 84 public void AddRegion(Scene scene)
85 { 85 {
86// m_log.DebugFormat("[FRIENDS COMMANDO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); 86// m_log.DebugFormat("[FRIENDS COMMANDO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
87 } 87 }
88 88
89 public void RemoveRegion(Scene scene) 89 public void RemoveRegion(Scene scene)
90 { 90 {
91// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); 91// m_log.DebugFormat("[FRIENDS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
@@ -107,7 +107,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends
107 m_scene.AddCommand( 107 m_scene.AddCommand(
108 "Friends", this, "friends show", 108 "Friends", this, "friends show",
109 "friends show [--cache] <first-name> <last-name>", 109 "friends show [--cache] <first-name> <last-name>",
110 "Show the friends for the given user if they exist.\n", 110 "Show the friends for the given user if they exist.",
111 "The --cache option will show locally cached information for that user.", 111 "The --cache option will show locally cached information for that user.",
112 HandleFriendsShowCommand); 112 HandleFriendsShowCommand);
113 } 113 }
@@ -197,4 +197,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.Friends
197 } 197 }
198 } 198 }
199 } 199 }
200} \ No newline at end of file 200}
diff --git a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs
index 5a6b284..1b5ee04 100644
--- a/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/SitStand/SitStandCommandsModule.cs
@@ -54,34 +54,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.SitStand
54 private Scene m_scene; 54 private Scene m_scene;
55 55
56 public string Name { get { return "SitStand Command Module"; } } 56 public string Name { get { return "SitStand Command Module"; } }
57 57
58 public Type ReplaceableInterface { get { return null; } } 58 public Type ReplaceableInterface { get { return null; } }
59 59
60 public void Initialise(IConfigSource source) 60 public void Initialise(IConfigSource source)
61 { 61 {
62// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE"); 62// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: INITIALIZED MODULE");
63 } 63 }
64 64
65 public void PostInitialise() 65 public void PostInitialise()
66 { 66 {
67// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE"); 67// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: POST INITIALIZED MODULE");
68 } 68 }
69 69
70 public void Close() 70 public void Close()
71 { 71 {
72// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE"); 72// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: CLOSED MODULE");
73 } 73 }
74 74
75 public void AddRegion(Scene scene) 75 public void AddRegion(Scene scene)
76 { 76 {
77// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); 77// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
78 } 78 }
79 79
80 public void RemoveRegion(Scene scene) 80 public void RemoveRegion(Scene scene)
81 { 81 {
82// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); 82// m_log.DebugFormat("[ATTACHMENTS COMMAND MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
83 } 83 }
84 84
85 public void RegionLoaded(Scene scene) 85 public void RegionLoaded(Scene scene)
86 { 86 {
87// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); 87// m_log.DebugFormat("[ANIMATIONS COMMAND MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
@@ -143,7 +143,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.SitStand
143 if (sitPart != null) 143 if (sitPart != null)
144 { 144 {
145 MainConsole.Instance.OutputFormat( 145 MainConsole.Instance.OutputFormat(
146 "Sitting {0} on {1} {2} in {3}", 146 "Sitting {0} on {1} {2} in {3}",
147 sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name); 147 sp.Name, sitPart.ParentGroup.Name, sitPart.ParentGroup.UUID, m_scene.Name);
148 148
149 sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero); 149 sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, sitPart.UUID, Vector3.Zero);
@@ -202,14 +202,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.SitStand
202 202
203 foreach (ScenePresence sp in scenePresences) 203 foreach (ScenePresence sp in scenePresences)
204 { 204 {
205 if (!sp.IsChildAgent && nameRegex.IsMatch(sp.Name)) 205 if (!sp.IsChildAgent && nameRegex.IsMatch(sp.Name))
206 scenePresencesMatched.Add(sp); 206 scenePresencesMatched.Add(sp);
207 } 207 }
208 } 208 }
209 else 209 else
210 { 210 {
211 ScenePresence sp = m_scene.GetScenePresence(firstName, lastName); 211 ScenePresence sp = m_scene.GetScenePresence(firstName, lastName);
212 212
213 if (sp != null && !sp.IsChildAgent) 213 if (sp != null && !sp.IsChildAgent)
214 scenePresencesMatched.Add(sp); 214 scenePresencesMatched.Add(sp);
215 } 215 }
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
index 45af212..c6d7fe6 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs
@@ -143,7 +143,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
143 if (String.IsNullOrEmpty(m_freeSwitchRealm) || 143 if (String.IsNullOrEmpty(m_freeSwitchRealm) ||
144 String.IsNullOrEmpty(m_freeSwitchAPIPrefix)) 144 String.IsNullOrEmpty(m_freeSwitchAPIPrefix))
145 { 145 {
146 m_log.Error("[FreeSwitchVoice]: Freeswitch service mis-configured. Not starting."); 146 m_log.Error("[FreeSwitchVoice]: Freeswitch service mis-configured. Not starting.");
147 return; 147 return;
148 } 148 }
149 149
@@ -168,9 +168,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
168 168
169 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), 169 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix),
170 FreeSwitchSLVoiceBuddyHTTPHandler); 170 FreeSwitchSLVoiceBuddyHTTPHandler);
171 171
172 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_watcher.php", m_freeSwitchAPIPrefix), 172 MainServer.Instance.AddHTTPHandler(String.Format("{0}/viv_watcher.php", m_freeSwitchAPIPrefix),
173 FreeSwitchSLVoiceWatcherHTTPHandler); 173 FreeSwitchSLVoiceWatcherHTTPHandler);
174 174
175 m_log.InfoFormat("[FreeSwitchVoice]: using FreeSwitch server {0}", m_freeSwitchRealm); 175 m_log.InfoFormat("[FreeSwitchVoice]: using FreeSwitch server {0}", m_freeSwitchRealm);
176 176
@@ -302,7 +302,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
302 public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps) 302 public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps)
303 { 303 {
304 m_log.DebugFormat( 304 m_log.DebugFormat(
305 "[FreeSwitchVoice]: OnRegisterCaps() called with agentID {0} caps {1} in scene {2}", 305 "[FreeSwitchVoice]: OnRegisterCaps() called with agentID {0} caps {1} in scene {2}",
306 agentID, caps, scene.RegionInfo.RegionName); 306 agentID, caps, scene.RegionInfo.RegionName);
307 307
308 string capsBase = "/CAPS/" + caps.CapsObjectPath; 308 string capsBase = "/CAPS/" + caps.CapsObjectPath;
@@ -352,7 +352,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
352 { 352 {
353 m_log.DebugFormat( 353 m_log.DebugFormat(
354 "[FreeSwitchVoice][PROVISIONVOICE]: ProvisionVoiceAccountRequest() request: {0}, path: {1}, param: {2}", request, path, param); 354 "[FreeSwitchVoice][PROVISIONVOICE]: ProvisionVoiceAccountRequest() request: {0}, path: {1}, param: {2}", request, path, param);
355 355
356 ScenePresence avatar = scene.GetScenePresence(agentID); 356 ScenePresence avatar = scene.GetScenePresence(agentID);
357 if (avatar == null) 357 if (avatar == null)
358 { 358 {
@@ -423,9 +423,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
423 UUID agentID, Caps caps) 423 UUID agentID, Caps caps)
424 { 424 {
425 m_log.DebugFormat( 425 m_log.DebugFormat(
426 "[FreeSwitchVoice][PARCELVOICE]: ParcelVoiceInfoRequest() on {0} for {1}", 426 "[FreeSwitchVoice][PARCELVOICE]: ParcelVoiceInfoRequest() on {0} for {1}",
427 scene.RegionInfo.RegionName, agentID); 427 scene.RegionInfo.RegionName, agentID);
428 428
429 ScenePresence avatar = scene.GetScenePresence(agentID); 429 ScenePresence avatar = scene.GetScenePresence(agentID);
430 string avatarName = avatar.Name; 430 string avatarName = avatar.Name;
431 431
@@ -512,7 +512,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
512 512
513 m_log.DebugFormat("[FreeSwitchVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", 513 m_log.DebugFormat("[FreeSwitchVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}",
514 avatarName, request, path, param); 514 avatarName, request, path, param);
515 515
516 return "<llsd>true</llsd>"; 516 return "<llsd>true</llsd>";
517 } 517 }
518 518
@@ -575,7 +575,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
575 575
576 public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) 576 public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request)
577 { 577 {
578 m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceGetPreloginHTTPHandler called"); 578// m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceGetPreloginHTTPHandler called");
579 579
580 Hashtable response = new Hashtable(); 580 Hashtable response = new Hashtable();
581 response["content_type"] = "text/xml"; 581 response["content_type"] = "text/xml";
@@ -610,7 +610,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
610 public Hashtable FreeSwitchSLVoiceBuddyHTTPHandler(Hashtable request) 610 public Hashtable FreeSwitchSLVoiceBuddyHTTPHandler(Hashtable request)
611 { 611 {
612 m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceBuddyHTTPHandler called"); 612 m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceBuddyHTTPHandler called");
613 613
614 Hashtable response = new Hashtable(); 614 Hashtable response = new Hashtable();
615 response["int_response_code"] = 200; 615 response["int_response_code"] = 200;
616 response["str_response_string"] = string.Empty; 616 response["str_response_string"] = string.Empty;
@@ -678,16 +678,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
678// Regex normalizeEndLines = new Regex(@"(\r\n|\n)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); 678// Regex normalizeEndLines = new Regex(@"(\r\n|\n)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
679// 679//
680// m_log.DebugFormat( 680// m_log.DebugFormat(
681// "[FREESWITCH]: FreeSwitchSLVoiceBuddyHTTPHandler() response {0}", 681// "[FREESWITCH]: FreeSwitchSLVoiceBuddyHTTPHandler() response {0}",
682// normalizeEndLines.Replace((string)response["str_response_string"],"")); 682// normalizeEndLines.Replace((string)response["str_response_string"],""));
683 683
684 return response; 684 return response;
685 } 685 }
686 686
687 public Hashtable FreeSwitchSLVoiceWatcherHTTPHandler(Hashtable request) 687 public Hashtable FreeSwitchSLVoiceWatcherHTTPHandler(Hashtable request)
688 { 688 {
689 m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceWatcherHTTPHandler called"); 689 m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceWatcherHTTPHandler called");
690 690
691 Hashtable response = new Hashtable(); 691 Hashtable response = new Hashtable();
692 response["int_response_code"] = 200; 692 response["int_response_code"] = 200;
693 response["content-type"] = "text/xml"; 693 response["content-type"] = "text/xml";
@@ -700,8 +700,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
700 700
701 StringBuilder resp = new StringBuilder(); 701 StringBuilder resp = new StringBuilder();
702 resp.Append("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?><response xmlns=\"http://www.vivox.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation= \"/xsd/buddy_list.xsd\">"); 702 resp.Append("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?><response xmlns=\"http://www.vivox.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation= \"/xsd/buddy_list.xsd\">");
703 703
704 // FIXME: This is enough of a response to stop viewer 2 complaining about a login failure and get voice to work. If we don't 704 // FIXME: This is enough of a response to stop viewer 2 complaining about a login failure and get voice to work. If we don't
705 // give an OK response, then viewer 2 engages in an continuous viv_signin.php, viv_buddy.php, viv_watcher.php loop 705 // give an OK response, then viewer 2 engages in an continuous viv_signin.php, viv_buddy.php, viv_watcher.php loop
706 // Viewer 1 appeared happy to ignore the lack of reply and still works with this reply. 706 // Viewer 1 appeared happy to ignore the lack of reply and still works with this reply.
707 // 707 //
@@ -711,22 +711,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
711 <cookie_name>lib_session</cookie_name> 711 <cookie_name>lib_session</cookie_name>
712 <cookie>{0}</cookie> 712 <cookie>{0}</cookie>
713 <auth_token>{0}</auth_token> 713 <auth_token>{0}</auth_token>
714 <body/></level0></response>", auth_token)); 714 <body/></level0></response>", auth_token));
715 715
716 response["str_response_string"] = resp.ToString(); 716 response["str_response_string"] = resp.ToString();
717 717
718// Regex normalizeEndLines = new Regex(@"(\r\n|\n)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); 718// Regex normalizeEndLines = new Regex(@"(\r\n|\n)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
719// 719//
720// m_log.DebugFormat( 720// m_log.DebugFormat(
721// "[FREESWITCH]: FreeSwitchSLVoiceWatcherHTTPHandler() response {0}", 721// "[FREESWITCH]: FreeSwitchSLVoiceWatcherHTTPHandler() response {0}",
722// normalizeEndLines.Replace((string)response["str_response_string"],"")); 722// normalizeEndLines.Replace((string)response["str_response_string"],""));
723 723
724 return response; 724 return response;
725 } 725 }
726 726
727 public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) 727 public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request)
728 { 728 {
729 m_log.Debug("[FreeSwitchVoice]: FreeSwitchSLVoiceSigninHTTPHandler called"); 729 //m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called");
730// string requestbody = (string)request["body"]; 730// string requestbody = (string)request["body"];
731// string uri = (string)request["uri"]; 731// string uri = (string)request["uri"];
732// string contenttype = (string)request["content-type"]; 732// string contenttype = (string)request["content-type"];
@@ -771,10 +771,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
771 </level0> 771 </level0>
772 </response>", userid, pos, avatarName); 772 </response>", userid, pos, avatarName);
773 773
774 response["int_response_code"] = 200; 774 response["int_response_code"] = 200;
775 775
776// m_log.DebugFormat("[FreeSwitchVoice]: Sending FreeSwitchSLVoiceSigninHTTPHandler response"); 776// m_log.DebugFormat("[FreeSwitchVoice]: Sending FreeSwitchSLVoiceSigninHTTPHandler response");
777 777
778 return response; 778 return response;
779 } 779 }
780 780
@@ -859,23 +859,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice
859 response["keepalive"] = false; 859 response["keepalive"] = false;
860 response["int_response_code"] = 500; 860 response["int_response_code"] = 500;
861 861
862 Hashtable requestBody = ParseRequestBody((string)request["body"]); 862 Hashtable requestBody = ParseRequestBody((string)request["body"]);
863 863
864 string section = (string) requestBody["section"]; 864 string section = (string) requestBody["section"];
865 865
866 if (section == "directory") 866 if (section == "directory")
867 { 867 {
868 string eventCallingFunction = (string)requestBody["Event-Calling-Function"]; 868 string eventCallingFunction = (string)requestBody["Event-Calling-Function"];
869 m_log.DebugFormat( 869 m_log.DebugFormat(
870 "[FreeSwitchVoice]: Received request for config section directory, event calling function '{0}'", 870 "[FreeSwitchVoice]: Received request for config section directory, event calling function '{0}'",
871 eventCallingFunction); 871 eventCallingFunction);
872 872
873 response = m_FreeswitchService.HandleDirectoryRequest(requestBody); 873 response = m_FreeswitchService.HandleDirectoryRequest(requestBody);
874 } 874 }
875 else if (section == "dialplan") 875 else if (section == "dialplan")
876 { 876 {
877 m_log.DebugFormat("[FreeSwitchVoice]: Received request for config section dialplan"); 877 m_log.DebugFormat("[FreeSwitchVoice]: Received request for config section dialplan");
878 878
879 response = m_FreeswitchService.HandleDialplanRequest(requestBody); 879 response = m_FreeswitchService.HandleDialplanRequest(requestBody);
880 } 880 }
881 else 881 else
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
index dd44564..defaa9c 100644
--- a/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/Voice/VivoxVoice/VivoxVoiceModule.cs
@@ -114,13 +114,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
114 114
115 private static Dictionary<string,string> m_parents = new Dictionary<string,string>(); 115 private static Dictionary<string,string> m_parents = new Dictionary<string,string>();
116 private static bool m_dumpXml; 116 private static bool m_dumpXml;
117 117
118 private IConfig m_config; 118 private IConfig m_config;
119 119
120 private object m_Lock; 120 private object m_Lock;
121 121
122 public void Initialise(IConfigSource config) 122 public void Initialise(IConfigSource config)
123 { 123 {
124 MainConsole.Instance.Commands.AddCommand("vivox", false, "vivox debug", "vivox debug <on>|<off>", "Set vivox debugging", HandleDebug);
124 125
125 m_config = config.Configs["VivoxVoice"]; 126 m_config = config.Configs["VivoxVoice"];
126 127
@@ -152,22 +153,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
152 // Validate against constraints and default if necessary 153 // Validate against constraints and default if necessary
153 if (m_vivoxChannelRollOff < CHAN_ROLL_OFF_MIN || m_vivoxChannelRollOff > CHAN_ROLL_OFF_MAX) 154 if (m_vivoxChannelRollOff < CHAN_ROLL_OFF_MIN || m_vivoxChannelRollOff > CHAN_ROLL_OFF_MAX)
154 { 155 {
155 m_log.WarnFormat("[VivoxVoice] Invalid value for roll off ({0}), reset to {1}.", 156 m_log.WarnFormat("[VivoxVoice] Invalid value for roll off ({0}), reset to {1}.",
156 m_vivoxChannelRollOff, CHAN_ROLL_OFF_DEFAULT); 157 m_vivoxChannelRollOff, CHAN_ROLL_OFF_DEFAULT);
157 m_vivoxChannelRollOff = CHAN_ROLL_OFF_DEFAULT; 158 m_vivoxChannelRollOff = CHAN_ROLL_OFF_DEFAULT;
158 } 159 }
159 160
160 if (m_vivoxChannelMaximumRange < CHAN_MAX_RANGE_MIN || m_vivoxChannelMaximumRange > CHAN_MAX_RANGE_MAX) 161 if (m_vivoxChannelMaximumRange < CHAN_MAX_RANGE_MIN || m_vivoxChannelMaximumRange > CHAN_MAX_RANGE_MAX)
161 { 162 {
162 m_log.WarnFormat("[VivoxVoice] Invalid value for maximum range ({0}), reset to {1}.", 163 m_log.WarnFormat("[VivoxVoice] Invalid value for maximum range ({0}), reset to {1}.",
163 m_vivoxChannelMaximumRange, CHAN_MAX_RANGE_DEFAULT); 164 m_vivoxChannelMaximumRange, CHAN_MAX_RANGE_DEFAULT);
164 m_vivoxChannelMaximumRange = CHAN_MAX_RANGE_DEFAULT; 165 m_vivoxChannelMaximumRange = CHAN_MAX_RANGE_DEFAULT;
165 } 166 }
166 167
167 if (m_vivoxChannelClampingDistance < CHAN_CLAMPING_DISTANCE_MIN || 168 if (m_vivoxChannelClampingDistance < CHAN_CLAMPING_DISTANCE_MIN ||
168 m_vivoxChannelClampingDistance > CHAN_CLAMPING_DISTANCE_MAX) 169 m_vivoxChannelClampingDistance > CHAN_CLAMPING_DISTANCE_MAX)
169 { 170 {
170 m_log.WarnFormat("[VivoxVoice] Invalid value for clamping distance ({0}), reset to {1}.", 171 m_log.WarnFormat("[VivoxVoice] Invalid value for clamping distance ({0}), reset to {1}.",
171 m_vivoxChannelClampingDistance, CHAN_CLAMPING_DISTANCE_DEFAULT); 172 m_vivoxChannelClampingDistance, CHAN_CLAMPING_DISTANCE_DEFAULT);
172 m_vivoxChannelClampingDistance = CHAN_CLAMPING_DISTANCE_DEFAULT; 173 m_vivoxChannelClampingDistance = CHAN_CLAMPING_DISTANCE_DEFAULT;
173 } 174 }
@@ -179,7 +180,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
179 case "presentation" : break; 180 case "presentation" : break;
180 case "auditorium" : break; 181 case "auditorium" : break;
181 default : 182 default :
182 m_log.WarnFormat("[VivoxVoice] Invalid value for channel mode ({0}), reset to {1}.", 183 m_log.WarnFormat("[VivoxVoice] Invalid value for channel mode ({0}), reset to {1}.",
183 m_vivoxChannelMode, CHAN_MODE_DEFAULT); 184 m_vivoxChannelMode, CHAN_MODE_DEFAULT);
184 m_vivoxChannelMode = CHAN_MODE_DEFAULT; 185 m_vivoxChannelMode = CHAN_MODE_DEFAULT;
185 break; 186 break;
@@ -190,7 +191,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
190 case "positional" : break; 191 case "positional" : break;
191 case "channel" : break; 192 case "channel" : break;
192 default : 193 default :
193 m_log.WarnFormat("[VivoxVoice] Invalid value for channel type ({0}), reset to {1}.", 194 m_log.WarnFormat("[VivoxVoice] Invalid value for channel type ({0}), reset to {1}.",
194 m_vivoxChannelType, CHAN_TYPE_DEFAULT); 195 m_vivoxChannelType, CHAN_TYPE_DEFAULT);
195 m_vivoxChannelType = CHAN_TYPE_DEFAULT; 196 m_vivoxChannelType = CHAN_TYPE_DEFAULT;
196 break; 197 break;
@@ -229,7 +230,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
229 230
230 public void AddRegion(Scene scene) 231 public void AddRegion(Scene scene)
231 { 232 {
232 if (m_pluginEnabled) 233 if (m_pluginEnabled)
233 { 234 {
234 lock (vlock) 235 lock (vlock)
235 { 236 {
@@ -237,13 +238,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
237 238
238 string sceneUUID = scene.RegionInfo.RegionID.ToString(); 239 string sceneUUID = scene.RegionInfo.RegionID.ToString();
239 string sceneName = scene.RegionInfo.RegionName; 240 string sceneName = scene.RegionInfo.RegionName;
240 241
241 // Make sure that all local channels are deleted. 242 // Make sure that all local channels are deleted.
242 // So we have to search for the children, and then do an 243 // So we have to search for the children, and then do an
243 // iteration over the set of chidren identified. 244 // iteration over the set of chidren identified.
244 // This assumes that there is just one directory per 245 // This assumes that there is just one directory per
245 // region. 246 // region.
246 247
247 if (VivoxTryGetDirectory(sceneUUID + "D", out channelId)) 248 if (VivoxTryGetDirectory(sceneUUID + "D", out channelId))
248 { 249 {
249 m_log.DebugFormat("[VivoxVoice]: region {0}: uuid {1}: located directory id {2}", 250 m_log.DebugFormat("[VivoxVoice]: region {0}: uuid {1}: located directory id {2}",
@@ -262,7 +263,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
262 { 263 {
263 if (!IsOK(VivoxDeleteChannel(channelId, id))) 264 if (!IsOK(VivoxDeleteChannel(channelId, id)))
264 m_log.WarnFormat("[VivoxVoice] Channel delete failed {0}:{1}:{2}", i, channelId, id); 265 m_log.WarnFormat("[VivoxVoice] Channel delete failed {0}:{1}:{2}", i, channelId, id);
265 } 266 }
266 } 267 }
267 } 268 }
268 } 269 }
@@ -310,7 +311,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
310 311
311 public void RemoveRegion(Scene scene) 312 public void RemoveRegion(Scene scene)
312 { 313 {
313 if (m_pluginEnabled) 314 if (m_pluginEnabled)
314 { 315 {
315 lock (vlock) 316 lock (vlock)
316 { 317 {
@@ -318,7 +319,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
318 319
319 string sceneUUID = scene.RegionInfo.RegionID.ToString(); 320 string sceneUUID = scene.RegionInfo.RegionID.ToString();
320 string sceneName = scene.RegionInfo.RegionName; 321 string sceneName = scene.RegionInfo.RegionName;
321 322
322 // Make sure that all local channels are deleted. 323 // Make sure that all local channels are deleted.
323 // So we have to search for the children, and then do an 324 // So we have to search for the children, and then do an
324 // iteration over the set of chidren identified. 325 // iteration over the set of chidren identified.
@@ -342,7 +343,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
342 { 343 {
343 if (!IsOK(VivoxDeleteChannel(channelId, id))) 344 if (!IsOK(VivoxDeleteChannel(channelId, id)))
344 m_log.WarnFormat("[VivoxVoice] Channel delete failed {0}:{1}:{2}", i, channelId, id); 345 m_log.WarnFormat("[VivoxVoice] Channel delete failed {0}:{1}:{2}", i, channelId, id);
345 } 346 }
346 } 347 }
347 } 348 }
348 } 349 }
@@ -352,7 +353,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
352 353
353 // Remove the channel umbrella entry 354 // Remove the channel umbrella entry
354 355
355 lock (m_parents) 356 lock (m_parents)
356 { 357 {
357 if (m_parents.ContainsKey(sceneUUID)) 358 if (m_parents.ContainsKey(sceneUUID))
358 { 359 {
@@ -374,7 +375,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
374 VivoxLogout(); 375 VivoxLogout();
375 } 376 }
376 377
377 public Type ReplaceableInterface 378 public Type ReplaceableInterface
378 { 379 {
379 get { return null; } 380 get { return null; }
380 } 381 }
@@ -395,11 +396,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
395 // (login, region crossing). We contribute two capabilities to 396 // (login, region crossing). We contribute two capabilities to
396 // the set of capabilities handed back to the client: 397 // the set of capabilities handed back to the client:
397 // ProvisionVoiceAccountRequest and ParcelVoiceInfoRequest. 398 // ProvisionVoiceAccountRequest and ParcelVoiceInfoRequest.
398 // 399 //
399 // ProvisionVoiceAccountRequest allows the client to obtain 400 // ProvisionVoiceAccountRequest allows the client to obtain
400 // the voice account credentials for the avatar it is 401 // the voice account credentials for the avatar it is
401 // controlling (e.g., user name, password, etc). 402 // controlling (e.g., user name, password, etc).
402 // 403 //
403 // ParcelVoiceInfoRequest is invoked whenever the client 404 // ParcelVoiceInfoRequest is invoked whenever the client
404 // changes from one region or parcel to another. 405 // changes from one region or parcel to another.
405 // 406 //
@@ -475,8 +476,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
475 avatarName = avatar.Name; 476 avatarName = avatar.Name;
476 477
477 m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene, agentID); 478 m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: scene = {0}, agentID = {1}", scene, agentID);
478 m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", 479// m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}",
479 request, path, param); 480// request, path, param);
480 481
481 XmlElement resp; 482 XmlElement resp;
482 bool retry = false; 483 bool retry = false;
@@ -492,9 +493,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
492 493
493 if (XmlFind(resp, "response.level0.status", out code)) 494 if (XmlFind(resp, "response.level0.status", out code))
494 { 495 {
495 if (code != "OK") 496 if (code != "OK")
496 { 497 {
497 if (XmlFind(resp, "response.level0.body.code", out code)) 498 if (XmlFind(resp, "response.level0.body.code", out code))
498 { 499 {
499 // If the request was recognized, then this should be set to something 500 // If the request was recognized, then this should be set to something
500 switch (code) 501 switch (code)
@@ -529,27 +530,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
529 switch (code) 530 switch (code)
530 { 531 {
531 case "201" : // Account expired 532 case "201" : // Account expired
532 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : expired credentials", 533 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : expired credentials",
533 avatarName); 534 avatarName);
534 m_adminConnected = false; 535 m_adminConnected = false;
535 retry = DoAdminLogin(); 536 retry = DoAdminLogin();
536 break; 537 break;
537 538
538 case "202" : // Missing credentials 539 case "202" : // Missing credentials
539 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : missing credentials", 540 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : missing credentials",
540 avatarName); 541 avatarName);
541 break; 542 break;
542 543
543 case "212" : // Not authorized 544 case "212" : // Not authorized
544 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : not authorized", 545 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : not authorized",
545 avatarName); 546 avatarName);
546 break; 547 break;
547 548
548 case "300" : // Required parameter missing 549 case "300" : // Required parameter missing
549 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : parameter missing", 550 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : parameter missing",
550 avatarName); 551 avatarName);
551 break; 552 break;
552 553
553 case "400" : // Create failed 554 case "400" : // Create failed
554 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : create failed", 555 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Create account information failed : create failed",
555 avatarName); 556 avatarName);
@@ -557,7 +558,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
557 } 558 }
558 } 559 }
559 break; 560 break;
560 561
561 case "404" : // Failed to retrieve account 562 case "404" : // Failed to retrieve account
562 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : retrieve failed"); 563 m_log.ErrorFormat("[VivoxVoice]: avatar \"{0}\": Get account information failed : retrieve failed");
563 // [AMW] Sleep and retry for a fixed period? Or just abandon? 564 // [AMW] Sleep and retry for a fixed period? Or just abandon?
@@ -574,7 +575,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
574 m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: Get Account Request failed for \"{0}\"", avatarName); 575 m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: Get Account Request failed for \"{0}\"", avatarName);
575 throw new Exception("Unable to execute request"); 576 throw new Exception("Unable to execute request");
576 } 577 }
577 578
578 // Unconditionally change the password on each request 579 // Unconditionally change the password on each request
579 VivoxPassword(agentname, password); 580 VivoxPassword(agentname, password);
580 581
@@ -583,7 +584,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
583 584
584 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); 585 string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse);
585 586
586 m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r); 587// m_log.DebugFormat("[VivoxVoice][PROVISIONVOICE]: avatar \"{0}\": {1}", avatarName, r);
587 588
588 return r; 589 return r;
589 } 590 }
@@ -612,7 +613,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
612 string avatarName = avatar.Name; 613 string avatarName = avatar.Name;
613 614
614 // - check whether we have a region channel in our cache 615 // - check whether we have a region channel in our cache
615 // - if not: 616 // - if not:
616 // create it and cache it 617 // create it and cache it
617 // - send it to the client 618 // - send it to the client
618 // - send channel_uri: as "sip:regionID@m_sipDomain" 619 // - send channel_uri: as "sip:regionID@m_sipDomain"
@@ -621,7 +622,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
621 LLSDParcelVoiceInfoResponse parcelVoiceInfo; 622 LLSDParcelVoiceInfoResponse parcelVoiceInfo;
622 string channel_uri; 623 string channel_uri;
623 624
624 if (null == scene.LandChannel) 625 if (null == scene.LandChannel)
625 throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available", 626 throw new Exception(String.Format("region \"{0}\": avatar \"{1}\": land data not yet available",
626 scene.RegionInfo.RegionName, avatarName)); 627 scene.RegionInfo.RegionName, avatarName));
627 628
@@ -630,24 +631,28 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
630 // voice, if all do retrieve or obtain the parcel 631 // voice, if all do retrieve or obtain the parcel
631 // voice channel 632 // voice channel
632 LandData land = scene.GetLandData(avatar.AbsolutePosition); 633 LandData land = scene.GetLandData(avatar.AbsolutePosition);
634 if (land == null)
635 {
636 return "<llsd><undef /></llsd>";
637 }
633 638
634 m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}", 639// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": request: {4}, path: {5}, param: {6}",
635 scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param); 640// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, request, path, param);
636 // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}", 641 // m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: avatar \"{0}\": location: {1} {2} {3}",
637 // avatarName, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); 642 // avatarName, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z);
638 643
639 // TODO: EstateSettings don't seem to get propagated... 644 // TODO: EstateSettings don't seem to get propagated...
640 if (!scene.RegionInfo.EstateSettings.AllowVoice) 645 if (!scene.RegionInfo.EstateSettings.AllowVoice)
641 { 646 {
642 m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings", 647 //m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": voice not enabled in estate settings",
643 scene.RegionInfo.RegionName); 648 // scene.RegionInfo.RegionName);
644 channel_uri = String.Empty; 649 channel_uri = String.Empty;
645 } 650 }
646 651
647 if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0) 652 if ((land.Flags & (uint)ParcelFlags.AllowVoiceChat) == 0)
648 { 653 {
649 m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel", 654 //m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": voice not enabled for parcel",
650 scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName); 655 // scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName);
651 channel_uri = String.Empty; 656 channel_uri = String.Empty;
652 } 657 }
653 else 658 else
@@ -662,15 +667,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
662 parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds); 667 parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
663 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); 668 string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
664 669
665 m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}", 670// m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": Parcel \"{1}\" ({2}): avatar \"{3}\": {4}",
666 scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r); 671// scene.RegionInfo.RegionName, land.Name, land.LocalID, avatarName, r);
667 return r; 672 return r;
668 } 673 }
669 catch (Exception e) 674 catch (Exception e)
670 { 675 {
671 m_log.ErrorFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2}, retry later", 676 m_log.ErrorFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2}, retry later",
672 scene.RegionInfo.RegionName, avatarName, e.Message); 677 scene.RegionInfo.RegionName, avatarName, e.Message);
673 m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed", 678 m_log.DebugFormat("[VivoxVoice][PARCELVOICE]: region \"{0}\": avatar \"{1}\": {2} failed",
674 scene.RegionInfo.RegionName, avatarName, e.ToString()); 679 scene.RegionInfo.RegionName, avatarName, e.ToString());
675 680
676 return "<llsd><undef /></llsd>"; 681 return "<llsd><undef /></llsd>";
@@ -690,11 +695,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
690 public string ChatSessionRequest(Scene scene, string request, string path, string param, 695 public string ChatSessionRequest(Scene scene, string request, string path, string param,
691 UUID agentID, Caps caps) 696 UUID agentID, Caps caps)
692 { 697 {
693 ScenePresence avatar = scene.GetScenePresence(agentID); 698// ScenePresence avatar = scene.GetScenePresence(agentID);
694 string avatarName = avatar.Name; 699// string avatarName = avatar.Name;
695 700
696 m_log.DebugFormat("[VivoxVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}", 701// m_log.DebugFormat("[VivoxVoice][CHATSESSION]: avatar \"{0}\": request: {1}, path: {2}, param: {3}",
697 avatarName, request, path, param); 702// avatarName, request, path, param);
698 return "<llsd>true</llsd>"; 703 return "<llsd>true</llsd>";
699 } 704 }
700 705
@@ -716,17 +721,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
716 { 721 {
717 landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name); 722 landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, land.Name);
718 landUUID = land.GlobalID.ToString(); 723 landUUID = land.GlobalID.ToString();
719 m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", 724 m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}",
720 landName, land.LocalID, landUUID); 725 landName, land.LocalID, landUUID);
721 } 726 }
722 else 727 else
723 { 728 {
724 landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, scene.RegionInfo.RegionName); 729 landName = String.Format("{0}:{1}", scene.RegionInfo.RegionName, scene.RegionInfo.RegionName);
725 landUUID = scene.RegionInfo.RegionID.ToString(); 730 landUUID = scene.RegionInfo.RegionID.ToString();
726 m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}", 731 m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parcel id {1}: using channel name {2}",
727 landName, land.LocalID, landUUID); 732 landName, land.LocalID, landUUID);
728 } 733 }
729 734
730 lock (vlock) 735 lock (vlock)
731 { 736 {
732 // Added by Adam to help debug channel not availible errors. 737 // Added by Adam to help debug channel not availible errors.
@@ -737,7 +742,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
737 else 742 else
738 throw new Exception("vivox channel uri not available"); 743 throw new Exception("vivox channel uri not available");
739 744
740 m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parent channel id {1}: retrieved parcel channel_uri {2} ", 745 m_log.DebugFormat("[VivoxVoice]: Region:Parcel \"{0}\": parent channel id {1}: retrieved parcel channel_uri {2} ",
741 landName, parentId, channelUri); 746 landName, parentId, channelUri);
742 } 747 }
743 748
@@ -767,6 +772,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
767 return VivoxCall(requrl, false); 772 return VivoxCall(requrl, false);
768 } 773 }
769 774
775
770 private static readonly string m_vivoxGetAccountPath = "http://{0}/api2/viv_get_acct.php?auth_token={1}&user_name={2}"; 776 private static readonly string m_vivoxGetAccountPath = "http://{0}/api2/viv_get_acct.php?auth_token={1}&user_name={2}";
771 777
772 /// <summary> 778 /// <summary>
@@ -779,6 +785,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
779 return VivoxCall(requrl, true); 785 return VivoxCall(requrl, true);
780 } 786 }
781 787
788
782 private static readonly string m_vivoxNewAccountPath = "http://{0}/api2/viv_adm_acct_new.php?username={1}&pwd={2}&auth_token={3}"; 789 private static readonly string m_vivoxNewAccountPath = "http://{0}/api2/viv_adm_acct_new.php?username={1}&pwd={2}&auth_token={3}";
783 790
784 /// <summary> 791 /// <summary>
@@ -793,6 +800,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
793 return VivoxCall(requrl, true); 800 return VivoxCall(requrl, true);
794 } 801 }
795 802
803
796 private static readonly string m_vivoxPasswordPath = "http://{0}/api2/viv_adm_password.php?user_name={1}&new_pwd={2}&auth_token={3}"; 804 private static readonly string m_vivoxPasswordPath = "http://{0}/api2/viv_adm_password.php?user_name={1}&new_pwd={2}&auth_token={3}";
797 805
798 /// <summary> 806 /// <summary>
@@ -804,18 +812,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
804 return VivoxCall(requrl, true); 812 return VivoxCall(requrl, true);
805 } 813 }
806 814
815
807 private static readonly string m_vivoxChannelPath = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_name={2}&auth_token={3}"; 816 private static readonly string m_vivoxChannelPath = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_name={2}&auth_token={3}";
808 817
809 /// <summary> 818 /// <summary>
810 /// Create a channel. 819 /// Create a channel.
811 /// Once again, there a multitude of options possible. In the simplest case 820 /// Once again, there a multitude of options possible. In the simplest case
812 /// we specify only the name and get a non-persistent cannel in return. Non 821 /// we specify only the name and get a non-persistent cannel in return. Non
813 /// persistent means that the channel gets deleted if no-one uses it for 822 /// persistent means that the channel gets deleted if no-one uses it for
814 /// 5 hours. To accomodate future requirements, it may be a good idea to 823 /// 5 hours. To accomodate future requirements, it may be a good idea to
815 /// initially create channels under the umbrella of a parent ID based upon 824 /// initially create channels under the umbrella of a parent ID based upon
816 /// the region name. That way we have a context for side channels, if those 825 /// the region name. That way we have a context for side channels, if those
817 /// are required in a later phase. 826 /// are required in a later phase.
818 /// 827 ///
819 /// In this case the call handles parent and description as optional values. 828 /// In this case the call handles parent and description as optional values.
820 /// </summary> 829 /// </summary>
821 private bool VivoxTryCreateChannel(string parent, string channelId, string description, out string channelUri) 830 private bool VivoxTryCreateChannel(string parent, string channelId, string description, out string channelUri)
@@ -837,7 +846,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
837 requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel); 846 requrl = String.Format("{0}&chan_dist_model={1}", requrl, m_vivoxChannelDistanceModel);
838 requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange); 847 requrl = String.Format("{0}&chan_max_range={1}", requrl, m_vivoxChannelMaximumRange);
839 requrl = String.Format("{0}&chan_clamping_distance={1}", requrl, m_vivoxChannelClampingDistance); 848 requrl = String.Format("{0}&chan_clamping_distance={1}", requrl, m_vivoxChannelClampingDistance);
840 849
841 XmlElement resp = VivoxCall(requrl, true); 850 XmlElement resp = VivoxCall(requrl, true);
842 if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri)) 851 if (XmlFind(resp, "response.level0.body.chan_uri", out channelUri))
843 return true; 852 return true;
@@ -880,7 +889,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
880 889
881 /// <summary> 890 /// <summary>
882 /// Retrieve a channel. 891 /// Retrieve a channel.
883 /// Once again, there a multitude of options possible. In the simplest case 892 /// Once again, there a multitude of options possible. In the simplest case
884 /// we specify only the name and get a non-persistent cannel in return. Non 893 /// we specify only the name and get a non-persistent cannel in return. Non
885 /// persistent means that the channel gets deleted if no-one uses it for 894 /// persistent means that the channel gets deleted if no-one uses it for
886 /// 5 hours. To accomodate future requirements, it may be a good idea to 895 /// 5 hours. To accomodate future requirements, it may be a good idea to
@@ -889,7 +898,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
889 /// are required in a later phase. 898 /// are required in a later phase.
890 /// In this case the call handles parent and description as optional values. 899 /// In this case the call handles parent and description as optional values.
891 /// </summary> 900 /// </summary>
892 private bool VivoxTryGetChannel(string channelParent, string channelName, 901 private bool VivoxTryGetChannel(string channelParent, string channelName,
893 out string channelId, out string channelUri) 902 out string channelId, out string channelUri)
894 { 903 {
895 string count; 904 string count;
@@ -997,7 +1006,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
997 string type; 1006 string type;
998 1007
999 // skip if not a directory 1008 // skip if not a directory
1000 if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.type", i, out type) || 1009 if (!XmlFind(resp, "response.level0.channel-search.channels.channels.level4.type", i, out type) ||
1001 type != "dir") 1010 type != "dir")
1002 continue; 1011 continue;
1003 1012
@@ -1019,7 +1028,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1019 return false; 1028 return false;
1020 } 1029 }
1021 1030
1022 // private static readonly string m_vivoxChannelById = "http://{0}/api2/viv_chan_mod.php?mode={1}&chan_id={2}&auth_token={3}"; 1031 // private static readonly string m_vivoxChannelById = "https://{0}/api2/viv_chan_mod.php?mode={1}&chan_id={2}&auth_token={3}";
1023 1032
1024 // private XmlElement VivoxGetChannelById(string parent, string channelid) 1033 // private XmlElement VivoxGetChannelById(string parent, string channelid)
1025 // { 1034 // {
@@ -1035,7 +1044,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1035 1044
1036 /// <summary> 1045 /// <summary>
1037 /// Delete a channel. 1046 /// Delete a channel.
1038 /// Once again, there a multitude of options possible. In the simplest case 1047 /// Once again, there a multitude of options possible. In the simplest case
1039 /// we specify only the name and get a non-persistent cannel in return. Non 1048 /// we specify only the name and get a non-persistent cannel in return. Non
1040 /// persistent means that the channel gets deleted if no-one uses it for 1049 /// persistent means that the channel gets deleted if no-one uses it for
1041 /// 5 hours. To accomodate future requirements, it may be a good idea to 1050 /// 5 hours. To accomodate future requirements, it may be a good idea to
@@ -1044,6 +1053,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1044 /// are required in a later phase. 1053 /// are required in a later phase.
1045 /// In this case the call handles parent and description as optional values. 1054 /// In this case the call handles parent and description as optional values.
1046 /// </summary> 1055 /// </summary>
1056
1047 private XmlElement VivoxDeleteChannel(string parent, string channelid) 1057 private XmlElement VivoxDeleteChannel(string parent, string channelid)
1048 { 1058 {
1049 string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken); 1059 string requrl = String.Format(m_vivoxChannelDel, m_vivoxServer, "delete", channelid, m_authToken);
@@ -1059,6 +1069,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1059 /// <summary> 1069 /// <summary>
1060 /// Return information on channels in the given directory 1070 /// Return information on channels in the given directory
1061 /// </summary> 1071 /// </summary>
1072
1062 private XmlElement VivoxListChildren(string channelid) 1073 private XmlElement VivoxListChildren(string channelid)
1063 { 1074 {
1064 string requrl = String.Format(m_vivoxChannelSearch, m_vivoxServer, channelid, m_authToken); 1075 string requrl = String.Format(m_vivoxChannelSearch, m_vivoxServer, channelid, m_authToken);
@@ -1087,7 +1098,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1087 // return VivoxGetChannelById(null, id); 1098 // return VivoxGetChannelById(null, id);
1088 // } 1099 // }
1089 // } 1100 // }
1090 // } 1101 // }
1091 // } 1102 // }
1092 // } 1103 // }
1093 1104
@@ -1095,12 +1106,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1095 // return VivoxGetChannel(null, Guid.NewGuid().ToString()); 1106 // return VivoxGetChannel(null, Guid.NewGuid().ToString());
1096 1107
1097 // } 1108 // }
1098 1109
1099 /// <summary> 1110 /// <summary>
1100 /// This method handles the WEB side of making a request over the 1111 /// This method handles the WEB side of making a request over the
1101 /// Vivox interface. The returned values are tansferred to a has 1112 /// Vivox interface. The returned values are tansferred to a has
1102 /// table which is returned as the result. 1113 /// table which is returned as the result.
1103 /// The outcome of the call can be determined by examining the 1114 /// The outcome of the call can be determined by examining the
1104 /// status value in the hash table. 1115 /// status value in the hash table.
1105 /// </summary> 1116 /// </summary>
1106 private XmlElement VivoxCall(string requrl, bool admin) 1117 private XmlElement VivoxCall(string requrl, bool admin)
@@ -1114,9 +1125,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1114 return null; 1125 return null;
1115 1126
1116 doc = new XmlDocument(); 1127 doc = new XmlDocument();
1128 doc.XmlResolver = null;
1117 1129
1118 // Let's serialize all calls to Vivox. Most of these are driven by 1130 // Let's serialize all calls to Vivox. Most of these are driven by
1119 // the clients (CAPs), when the user arrives at the region. We don't 1131 // the clients (CAPs), when the user arrives at the region. We don't
1120 // want to issue many simultaneous http requests to Vivox, because mono 1132 // want to issue many simultaneous http requests to Vivox, because mono
1121 // doesn't like that 1133 // doesn't like that
1122 lock (m_Lock) 1134 lock (m_Lock)
@@ -1124,7 +1136,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1124 try 1136 try
1125 { 1137 {
1126 // Otherwise prepare the request 1138 // Otherwise prepare the request
1127 m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl); 1139 //m_log.DebugFormat("[VivoxVoice] Sending request <{0}>", requrl);
1128 1140
1129 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl); 1141 HttpWebRequest req = (HttpWebRequest)WebRequest.Create(requrl);
1130 1142
@@ -1135,7 +1147,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1135 using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse()) 1147 using (HttpWebResponse rsp = (HttpWebResponse)req.GetResponse())
1136 using (Stream s = rsp.GetResponseStream()) 1148 using (Stream s = rsp.GetResponseStream())
1137 using (XmlTextReader rdr = new XmlTextReader(s)) 1149 using (XmlTextReader rdr = new XmlTextReader(s))
1138 doc.Load(rdr); 1150 {
1151 rdr.ProhibitDtd = true;
1152 doc.Load(rdr);
1153 }
1139 } 1154 }
1140 catch (Exception e) 1155 catch (Exception e)
1141 { 1156 {
@@ -1162,7 +1177,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1162 1177
1163 /// <summary> 1178 /// <summary>
1164 /// Login has been factored in this way because it gets called 1179 /// Login has been factored in this way because it gets called
1165 /// from several places in the module, and we want it to work 1180 /// from several places in the module, and we want it to work
1166 /// the same way each time. 1181 /// the same way each time.
1167 /// </summary> 1182 /// </summary>
1168 private bool DoAdminLogin() 1183 private bool DoAdminLogin()
@@ -1177,15 +1192,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1177 XmlElement resp = null; 1192 XmlElement resp = null;
1178 1193
1179 resp = VivoxLogin(m_vivoxAdminUser, m_vivoxAdminPassword); 1194 resp = VivoxLogin(m_vivoxAdminUser, m_vivoxAdminPassword);
1180 1195
1181 if (XmlFind(resp, "response.level0.body.status", out status)) 1196 if (XmlFind(resp, "response.level0.body.status", out status))
1182 { 1197 {
1183 if (status == "Ok") 1198 if (status == "Ok")
1184 { 1199 {
1185 m_log.Info("[VivoxVoice] Admin connection established"); 1200 m_log.Info("[VivoxVoice] Admin connection established");
1186 if (XmlFind(resp, "response.level0.body.auth_token", out m_authToken)) 1201 if (XmlFind(resp, "response.level0.body.auth_token", out m_authToken))
1187 { 1202 {
1188 if (m_dumpXml) m_log.DebugFormat("[VivoxVoice] Auth Token <{0}>", 1203 if (m_dumpXml) m_log.DebugFormat("[VivoxVoice] Auth Token <{0}>",
1189 m_authToken); 1204 m_authToken);
1190 m_adminConnected = true; 1205 m_adminConnected = true;
1191 } 1206 }
@@ -1204,9 +1219,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1204 1219
1205 /// <summary> 1220 /// <summary>
1206 /// The XmlScan routine is provided to aid in the 1221 /// The XmlScan routine is provided to aid in the
1207 /// reverse engineering of incompletely 1222 /// reverse engineering of incompletely
1208 /// documented packets returned by the Vivox 1223 /// documented packets returned by the Vivox
1209 /// voice server. It is only called if the 1224 /// voice server. It is only called if the
1210 /// m_dumpXml switch is set. 1225 /// m_dumpXml switch is set.
1211 /// </summary> 1226 /// </summary>
1212 private void XmlScanl(XmlElement e, int index) 1227 private void XmlScanl(XmlElement e, int index)
@@ -1251,7 +1266,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1251 private bool XmlFind(XmlElement root, string tag, int nth, out string result) 1266 private bool XmlFind(XmlElement root, string tag, int nth, out string result)
1252 { 1267 {
1253 if (root == null || tag == null || tag == String.Empty) 1268 if (root == null || tag == null || tag == String.Empty)
1254 { 1269 {
1255 result = String.Empty; 1270 result = String.Empty;
1256 return false; 1271 return false;
1257 } 1272 }
@@ -1262,7 +1277,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1262 { 1277 {
1263 int nth = 0; 1278 int nth = 0;
1264 if (root == null || tag == null || tag == String.Empty) 1279 if (root == null || tag == null || tag == String.Empty)
1265 { 1280 {
1266 result = String.Empty; 1281 result = String.Empty;
1267 return false; 1282 return false;
1268 } 1283 }
@@ -1273,7 +1288,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1273 /// XmlSearch is initially called by XmlFind, and then 1288 /// XmlSearch is initially called by XmlFind, and then
1274 /// recursively called by itself until the document 1289 /// recursively called by itself until the document
1275 /// supplied to XmlFind is either exhausted or the name hierarchy 1290 /// supplied to XmlFind is either exhausted or the name hierarchy
1276 /// is matched. 1291 /// is matched.
1277 /// 1292 ///
1278 /// If the hierarchy is matched, the value is returned in 1293 /// If the hierarchy is matched, the value is returned in
1279 /// result, and true returned as the function's 1294 /// result, and true returned as the function's
@@ -1287,7 +1302,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1287 result = String.Empty; 1302 result = String.Empty;
1288 return false; 1303 return false;
1289 } 1304 }
1290 1305
1291 if (tags.Length-index == 1) 1306 if (tags.Length-index == 1)
1292 { 1307 {
1293 if (nth == 0) 1308 if (nth == 0)
@@ -1324,5 +1339,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.VivoxVoice
1324 result = String.Empty; 1339 result = String.Empty;
1325 return false; 1340 return false;
1326 } 1341 }
1342
1343 private void HandleDebug(string module, string[] cmd)
1344 {
1345 if (cmd.Length < 3)
1346 {
1347 MainConsole.Instance.Output("Error: missing on/off flag");
1348 return;
1349 }
1350
1351 if (cmd[2] == "on")
1352 m_dumpXml = true;
1353 else if (cmd[2] == "off")
1354 m_dumpXml = false;
1355 else
1356 MainConsole.Instance.Output("Error: only on and off are supported");
1357 }
1327 } 1358 }
1328} 1359}
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
index e1b6abb..8791235 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs
@@ -125,7 +125,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
125 { 125 {
126 if (!m_groupMessagingEnabled) 126 if (!m_groupMessagingEnabled)
127 return; 127 return;
128 128
129 scene.RegisterModuleInterface<IGroupsMessagingModule>(this); 129 scene.RegisterModuleInterface<IGroupsMessagingModule>(this);
130 130
131 scene.AddCommand( 131 scene.AddCommand(
@@ -136,7 +136,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
136 "This setting turns on very verbose groups messaging debugging", 136 "This setting turns on very verbose groups messaging debugging",
137 HandleDebugGroupsMessagingVerbose); 137 HandleDebugGroupsMessagingVerbose);
138 } 138 }
139 139
140 public void RegionLoaded(Scene scene) 140 public void RegionLoaded(Scene scene)
141 { 141 {
142 if (!m_groupMessagingEnabled) 142 if (!m_groupMessagingEnabled)
@@ -205,7 +205,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
205 m_msgTransferModule = null; 205 m_msgTransferModule = null;
206 } 206 }
207 207
208 public Type ReplaceableInterface 208 public Type ReplaceableInterface
209 { 209 {
210 get { return null; } 210 get { return null; }
211 } 211 }
@@ -253,7 +253,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
253 { 253 {
254 if (m_debugEnabled) 254 if (m_debugEnabled)
255 m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 255 m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
256 256
257 GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); 257 GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null);
258 258
259 if (groupInfo != null) 259 if (groupInfo != null)
@@ -270,7 +270,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
270 { 270 {
271 SendMessageToGroup(im, groupID, new UUID(im.fromAgentID), null); 271 SendMessageToGroup(im, groupID, new UUID(im.fromAgentID), null);
272 } 272 }
273 273
274 public void SendMessageToGroup( 274 public void SendMessageToGroup(
275 GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition) 275 GridInstantMessage im, UUID groupID, UUID sendingAgentForGroupCalls, Func<GroupMembersData, bool> sendCondition)
276 { 276 {
@@ -294,28 +294,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
294 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds); 294 m_usersOnlineCache.Add(groupID, onlineAgents, m_usersOnlineCacheExpirySeconds);
295 } 295 }
296 296
297 attemptDeliveryUuidSet 297 attemptDeliveryUuidSet
298 = new HashSet<string>(Array.ConvertAll<PresenceInfo, string>(onlineAgents, pi => pi.UserID)); 298 = new HashSet<string>(Array.ConvertAll<PresenceInfo, string>(onlineAgents, pi => pi.UserID));
299
300 //Array.ForEach<PresenceInfo>(onlineAgents, pi => attemptDeliveryUuidSet.Add(pi.UserID));
301
302 //groupMembers = groupMembers.Where(gmd => onlineAgentsUuidSet.Contains(gmd.AgentID.ToString())).ToList();
303
304 // if (m_debugEnabled)
305// m_log.DebugFormat(
306// "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members, {2} online",
307// groupID, groupMembersCount, groupMembers.Count());
308 } 299 }
309 else 300 else
310 { 301 {
311 attemptDeliveryUuidSet 302 attemptDeliveryUuidSet
312 = new HashSet<string>(groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString())); 303 = new HashSet<string>(groupMembers.ConvertAll<string>(gmd => gmd.AgentID.ToString()));
313 304
314 if (m_debugEnabled) 305 if (m_debugEnabled)
315 m_log.DebugFormat( 306 m_log.DebugFormat(
316 "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members", 307 "[GROUPS-MESSAGING]: SendMessageToGroup called for group {0} with {1} visible members",
317 groupID, groupMembers.Count); 308 groupID, groupMembers.Count);
318 } 309 }
319 310
320 foreach (GroupMembersData member in groupMembers) 311 foreach (GroupMembersData member in groupMembers)
321 { 312 {
@@ -323,9 +314,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
323 { 314 {
324 if (!sendCondition(member)) 315 if (!sendCondition(member))
325 { 316 {
326 if (m_debugEnabled) 317 if (m_debugEnabled)
327 m_log.DebugFormat( 318 m_log.DebugFormat(
328 "[GROUPS-MESSAGING]: Not sending to {0} as they do not fulfill send condition", 319 "[GROUPS-MESSAGING]: Not sending to {0} as they do not fulfill send condition",
329 member.AgentID); 320 member.AgentID);
330 321
331 continue; 322 continue;
@@ -334,7 +325,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
334 else if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) 325 else if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID))
335 { 326 {
336 // Don't deliver messages to people who have dropped this session 327 // Don't deliver messages to people who have dropped this session
337 if (m_debugEnabled) 328 if (m_debugEnabled)
338 m_log.DebugFormat( 329 m_log.DebugFormat(
339 "[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); 330 "[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID);
340 331
@@ -369,9 +360,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
369 // If they're not local, forward across the grid 360 // If they're not local, forward across the grid
370 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); 361 m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { });
371 362
372 if (m_debugEnabled) 363 if (m_debugEnabled)
373 m_log.DebugFormat( 364 m_log.DebugFormat(
374 "[GROUPS-MESSAGING]: Delivering to {0} via grid took {1} ms", 365 "[GROUPS-MESSAGING]: Delivering to {0} via grid took {1} ms",
375 member.AgentID, Environment.TickCount - startTick); 366 member.AgentID, Environment.TickCount - startTick);
376 } 367 }
377 else 368 else
@@ -381,21 +372,22 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
381 ProcessMessageFromGroupSession(msg, client); 372 ProcessMessageFromGroupSession(msg, client);
382 373
383 // Deliver locally, directly 374 // Deliver locally, directly
384 if (m_debugEnabled) 375 if (m_debugEnabled)
385 m_log.DebugFormat( 376 m_log.DebugFormat(
386 "[GROUPS-MESSAGING]: Delivering to {0} locally took {1} ms", 377 "[GROUPS-MESSAGING]: Delivering to {0} locally took {1} ms",
387 member.AgentID, Environment.TickCount - startTick); 378 member.AgentID, Environment.TickCount - startTick);
388 } 379 }
389 } 380 }
390 else 381 else if(im.dialog != (byte)InstantMessageDialog.SessionAdd &&
382 im.dialog != (byte)InstantMessageDialog.SessionDrop)
391 { 383 {
392 int startTick = Environment.TickCount; 384 int startTick = Environment.TickCount;
393 385
394 m_msgTransferModule.HandleUndeliverableMessage(msg, delegate(bool success) { }); 386 m_msgTransferModule.HandleUndeliverableMessage(msg, delegate(bool success) { });
395 387
396 if (m_debugEnabled) 388 if (m_debugEnabled)
397 m_log.DebugFormat( 389 m_log.DebugFormat(
398 "[GROUPS-MESSAGING]: Handling undeliverable message for {0} took {1} ms", 390 "[GROUPS-MESSAGING]: Handling undeliverable message for {0} took {1} ms",
399 member.AgentID, Environment.TickCount - startTick); 391 member.AgentID, Environment.TickCount - startTick);
400 } 392 }
401 } 393 }
@@ -405,7 +397,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
405 "[GROUPS-MESSAGING]: Total SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3} ms", 397 "[GROUPS-MESSAGING]: Total SendMessageToGroup for group {0} with {1} members, {2} candidates for delivery took {3} ms",
406 groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick); 398 groupID, groupMembersCount, attemptDeliveryUuidSet.Count(), Environment.TickCount - requestStartTick);
407 } 399 }
408 400
409 #region SimGridEventHandlers 401 #region SimGridEventHandlers
410 402
411 void OnClientLogin(IClientAPI client) 403 void OnClientLogin(IClientAPI client)
@@ -425,7 +417,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
425 // The instant message module will only deliver messages of dialog types: 417 // The instant message module will only deliver messages of dialog types:
426 // MessageFromAgent, StartTyping, StopTyping, MessageFromObject 418 // MessageFromAgent, StartTyping, StopTyping, MessageFromObject
427 // 419 //
428 // Any other message type will not be delivered to a client by the 420 // Any other message type will not be delivered to a client by the
429 // Instant Message Module 421 // Instant Message Module
430 422
431 if (m_debugEnabled) 423 if (m_debugEnabled)
@@ -436,28 +428,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
436 } 428 }
437 429
438 // Incoming message from a group 430 // Incoming message from a group
439 if ((msg.fromGroup == true) && 431 if ((msg.fromGroup == true) &&
440 ((msg.dialog == (byte)InstantMessageDialog.SessionSend) 432 ((msg.dialog == (byte)InstantMessageDialog.SessionSend)
441 || (msg.dialog == (byte)InstantMessageDialog.SessionAdd) 433 || (msg.dialog == (byte)InstantMessageDialog.SessionAdd)
442 || (msg.dialog == (byte)InstantMessageDialog.SessionDrop))) 434 || (msg.dialog == (byte)InstantMessageDialog.SessionDrop)))
443 { 435 {
444 IClientAPI client = null; 436 IClientAPI client = null;
445 437
446 if (msg.dialog == (byte)InstantMessageDialog.SessionSend) 438 client = GetActiveClient(new UUID(msg.toAgentID));
447 {
448 client = GetActiveClient(new UUID(msg.toAgentID));
449 439
450 if (client != null) 440 if (client == null)
451 { 441 {
452 if (m_debugEnabled) 442 m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
453 m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} locally", client.Name);
454 }
455 else
456 {
457 m_log.WarnFormat("[GROUPS-MESSAGING]: Received a message over the grid for a client that isn't here: {0}", msg.toAgentID);
458 443
459 return; 444 return;
460 }
461 } 445 }
462 446
463 ProcessMessageFromGroupSession(msg, client); 447 ProcessMessageFromGroupSession(msg, client);
@@ -466,83 +450,101 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
466 450
467 private void ProcessMessageFromGroupSession(GridInstantMessage msg, IClientAPI client) 451 private void ProcessMessageFromGroupSession(GridInstantMessage msg, IClientAPI client)
468 { 452 {
469 if (m_debugEnabled) 453 if (m_debugEnabled)
470 m_log.DebugFormat( 454 m_log.DebugFormat(
471 "[GROUPS-MESSAGING]: Session message from {0} going to agent {1}, sessionID {2}, type {3}", 455 "[GROUPS-MESSAGING]: Session message from {0} going to agent {1}, sessionID {2}, type {3}",
472 msg.fromAgentName, msg.toAgentID, msg.imSessionID, (InstantMessageDialog)msg.dialog); 456 msg.fromAgentName, msg.toAgentID, msg.imSessionID, (InstantMessageDialog)msg.dialog);
473 457
474 UUID AgentID = new UUID(msg.fromAgentID); 458 UUID fromAgentID = new UUID(msg.fromAgentID);
475 UUID GroupID = new UUID(msg.imSessionID); 459 UUID GroupID = new UUID(msg.imSessionID);
460 IEventQueue eq = client.Scene.RequestModuleInterface<IEventQueue>();
476 461
477 switch (msg.dialog) 462 switch (msg.dialog)
478 { 463 {
479 case (byte)InstantMessageDialog.SessionAdd: 464 case (byte)InstantMessageDialog.SessionAdd:
480 m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); 465 m_groupData.AgentInvitedToGroupChatSession(fromAgentID, GroupID);
466 if(eq != null)
467 eq.ChatterBoxSessionAgentListUpdates(
468 GroupID
469 , fromAgentID
470 , client.AgentId
471 , false //canVoiceChat
472 , false //isModerator
473 , false //text mute
474 , true // enter
475 );
481 break; 476 break;
482 477
483 case (byte)InstantMessageDialog.SessionDrop: 478 case (byte)InstantMessageDialog.SessionDrop:
484 m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); 479 m_groupData.AgentDroppedFromGroupChatSession(fromAgentID, GroupID);
480 if(eq != null)
481 eq.ChatterBoxSessionAgentListUpdates(
482 GroupID
483 , fromAgentID
484 , client.AgentId
485 , false //canVoiceChat
486 , false //isModerator
487 , false //text mute
488 , false // leave
489 );
485 break; 490 break;
486 491
487 case (byte)InstantMessageDialog.SessionSend: 492 case (byte)InstantMessageDialog.SessionSend:
488 if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) 493 if (!m_groupData.hasAgentDroppedGroupChatSession(client.AgentId, GroupID))
489 && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID)
490 )
491 { 494 {
492 // Agent not in session and hasn't dropped from session 495 if(!m_groupData.hasAgentBeenInvitedToGroupChatSession(client.AgentId, GroupID))
493 // Add them to the session for now, and Invite them
494 m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID);
495
496 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null);
497 if (groupInfo != null)
498 { 496 {
499 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message");
500 497
501 // Force? open the group session dialog??? 498 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null);
502 // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); 499 if (groupInfo != null)
503 IEventQueue eq = client.Scene.RequestModuleInterface<IEventQueue>(); 500 {
504 eq.ChatterboxInvitation( 501 if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message");
505 GroupID 502
506 , groupInfo.GroupName 503 if(eq != null)
507 , new UUID(msg.fromAgentID) 504 {
508 , msg.message 505 eq.ChatterboxInvitation(
509 , new UUID(msg.toAgentID) 506 GroupID
510 , msg.fromAgentName 507 , groupInfo.GroupName
511 , msg.dialog 508 , fromAgentID
512 , msg.timestamp 509 , msg.message
513 , msg.offline == 1 510 , client.AgentId
514 , (int)msg.ParentEstateID 511 , msg.fromAgentName
515 , msg.Position 512 , msg.dialog
516 , 1 513 , msg.timestamp
517 , new UUID(msg.imSessionID) 514 , msg.offline == 1
518 , msg.fromGroup 515 , (int)msg.ParentEstateID
519 , Utils.StringToBytes(groupInfo.GroupName) 516 , msg.Position
520 ); 517 , 1
521 518 , new UUID(msg.imSessionID)
522 eq.ChatterBoxSessionAgentListUpdates( 519 , msg.fromGroup
523 new UUID(GroupID) 520 , Utils.StringToBytes(groupInfo.GroupName)
524 , new UUID(msg.fromAgentID) 521 );
525 , new UUID(msg.toAgentID) 522 }
526 , false //canVoiceChat 523 }
527 , false //isModerator 524 }
528 , false //text mute 525 else
529 ); 526 {
527 client.SendInstantMessage(msg);
530 } 528 }
531 529
532 break; 530// if (!m_groupData.hasAgentBeenInvitedToGroupChatSession(fromAgentID, GroupID))
533 } 531 {
534 else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) 532 m_groupData.AgentInvitedToGroupChatSession(fromAgentID, GroupID);
535 { 533 eq.ChatterBoxSessionAgentListUpdates(
536 // User hasn't dropped, so they're in the session, 534 GroupID
537 // maybe we should deliver it. 535 , fromAgentID
538 client.SendInstantMessage(msg); 536 , client.AgentId
537 , false //canVoiceChat
538 , false //isModerator
539 , false //text mute
540 , true // enter
541 );
542 }
539 } 543 }
540
541 break; 544 break;
542 545
543 default: 546 default:
544 client.SendInstantMessage(msg); 547 client.SendInstantMessage(msg);
545
546 break;; 548 break;;
547 } 549 }
548 } 550 }
@@ -559,41 +561,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
559 DebugGridInstantMessage(im); 561 DebugGridInstantMessage(im);
560 } 562 }
561 563
564 UUID GroupID = new UUID(im.imSessionID);
565 UUID AgentID = new UUID(im.fromAgentID);
566
562 // Start group IM session 567 // Start group IM session
563 if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) 568 if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart))
564 { 569 {
565 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); 570 if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID);
566 571
567 UUID GroupID = new UUID(im.imSessionID);
568 UUID AgentID = new UUID(im.fromAgentID);
569
570 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); 572 GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null);
571 573
572 if (groupInfo != null) 574 if (groupInfo != null)
573 { 575 {
574 m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); 576 m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID);
575 577
576 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); 578 ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID);
577 579
578 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>(); 580 // we need to send here a list of known participants.
579 queue.ChatterBoxSessionAgentListUpdates( 581 im.dialog = (byte)InstantMessageDialog.SessionAdd;
580 GroupID 582 SendMessageToGroup(im, GroupID);
581 , AgentID
582 , new UUID(im.toAgentID)
583 , false //canVoiceChat
584 , false //isModerator
585 , false //text mute
586 );
587 } 583 }
588 } 584 }
589 585
590 // Send a message from locally connected client to a group 586 // Send a message from locally connected client to a group
591 if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) 587 if ((im.dialog == (byte)InstantMessageDialog.SessionSend))
592 { 588 {
593 UUID GroupID = new UUID(im.imSessionID); 589 if (m_debugEnabled)
594 UUID AgentID = new UUID(im.fromAgentID);
595
596 if (m_debugEnabled)
597 m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); 590 m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
598 591
599 //If this agent is sending a message, then they want to be in the session 592 //If this agent is sending a message, then they want to be in the session
@@ -601,6 +594,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
601 594
602 SendMessageToGroup(im, GroupID); 595 SendMessageToGroup(im, GroupID);
603 } 596 }
597
598 if ((im.dialog == (byte)InstantMessageDialog.SessionDrop))
599 {
600 if (m_debugEnabled)
601 m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString());
602
603 m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID);
604
605 SendMessageToGroup(im, GroupID);
606 }
604 } 607 }
605 608
606 #endregion 609 #endregion
@@ -656,7 +659,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
656 /// </summary> 659 /// </summary>
657 private IClientAPI GetActiveClient(UUID agentID) 660 private IClientAPI GetActiveClient(UUID agentID)
658 { 661 {
659 if (m_debugEnabled) 662 if (m_debugEnabled)
660 m_log.DebugFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); 663 m_log.DebugFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID);
661 664
662 IClientAPI child = null; 665 IClientAPI child = null;
@@ -669,14 +672,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
669 { 672 {
670 if (!sp.IsChildAgent) 673 if (!sp.IsChildAgent)
671 { 674 {
672 if (m_debugEnabled) 675 if (m_debugEnabled)
673 m_log.DebugFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name); 676 m_log.DebugFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", sp.ControllingClient.Name);
674 677
675 return sp.ControllingClient; 678 return sp.ControllingClient;
676 } 679 }
677 else 680 else
678 { 681 {
679 if (m_debugEnabled) 682 if (m_debugEnabled)
680 m_log.DebugFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name); 683 m_log.DebugFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", sp.ControllingClient.Name);
681 684
682 child = sp.ControllingClient; 685 child = sp.ControllingClient;
@@ -687,12 +690,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
687 // If we didn't find a root, then just return whichever child we found, or null if none 690 // If we didn't find a root, then just return whichever child we found, or null if none
688 if (child == null) 691 if (child == null)
689 { 692 {
690 if (m_debugEnabled) 693 if (m_debugEnabled)
691 m_log.DebugFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); 694 m_log.DebugFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID);
692 } 695 }
693 else 696 else
694 { 697 {
695 if (m_debugEnabled) 698 if (m_debugEnabled)
696 m_log.DebugFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); 699 m_log.DebugFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name);
697 } 700 }
698 701
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
index 1565da9..65d50bb 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs
@@ -50,19 +50,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
50 /// ; To use this module, you must specify the following in your OpenSim.ini 50 /// ; To use this module, you must specify the following in your OpenSim.ini
51 /// [GROUPS] 51 /// [GROUPS]
52 /// Enabled = true 52 /// Enabled = true
53 /// 53 ///
54 /// Module = GroupsModule 54 /// Module = GroupsModule
55 /// NoticesEnabled = true 55 /// NoticesEnabled = true
56 /// DebugEnabled = true 56 /// DebugEnabled = true
57 /// 57 ///
58 /// GroupsServicesConnectorModule = XmlRpcGroupsServicesConnector 58 /// GroupsServicesConnectorModule = XmlRpcGroupsServicesConnector
59 /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php 59 /// XmlRpcServiceURL = http://osflotsam.org/xmlrpc.php
60 /// XmlRpcServiceReadKey = 1234 60 /// XmlRpcServiceReadKey = 1234
61 /// XmlRpcServiceWriteKey = 1234 61 /// XmlRpcServiceWriteKey = 1234
62 /// 62 ///
63 /// MessagingModule = GroupsMessagingModule 63 /// MessagingModule = GroupsMessagingModule
64 /// MessagingEnabled = true 64 /// MessagingEnabled = true
65 /// 65 ///
66 /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for 66 /// ; Disables HTTP Keep-Alive for Groups Module HTTP Requests, work around for
67 /// ; a problem discovered on some Windows based region servers. Only disable 67 /// ; a problem discovered on some Windows based region servers. Only disable
68 /// ; if you see a large number (dozens) of the following Exceptions: 68 /// ; if you see a large number (dozens) of the following Exceptions:
@@ -79,7 +79,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
79 private IMessageTransferModule m_msgTransferModule; 79 private IMessageTransferModule m_msgTransferModule;
80 80
81 private IGroupsMessagingModule m_groupsMessagingModule; 81 private IGroupsMessagingModule m_groupsMessagingModule;
82 82
83 private IGroupsServicesConnector m_groupData; 83 private IGroupsServicesConnector m_groupData;
84 84
85 // Configuration settings 85 // Configuration settings
@@ -205,10 +205,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
205 } 205 }
206 206
207 scene.EventManager.OnNewClient += OnNewClient; 207 scene.EventManager.OnNewClient += OnNewClient;
208 scene.EventManager.OnMakeRootAgent += OnMakeRoot;
209 scene.EventManager.OnMakeChildAgent += OnMakeChild;
208 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 210 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
209 // The InstantMessageModule itself doesn't do this, 211 scene.EventManager.OnClientClosed += OnClientClosed;
210 // so lets see if things explode if we don't do it
211 // scene.EventManager.OnClientClosed += OnClientClosed;
212 212
213 } 213 }
214 214
@@ -217,6 +217,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
217 if (!m_groupsEnabled) 217 if (!m_groupsEnabled)
218 return; 218 return;
219 219
220 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
221
222 scene.EventManager.OnNewClient -= OnNewClient;
223 scene.EventManager.OnMakeRootAgent -= OnMakeRoot;
224 scene.EventManager.OnMakeChildAgent -= OnMakeChild;
225 scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage;
226 scene.EventManager.OnClientClosed -= OnClientClosed;
220 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 227 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
221 228
222 lock (m_sceneList) 229 lock (m_sceneList)
@@ -233,7 +240,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
233 if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module."); 240 if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module.");
234 } 241 }
235 242
236 public Type ReplaceableInterface 243 public Type ReplaceableInterface
237 { 244 {
238 get { return null; } 245 get { return null; }
239 } 246 }
@@ -255,84 +262,124 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
255 #endregion 262 #endregion
256 263
257 #region EventHandlers 264 #region EventHandlers
265
266 private void OnMakeRoot(ScenePresence sp)
267 {
268 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
269
270 sp.ControllingClient.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
271 // Used for Notices and Group Invites/Accept/Reject
272 sp.ControllingClient.OnInstantMessage += OnInstantMessage;
273
274 // comented out because some viewers no longer suport it
275 // sp.ControllingClient.AddGenericPacketHandler("avatargroupsrequest", AvatarGroupsRequest);
276
277 // Send out group data update for compatibility.
278 // There might be some problem with the thread we're generating this on but not
279 // doing the update at this time causes problems (Mantis #7920 and #7915)
280 // TODO: move sending this update to a later time in the rootification of the client.
281 if(!sp.haveGroupInformation)
282 SendAgentGroupDataUpdate(sp.ControllingClient, false);
283 }
284
285 private void OnMakeChild(ScenePresence sp)
286 {
287 if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
288
289 sp.ControllingClient.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
290 sp.ControllingClient.OnInstantMessage -= OnInstantMessage;
291 }
292
258 private void OnNewClient(IClientAPI client) 293 private void OnNewClient(IClientAPI client)
259 { 294 {
260 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 295 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
261 296
262 client.OnUUIDGroupNameRequest += HandleUUIDGroupNameRequest;
263 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; 297 client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest;
264 client.OnRequestAvatarProperties += OnRequestAvatarProperties; 298 client.OnRequestAvatarProperties += OnRequestAvatarProperties;
265 299
266 // Used for Notices and Group Invites/Accept/Reject
267 client.OnInstantMessage += OnInstantMessage;
268 300
269 // Send client their groups information.
270 SendAgentGroupDataUpdate(client, client.AgentId);
271 } 301 }
272 302
303/* this should be the right message to ask for other avatars groups
304
305 private void AvatarGroupsRequest(Object sender, string method, List<String> args)
306 {
307 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
308
309 if (!(sender is IClientAPI))
310 return;
311
312 IClientAPI remoteClient = (IClientAPI)sender;
313
314 UUID avatarID;
315 UUID.TryParse(args[0], out avatarID);
316
317 if (avatarID != UUID.Zero)
318 {
319 GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID);
320 remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups);
321 }
322 }
323*/
324
325 // this should not be used to send groups memberships, but some viewers do expect it
326 // it does send unnecessary memberships, when viewers just want other properties information
273 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID) 327 private void OnRequestAvatarProperties(IClientAPI remoteClient, UUID avatarID)
274 { 328 {
275 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 329 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
276 330
277 //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray();
278 GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); 331 GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID);
279 remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); 332 remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups);
280 } 333 }
281 334
282 /* 335
283 * This becomes very problematic in a shared module. In a shared module you may have more then one 336 private void OnClientClosed(UUID AgentId, Scene scene)
284 * reference to IClientAPI's, one for 0 or 1 root connections, and 0 or more child connections.
285 * The OnClientClosed event does not provide anything to indicate which one of those should be closed
286 * nor does it provide what scene it was from so that the specific reference can be looked up.
287 * The InstantMessageModule.cs does not currently worry about unregistering the handles,
288 * and it should be an issue, since it's the client that references us not the other way around
289 * , so as long as we don't keep a reference to the client laying around, the client can still be GC'ed
290 private void OnClientClosed(UUID AgentId)
291 { 337 {
292 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 338 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
339 if (scene == null)
340 return;
293 341
294 lock (m_ActiveClients) 342 ScenePresence sp = scene.GetScenePresence(AgentId);
343 IClientAPI client = sp.ControllingClient;
344 if (client != null)
295 { 345 {
296 if (m_ActiveClients.ContainsKey(AgentId)) 346 client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest;
347 client.OnRequestAvatarProperties -= OnRequestAvatarProperties;
348 // make child possible not called?
349 client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
350 client.OnInstantMessage -= OnInstantMessage;
351 }
352
353/*
354 lock (m_ActiveClients)
297 { 355 {
298 IClientAPI client = m_ActiveClients[AgentId]; 356 if (m_ActiveClients.ContainsKey(AgentId))
299 client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest; 357 {
300 client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest; 358 IClientAPI client = m_ActiveClients[AgentId];
301 client.OnDirFindQuery -= OnDirFindQuery; 359 client.OnUUIDGroupNameRequest -= HandleUUIDGroupNameRequest;
302 client.OnInstantMessage -= OnInstantMessage; 360 client.OnAgentDataUpdateRequest -= OnAgentDataUpdateRequest;
361 client.OnDirFindQuery -= OnDirFindQuery;
362 client.OnInstantMessage -= OnInstantMessage;
303 363
304 m_ActiveClients.Remove(AgentId); 364 m_ActiveClients.Remove(AgentId);
305 } 365 }
306 else 366 else
307 { 367 {
308 if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Client closed that wasn't registered here."); 368 if (m_debugEnabled) m_log.WarnFormat("[GROUPS]: Client closed that wasn't registered here.");
369 }
309 } 370 }
310 371*/
311
312 }
313 } 372 }
314 */
315 373
316 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID) 374 private void OnAgentDataUpdateRequest(IClientAPI remoteClient, UUID dataForAgentID, UUID sessionID)
317 { 375 {
318 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 376 // this a private message for own agent only
319 377 if (dataForAgentID != GetRequestingAgentID(remoteClient))
320 UUID activeGroupID = UUID.Zero; 378 return;
321 string activeGroupTitle = string.Empty;
322 string activeGroupName = string.Empty;
323 ulong activeGroupPowers = (ulong)GroupPowers.None;
324
325 GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient), dataForAgentID);
326 if (membership != null)
327 {
328 activeGroupID = membership.GroupID;
329 activeGroupTitle = membership.GroupTitle;
330 activeGroupPowers = membership.GroupPowers;
331 }
332
333 SendAgentDataUpdate(remoteClient, dataForAgentID, activeGroupID, activeGroupName, activeGroupPowers, activeGroupTitle);
334 379
335 SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); 380 SendAgentGroupDataUpdate(remoteClient, false);
381 // its a info request not a change, so nothing is sent to others
382 // they do get the group title with the avatar object update on arrivel to a region
336 } 383 }
337 384
338 private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient) 385 private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient)
@@ -340,7 +387,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
340 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 387 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
341 388
342 string GroupName; 389 string GroupName;
343 390
344 GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null); 391 GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null);
345 if (group != null) 392 if (group != null)
346 { 393 {
@@ -356,9 +403,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
356 403
357 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) 404 private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im)
358 { 405 {
359 if (m_debugEnabled) 406 if (m_debugEnabled)
360 m_log.DebugFormat( 407 m_log.DebugFormat(
361 "[GROUPS]: {0} called for {1}, message type {2}", 408 "[GROUPS]: {0} called for {1}, message type {2}",
362 System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog); 409 System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name, (InstantMessageDialog)im.dialog);
363 410
364 // Group invitations 411 // Group invitations
@@ -403,11 +450,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
403 450
404 OutgoingInstantMessage(msg, inviteInfo.AgentID); 451 OutgoingInstantMessage(msg, inviteInfo.AgentID);
405 452
406 UpdateAllClientsWithGroupInfo(inviteInfo.AgentID); 453 IClientAPI inviteeClient = GetActiveRootClient(inviteInfo.AgentID);
407 454 if(inviteeClient !=null)
408 // TODO: If the inviter is still online, they need an agent dataupdate 455 {
409 // and maybe group membership updates for the invitee 456 SendAgentGroupDataUpdate(inviteeClient,true);
410 457 }
411 m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); 458 m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID);
412 } 459 }
413 460
@@ -459,8 +506,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
459 //variable will be set to null and attachment will 506 //variable will be set to null and attachment will
460 //not be included with the group notice. 507 //not be included with the group notice.
461 Scene scene = (Scene)remoteClient.Scene; 508 Scene scene = (Scene)remoteClient.Scene;
462 item = new InventoryItemBase(itemID, ownerID); 509 item = scene.InventoryService.GetItem(ownerID, itemID);
463 item = scene.InventoryService.GetItem(item);
464 510
465 if (item != null) 511 if (item != null)
466 { 512 {
@@ -523,20 +569,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
523 if (targetUser != null) 569 if (targetUser != null)
524 { 570 {
525 m_log.DebugFormat( 571 m_log.DebugFormat(
526 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", 572 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
527 NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); 573 NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices);
528 } 574 }
529 else 575 else
530 { 576 {
531 m_log.DebugFormat( 577 m_log.DebugFormat(
532 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", 578 "[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})",
533 NoticeID, member.AgentID, member.AcceptNotices); 579 NoticeID, member.AgentID, member.AcceptNotices);
534 } 580 }
535 } 581 }
536 } 582 }
537 } 583 }
538 584
539 GridInstantMessage msg 585 GridInstantMessage msg
540 = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); 586 = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice);
541 587
542 if (m_groupsMessagingModule != null) 588 if (m_groupsMessagingModule != null)
@@ -553,7 +599,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
553 599
554 UUID noticeID = new UUID(im.imSessionID); 600 UUID noticeID = new UUID(im.imSessionID);
555 601
556 if (m_debugEnabled) 602 if (m_debugEnabled)
557 m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId); 603 m_log.DebugFormat("[GROUPS]: Requesting notice {0} for {1}", noticeID, remoteClient.AgentId);
558 604
559 GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); 605 GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID);
@@ -579,10 +625,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
579 } 625 }
580 else 626 else
581 { 627 {
582 if (m_debugEnabled) 628 if (m_debugEnabled)
583 m_log.DebugFormat( 629 m_log.DebugFormat(
584 "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.", 630 "[GROUPS]: Could not find notice {0} for {1} on GroupNoticeInventoryAccepted.",
585 noticeID, remoteClient.AgentId); 631 noticeID, remoteClient.AgentId);
586 } 632 }
587 } 633 }
588 634
@@ -598,15 +644,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
598 // so we need to send local updates to the agent. 644 // so we need to send local updates to the agent.
599 645
600 UUID ejecteeID = new UUID(im.toAgentID); 646 UUID ejecteeID = new UUID(im.toAgentID);
601 647 im.imSessionID = UUID.Zero.Guid;
602 im.dialog = (byte)InstantMessageDialog.MessageFromAgent; 648 im.dialog = (byte)InstantMessageDialog.MessageFromAgent;
603 OutgoingInstantMessage(im, ejecteeID); 649 OutgoingInstantMessage(im, ejecteeID);
604 650
605 IClientAPI ejectee = GetActiveClient(ejecteeID); 651 IClientAPI ejectee = GetActiveRootClient(ejecteeID);
606 if (ejectee != null) 652 if (ejectee != null)
607 { 653 {
608 UUID groupID = new UUID(im.imSessionID); 654 UUID groupID = new UUID(im.imSessionID);
609 ejectee.SendAgentDropGroup(groupID); 655 ejectee.SendAgentDropGroup(groupID);
656 SendAgentGroupDataUpdate(ejectee,true);
610 } 657 }
611 } 658 }
612 } 659 }
@@ -626,7 +673,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
626 case (byte)InstantMessageDialog.GroupInvitation: 673 case (byte)InstantMessageDialog.GroupInvitation:
627 case (byte)InstantMessageDialog.GroupNotice: 674 case (byte)InstantMessageDialog.GroupNotice:
628 UUID toAgentID = new UUID(msg.toAgentID); 675 UUID toAgentID = new UUID(msg.toAgentID);
629 IClientAPI localClient = GetActiveClient(toAgentID); 676 IClientAPI localClient = GetActiveRootClient(toAgentID);
630 if (localClient != null) 677 if (localClient != null)
631 { 678 {
632 localClient.SendInstantMessage(msg); 679 localClient.SendInstantMessage(msg);
@@ -651,18 +698,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
651 { 698 {
652 return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); 699 return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name);
653 } 700 }
654 701
655 public void ActivateGroup(IClientAPI remoteClient, UUID groupID) 702 public void ActivateGroup(IClientAPI remoteClient, UUID groupID)
656 { 703 {
657 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 704 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
658 705
659 m_groupData.SetAgentActiveGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); 706 UUID agentID = GetRequestingAgentID(remoteClient);
707 m_groupData.SetAgentActiveGroup(agentID, agentID, groupID);
660 708
661 // Changing active group changes title, active powers, all kinds of things 709 // llClientView does this
662 // anyone who is in any region that can see this client, should probably be 710 SendAgentGroupDataUpdate(remoteClient, true);
663 // updated with new group info. At a minimum, they should get ScenePresence
664 // updated with new title.
665 UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient));
666 } 711 }
667 712
668 /// <summary> 713 /// <summary>
@@ -672,7 +717,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
672 { 717 {
673 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 718 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
674 719
675
676 List<GroupRolesData> agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); 720 List<GroupRolesData> agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID);
677 GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); 721 GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID);
678 722
@@ -695,10 +739,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
695 739
696 public List<GroupMembersData> GroupMembersRequest(IClientAPI remoteClient, UUID groupID) 740 public List<GroupMembersData> GroupMembersRequest(IClientAPI remoteClient, UUID groupID)
697 { 741 {
698 if (m_debugEnabled) 742 if (m_debugEnabled)
699 m_log.DebugFormat( 743 m_log.DebugFormat(
700 "[GROUPS]: GroupMembersRequest called for {0} from client {1}", groupID, remoteClient.Name); 744 "[GROUPS]: GroupMembersRequest called for {0} from client {1}", groupID, remoteClient.Name);
701 745
702 List<GroupMembersData> data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); 746 List<GroupMembersData> data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID);
703 747
704 if (m_debugEnabled) 748 if (m_debugEnabled)
@@ -710,7 +754,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
710 } 754 }
711 755
712 return data; 756 return data;
713
714 } 757 }
715 758
716 public List<GroupRolesData> GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID) 759 public List<GroupRolesData> GroupRoleDataRequest(IClientAPI remoteClient, UUID groupID)
@@ -744,7 +787,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
744 787
745 GroupProfileData profile = new GroupProfileData(); 788 GroupProfileData profile = new GroupProfileData();
746 789
747
748 GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); 790 GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null);
749 if (groupInfo != null) 791 if (groupInfo != null)
750 { 792 {
@@ -770,7 +812,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
770 profile.MemberTitle = memberInfo.GroupTitle; 812 profile.MemberTitle = memberInfo.GroupTitle;
771 profile.PowersMask = memberInfo.GroupPowers; 813 profile.PowersMask = memberInfo.GroupPowers;
772 } 814 }
773 815/*
816 this should save xmlrpc calls, but seems to return wrong GroupMembershipCount and GroupRolesCount
817 UUID agent = GetRequestingAgentID(remoteClient);
818 GroupProfileData profile = m_groupData.GetMemberGroupProfile(agent, groupID, agent);
819*/
774 return profile; 820 return profile;
775 } 821 }
776 822
@@ -783,7 +829,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
783 829
784 public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) 830 public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID)
785 { 831 {
786 if (m_debugEnabled) 832 if (m_debugEnabled)
787 m_log.DebugFormat( 833 m_log.DebugFormat(
788 "[GROUPS]: {0} called with groupID={1}, agentID={2}", 834 "[GROUPS]: {0} called with groupID={1}, agentID={2}",
789 System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); 835 System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID);
@@ -791,6 +837,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
791 return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID); 837 return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID);
792 } 838 }
793 839
840 public GroupMembershipData GetActiveMembershipData(UUID agentID)
841 {
842 return m_groupData.GetAgentActiveMembership(agentID, agentID);
843 }
844
794 public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) 845 public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
795 { 846 {
796 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 847 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -811,7 +862,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
811 { 862 {
812 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 863 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
813 864
814 if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name) != null) 865 GroupRecord groupRecord = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name);
866
867 if (groupRecord != null)
815 { 868 {
816 remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); 869 remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists.");
817 return UUID.Zero; 870 return UUID.Zero;
@@ -824,31 +877,31 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
824 877
825 if (avatar != null) 878 if (avatar != null)
826 { 879 {
827 if (avatar.UserLevel < m_levelGroupCreate) 880 if (avatar.GodController.UserLevel < m_levelGroupCreate)
828 { 881 {
829 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient permissions to create a group."); 882 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient permissions to create a group.");
830 return UUID.Zero; 883 return UUID.Zero;
831 } 884 }
832 } 885 }
833 886
834 // check funds 887 // check funds
835 // is there is a money module present ? 888 // is there a money module present ?
836 IMoneyModule money = scene.RequestModuleInterface<IMoneyModule>(); 889 IMoneyModule money = scene.RequestModuleInterface<IMoneyModule>();
837 if (money != null) 890 if (money != null && money.GroupCreationCharge > 0)
838 { 891 {
839 // do the transaction, that is if the agent has got sufficient funds 892 // do the transaction, that is if the agent has sufficient funds
840 if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) { 893 if (!money.AmountCovered(remoteClient.AgentId, money.GroupCreationCharge)) {
841 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got insufficient funds to create a group."); 894 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient funds to create a group.");
842 return UUID.Zero; 895 return UUID.Zero;
843 } 896 }
844 money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate); 897 money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, MoneyTransactionType.GroupCreate, name);
845 } 898 }
846 UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); 899 UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient));
847 900
848 remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); 901 remoteClient.SendCreateGroupReply(groupID, true, "Group created successfully");
849 902
850 // Update the founder with new group information. 903 // Update the founder with new group information.
851 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 904 SendAgentGroupDataUpdate(remoteClient, true);
852 905
853 return groupID; 906 return groupID;
854 } 907 }
@@ -873,7 +926,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
873 if (membership != null) 926 if (membership != null)
874 { 927 {
875 return membership.GroupTitle; 928 return membership.GroupTitle;
876 } 929 }
877 return string.Empty; 930 return string.Empty;
878 } 931 }
879 932
@@ -889,10 +942,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
889 // TODO: Not sure what all is needed here, but if the active group role change is for the group 942 // TODO: Not sure what all is needed here, but if the active group role change is for the group
890 // the client currently has set active, then we need to do a scene presence update too 943 // the client currently has set active, then we need to do a scene presence update too
891 // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID) 944 // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID)
892
893 UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient));
894 }
895 945
946 SendDataUpdate(remoteClient, true);
947 }
896 948
897 public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) 949 public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType)
898 { 950 {
@@ -929,7 +981,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
929 } 981 }
930 982
931 // TODO: This update really should send out updates for everyone in the role that just got changed. 983 // TODO: This update really should send out updates for everyone in the role that just got changed.
932 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 984 SendAgentGroupDataUpdate(remoteClient, false);
933 } 985 }
934 986
935 public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) 987 public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes)
@@ -947,7 +999,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
947 case 1: 999 case 1:
948 // Remove 1000 // Remove
949 m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); 1001 m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID);
950 1002
951 break; 1003 break;
952 default: 1004 default:
953 m_log.ErrorFormat("[GROUPS]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes); 1005 m_log.ErrorFormat("[GROUPS]: {0} does not understand changes == {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, changes);
@@ -955,7 +1007,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
955 } 1007 }
956 1008
957 // TODO: This update really should send out updates for everyone in the role that just got changed. 1009 // TODO: This update really should send out updates for everyone in the role that just got changed.
958 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 1010 SendAgentGroupDataUpdate(remoteClient, false);
959 } 1011 }
960 1012
961 public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) 1013 public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID)
@@ -983,7 +1035,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
983 msg.toAgentID = agentID.Guid; 1035 msg.toAgentID = agentID.Guid;
984 msg.dialog = dialog; 1036 msg.dialog = dialog;
985 msg.fromGroup = true; 1037 msg.fromGroup = true;
986 msg.offline = (byte)0; 1038 msg.offline = (byte)1; // Allow this message to be stored for offline use
987 msg.ParentEstateID = 0; 1039 msg.ParentEstateID = 0;
988 msg.Position = Vector3.Zero; 1040 msg.Position = Vector3.Zero;
989 msg.RegionID = UUID.Zero.Guid; 1041 msg.RegionID = UUID.Zero.Guid;
@@ -1035,14 +1087,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1035 return msg; 1087 return msg;
1036 } 1088 }
1037 1089
1038 public void SendAgentGroupDataUpdate(IClientAPI remoteClient)
1039 {
1040 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1041
1042 // Send agent information about his groups
1043 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
1044 }
1045
1046 public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) 1090 public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID)
1047 { 1091 {
1048 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1092 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -1050,10 +1094,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1050 // Should check to see if OpenEnrollment, or if there's an outstanding invitation 1094 // Should check to see if OpenEnrollment, or if there's an outstanding invitation
1051 m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero); 1095 m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero);
1052 1096
1097 // check funds
1098 // is there a money module present ?
1099 GroupRecord groupRecord = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null);
1100 IMoneyModule money = remoteClient.Scene.RequestModuleInterface<IMoneyModule>();
1101 if (money != null && groupRecord.MembershipFee > 0)
1102 {
1103 // do the transaction, that is if the agent has sufficient funds
1104 if (!money.AmountCovered(GetRequestingAgentID(remoteClient), groupRecord.MembershipFee)) {
1105 remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have insufficient funds to join the group.");
1106 return;
1107 }
1108 money.ApplyCharge(GetRequestingAgentID(remoteClient), groupRecord.MembershipFee, MoneyTransactionType.GroupJoin, groupRecord.GroupName);
1109 }
1110
1053 remoteClient.SendJoinGroupReply(groupID, true); 1111 remoteClient.SendJoinGroupReply(groupID, true);
1054 1112
1055 // Should this send updates to everyone in the group? 1113 SendAgentGroupDataUpdate(remoteClient, true);
1056 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient));
1057 } 1114 }
1058 1115
1059 public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) 1116 public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID)
@@ -1068,7 +1125,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1068 1125
1069 // SL sends out notifcations to the group messaging session that the person has left 1126 // SL sends out notifcations to the group messaging session that the person has left
1070 // Should this also update everyone who is in the group? 1127 // Should this also update everyone who is in the group?
1071 SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); 1128 SendAgentGroupDataUpdate(remoteClient, true);
1072 } 1129 }
1073 1130
1074 public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) 1131 public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID)
@@ -1120,17 +1177,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1120 } 1177 }
1121 1178
1122 GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); 1179 GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null);
1123 1180 if (groupInfo == null)
1124 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID);
1125 if ((groupInfo == null) || (account == null))
1126 {
1127 return; 1181 return;
1128 } 1182
1183
1184 IClientAPI ejecteeClient = GetActiveRootClient(ejecteeID);
1129 1185
1130 // Send Message to Ejectee 1186 // Send Message to Ejectee
1131 GridInstantMessage msg = new GridInstantMessage(); 1187 GridInstantMessage msg = new GridInstantMessage();
1132 1188
1133 msg.imSessionID = UUID.Zero.Guid; 1189 string ejecteeName = "Unknown member";
1190 // if local send a normal message
1191 if(ejecteeClient != null)
1192 {
1193 msg.imSessionID = UUID.Zero.Guid;
1194 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent;
1195 // also execute and send update
1196 ejecteeClient.SendAgentDropGroup(groupID);
1197 SendAgentGroupDataUpdate(ejecteeClient,true);
1198 ejecteeName = ejecteeClient.Name;
1199 }
1200 else // send
1201 {
1202 // Interop, received special 210 code for ejecting a group member
1203 // this only works within the comms servers domain, and won't work hypergrid
1204 // TODO:FIXME: Use a presence server of some kind to find out where the
1205 // client actually is, and try contacting that region directly to notify them,
1206 // or provide the notification via xmlrpc update queue
1207
1208 msg.imSessionID = groupInfo.GroupID.Guid;
1209 msg.dialog = (byte)210; //interop
1210 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(regionInfo.ScopeID, ejecteeID);
1211 if (account != null)
1212 ejecteeName = account.FirstName + " " + account.LastName;
1213 }
1214
1134 msg.fromAgentID = agentID.Guid; 1215 msg.fromAgentID = agentID.Guid;
1135 // msg.fromAgentID = info.GroupID; 1216 // msg.fromAgentID = info.GroupID;
1136 msg.toAgentID = ejecteeID.Guid; 1217 msg.toAgentID = ejecteeID.Guid;
@@ -1138,7 +1219,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1138 msg.timestamp = 0; 1219 msg.timestamp = 0;
1139 msg.fromAgentName = agentName; 1220 msg.fromAgentName = agentName;
1140 msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName); 1221 msg.message = string.Format("You have been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName);
1141 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent; 1222//
1142 msg.fromGroup = false; 1223 msg.fromGroup = false;
1143 msg.offline = (byte)0; 1224 msg.offline = (byte)0;
1144 msg.ParentEstateID = 0; 1225 msg.ParentEstateID = 0;
@@ -1148,11 +1229,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1148 OutgoingInstantMessage(msg, ejecteeID); 1229 OutgoingInstantMessage(msg, ejecteeID);
1149 1230
1150 // Message to ejector 1231 // Message to ejector
1151 // Interop, received special 210 code for ejecting a group member
1152 // this only works within the comms servers domain, and won't work hypergrid
1153 // TODO:FIXME: Use a presence server of some kind to find out where the
1154 // client actually is, and try contacting that region directly to notify them,
1155 // or provide the notification via xmlrpc update queue
1156 1232
1157 msg = new GridInstantMessage(); 1233 msg = new GridInstantMessage();
1158 msg.imSessionID = UUID.Zero.Guid; 1234 msg.imSessionID = UUID.Zero.Guid;
@@ -1160,15 +1236,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1160 msg.toAgentID = agentID.Guid; 1236 msg.toAgentID = agentID.Guid;
1161 msg.timestamp = 0; 1237 msg.timestamp = 0;
1162 msg.fromAgentName = agentName; 1238 msg.fromAgentName = agentName;
1163 if (account != null) 1239
1164 { 1240 msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, ejecteeName);
1165 msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, account.FirstName + " " + account.LastName); 1241
1166 } 1242// msg.dialog = (byte)210; //interop
1167 else 1243 msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageFromAgent;
1168 {
1169 msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", agentName, groupInfo.GroupName, "Unknown member");
1170 }
1171 msg.dialog = (byte)210; //interop
1172 msg.fromGroup = false; 1244 msg.fromGroup = false;
1173 msg.offline = (byte)0; 1245 msg.offline = (byte)0;
1174 msg.ParentEstateID = 0; 1246 msg.ParentEstateID = 0;
@@ -1176,11 +1248,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1176 msg.RegionID = regionInfo.RegionID.Guid; 1248 msg.RegionID = regionInfo.RegionID.Guid;
1177 msg.binaryBucket = new byte[0]; 1249 msg.binaryBucket = new byte[0];
1178 OutgoingInstantMessage(msg, agentID); 1250 OutgoingInstantMessage(msg, agentID);
1179
1180
1181 // SL sends out messages to everyone in the group
1182 // Who all should receive updates and what should they be updated with?
1183 UpdateAllClientsWithGroupInfo(ejecteeID);
1184 } 1251 }
1185 1252
1186 public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID) 1253 public void InviteGroupRequest(IClientAPI remoteClient, UUID groupID, UUID invitedAgentID, UUID roleID)
@@ -1275,6 +1342,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1275 1342
1276 #region Client/Update Tools 1343 #region Client/Update Tools
1277 1344
1345 private IClientAPI GetActiveRootClient(UUID agentID)
1346 {
1347 foreach (Scene scene in m_sceneList)
1348 {
1349 ScenePresence sp = scene.GetScenePresence(agentID);
1350 if (sp != null && !sp.IsChildAgent && !sp.IsDeleted)
1351 {
1352 return sp.ControllingClient;
1353 }
1354 }
1355 return null;
1356 }
1357
1278 /// <summary> 1358 /// <summary>
1279 /// Try to find an active IClientAPI reference for agentID giving preference to root connections 1359 /// Try to find an active IClientAPI reference for agentID giving preference to root connections
1280 /// </summary> 1360 /// </summary>
@@ -1286,7 +1366,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1286 foreach (Scene scene in m_sceneList) 1366 foreach (Scene scene in m_sceneList)
1287 { 1367 {
1288 ScenePresence sp = scene.GetScenePresence(agentID); 1368 ScenePresence sp = scene.GetScenePresence(agentID);
1289 if (sp != null) 1369 if (sp != null && !sp.IsDeleted)
1290 { 1370 {
1291 if (!sp.IsChildAgent) 1371 if (!sp.IsChildAgent)
1292 { 1372 {
@@ -1303,67 +1383,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1303 return child; 1383 return child;
1304 } 1384 }
1305 1385
1306 /// <summary>
1307 /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'.
1308 /// </summary>
1309 private void SendGroupMembershipInfoViaCaps(IClientAPI remoteClient, UUID dataForAgentID, GroupMembershipData[] data)
1310 {
1311 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1312
1313 OSDArray AgentData = new OSDArray(1);
1314 OSDMap AgentDataMap = new OSDMap(1);
1315 AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
1316 AgentData.Add(AgentDataMap);
1317
1318 OSDArray GroupData = new OSDArray(data.Length);
1319 OSDArray NewGroupData = new OSDArray(data.Length);
1320
1321 foreach (GroupMembershipData membership in data)
1322 {
1323 if (GetRequestingAgentID(remoteClient) != dataForAgentID)
1324 {
1325 if (!membership.ListInProfile)
1326 {
1327 // If we're sending group info to remoteclient about another agent,
1328 // filter out groups the other agent doesn't want to share.
1329 continue;
1330 }
1331 }
1332
1333 OSDMap GroupDataMap = new OSDMap(6);
1334 OSDMap NewGroupDataMap = new OSDMap(1);
1335
1336 GroupDataMap.Add("GroupID", OSD.FromUUID(membership.GroupID));
1337 GroupDataMap.Add("GroupPowers", OSD.FromULong(membership.GroupPowers));
1338 GroupDataMap.Add("AcceptNotices", OSD.FromBoolean(membership.AcceptNotices));
1339 GroupDataMap.Add("GroupInsigniaID", OSD.FromUUID(membership.GroupPicture));
1340 GroupDataMap.Add("Contribution", OSD.FromInteger(membership.Contribution));
1341 GroupDataMap.Add("GroupName", OSD.FromString(membership.GroupName));
1342 NewGroupDataMap.Add("ListInProfile", OSD.FromBoolean(membership.ListInProfile));
1343
1344 GroupData.Add(GroupDataMap);
1345 NewGroupData.Add(NewGroupDataMap);
1346 }
1347
1348 OSDMap llDataStruct = new OSDMap(3);
1349 llDataStruct.Add("AgentData", AgentData);
1350 llDataStruct.Add("GroupData", GroupData);
1351 llDataStruct.Add("NewGroupData", NewGroupData);
1352
1353 if (m_debugEnabled)
1354 {
1355 m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct));
1356 }
1357
1358 IEventQueue queue = remoteClient.Scene.RequestModuleInterface<IEventQueue>();
1359
1360 if (queue != null)
1361 {
1362 queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient));
1363 }
1364
1365 }
1366
1367 private void SendScenePresenceUpdate(UUID AgentID, string Title) 1386 private void SendScenePresenceUpdate(UUID AgentID, string Title)
1368 { 1387 {
1369 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title); 1388 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Updating scene title for {0} with title: {1}", AgentID, Title);
@@ -1380,54 +1399,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1380 presence.Grouptitle = Title; 1399 presence.Grouptitle = Title;
1381 1400
1382 if (! presence.IsChildAgent) 1401 if (! presence.IsChildAgent)
1383 presence.SendAvatarDataToAllClients(); 1402 presence.SendAvatarDataToAllAgents();
1384 } 1403 }
1385 } 1404 }
1386 } 1405 }
1387 } 1406 }
1388 1407
1389 /// <summary> 1408 public void SendAgentGroupDataUpdate(IClientAPI remoteClient)
1390 /// Send updates to all clients who might be interested in groups data for dataForClientID
1391 /// </summary>
1392 private void UpdateAllClientsWithGroupInfo(UUID dataForClientID)
1393 { 1409 {
1394 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1410 SendAgentGroupDataUpdate(remoteClient, true);
1395
1396 // TODO: Probably isn't nessesary to update every client in every scene.
1397 // Need to examine client updates and do only what's nessesary.
1398 lock (m_sceneList)
1399 {
1400 foreach (Scene scene in m_sceneList)
1401 {
1402 scene.ForEachClient(delegate(IClientAPI client) { SendAgentGroupDataUpdate(client, dataForClientID); });
1403 }
1404 }
1405 } 1411 }
1406 1412
1407 /// <summary> 1413 /// <summary>
1408 /// Update remoteClient with group information about dataForAgentID 1414 /// Tell remoteClient about its agent groups, and optionally send title to others
1409 /// </summary> 1415 /// </summary>
1410 private void SendAgentGroupDataUpdate(IClientAPI remoteClient, UUID dataForAgentID) 1416 private void SendAgentGroupDataUpdate(IClientAPI remoteClient, bool tellOthers)
1411 { 1417 {
1412 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name); 1418 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called for {1}", System.Reflection.MethodBase.GetCurrentMethod().Name, remoteClient.Name);
1413 1419
1420 // NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information
1421 // to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything.
1422 if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc)
1423 return;
1424
1414 // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff 1425 // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff
1415 1426
1416 OnAgentDataUpdateRequest(remoteClient, dataForAgentID, UUID.Zero); 1427 UUID agentID = GetRequestingAgentID(remoteClient);
1417 1428
1418 // Need to send a group membership update to the client 1429 SendDataUpdate(remoteClient, tellOthers);
1419 // UDP version doesn't seem to behave nicely. But we're going to send it out here
1420 // with an empty group membership to hopefully remove groups being displayed due
1421 // to the core Groups Stub
1422 remoteClient.SendGroupMembership(new GroupMembershipData[0]);
1423 1430
1424 GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID); 1431 GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, agentID);
1425 SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray); 1432 remoteClient.UpdateGroupMembership(membershipArray);
1426 remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
1427 1433
1428 if (remoteClient.AgentId == dataForAgentID) 1434 remoteClient.SendAgentGroupDataUpdate(agentID, membershipArray);
1429 remoteClient.RefreshGroupMembership(); 1435 }
1430 }
1431 1436
1432 /// <summary> 1437 /// <summary>
1433 /// Get a list of groups memberships for the agent that are marked "ListInProfile" 1438 /// Get a list of groups memberships for the agent that are marked "ListInProfile"
@@ -1465,7 +1470,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1465 membershipArray = membershipData.ToArray(); 1470 membershipArray = membershipData.ToArray();
1466 } 1471 }
1467 } 1472 }
1468 1473
1469 if (m_debugEnabled) 1474 if (m_debugEnabled)
1470 { 1475 {
1471 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); 1476 m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId);
@@ -1478,13 +1483,27 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1478 return membershipArray; 1483 return membershipArray;
1479 } 1484 }
1480 1485
1481 1486 //tell remoteClient about its agent group info, and optionally send title to others
1482 private void SendAgentDataUpdate(IClientAPI remoteClient, UUID dataForAgentID, UUID activeGroupID, string activeGroupName, ulong activeGroupPowers, string activeGroupTitle) 1487 private void SendDataUpdate(IClientAPI remoteClient, bool tellOthers)
1483 { 1488 {
1484 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1489 if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1485 1490
1486 // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff 1491 UUID activeGroupID = UUID.Zero;
1487 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, dataForAgentID); 1492 string activeGroupTitle = string.Empty;
1493 string activeGroupName = string.Empty;
1494 ulong activeGroupPowers = (ulong)GroupPowers.None;
1495
1496 UUID agentID = GetRequestingAgentID(remoteClient);
1497 GroupMembershipData membership = m_groupData.GetAgentActiveMembership(agentID, agentID);
1498 if (membership != null)
1499 {
1500 activeGroupID = membership.GroupID;
1501 activeGroupTitle = membership.GroupTitle;
1502 activeGroupPowers = membership.GroupPowers;
1503 activeGroupName = membership.GroupName;
1504 }
1505
1506 UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, agentID);
1488 string firstname, lastname; 1507 string firstname, lastname;
1489 if (account != null) 1508 if (account != null)
1490 { 1509 {
@@ -1497,9 +1516,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1497 lastname = "Unknown"; 1516 lastname = "Unknown";
1498 } 1517 }
1499 1518
1500 remoteClient.SendAgentDataUpdate(dataForAgentID, activeGroupID, firstname, 1519 remoteClient.SendAgentDataUpdate(agentID, activeGroupID, firstname,
1501 lastname, activeGroupPowers, activeGroupName, 1520 lastname, activeGroupPowers, activeGroupName,
1502 activeGroupTitle); 1521 activeGroupTitle);
1522
1523
1524 if (tellOthers)
1525 SendScenePresenceUpdate(agentID, activeGroupTitle);
1526
1527 ScenePresence sp = (ScenePresence)remoteClient.SceneAgent;
1528 if (sp != null)
1529 sp.Grouptitle = activeGroupTitle;
1503 } 1530 }
1504 1531
1505 #endregion 1532 #endregion
@@ -1510,7 +1537,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1510 { 1537 {
1511 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 1538 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
1512 1539
1513 IClientAPI localClient = GetActiveClient(msgTo); 1540 IClientAPI localClient = GetActiveRootClient(msgTo);
1514 if (localClient != null) 1541 if (localClient != null)
1515 { 1542 {
1516 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name); 1543 if (m_debugEnabled) m_log.InfoFormat("[GROUPS]: MsgTo ({0}) is local, delivering directly", localClient.Name);
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs
index 6b5b40a..08c7096 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
43 /// <returns></returns> 43 /// <returns></returns>
44 /// <param name='RequestingAgentID'>The UUID of the user making the request.</param> 44 /// <param name='RequestingAgentID'>The UUID of the user making the request.</param>
45 /// <param name='GroupID'> 45 /// <param name='GroupID'>
46 /// The ID of the record to retrieve. 46 /// The ID of the record to retrieve.
47 /// GroupName may be specified instead, in which case this parameter will be UUID.Zero 47 /// GroupName may be specified instead, in which case this parameter will be UUID.Zero
48 /// </param> 48 /// </param>
49 /// <param name='GroupName'> 49 /// <param name='GroupName'>
@@ -51,7 +51,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
51 /// GroupID may be specified instead, in which case this parmeter will be null. 51 /// GroupID may be specified instead, in which case this parmeter will be null.
52 /// </param> 52 /// </param>
53 GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); 53 GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName);
54 54 GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID GroupID, UUID AgentID);
55
55 List<DirGroupsReplyData> FindGroups(UUID RequestingAgentID, string search); 56 List<DirGroupsReplyData> FindGroups(UUID RequestingAgentID, string search);
56 List<GroupMembersData> GetGroupMembers(UUID RequestingAgentID, UUID GroupID); 57 List<GroupMembersData> GetGroupMembers(UUID RequestingAgentID, UUID GroupID);
57 58
@@ -88,7 +89,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
88 /// If the user is a member of the group then the data structure is returned. If not, then null is returned. 89 /// If the user is a member of the group then the data structure is returned. If not, then null is returned.
89 /// </returns> 90 /// </returns>
90 GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID); 91 GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID);
91 92
92 /// <summary> 93 /// <summary>
93 /// Get information about the groups to which a user belongs. 94 /// Get information about the groups to which a user belongs.
94 /// </summary> 95 /// </summary>
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
index 1cb4747..98c7ed4 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs
@@ -48,16 +48,16 @@ using OpenSim.Services.Interfaces;
48/*************************************************************************** 48/***************************************************************************
49 * Simian Data Map 49 * Simian Data Map
50 * =============== 50 * ===============
51 * 51 *
52 * OwnerID -> Type -> Key 52 * OwnerID -> Type -> Key
53 * ----------------------- 53 * -----------------------
54 * 54 *
55 * UserID -> Group -> ActiveGroup 55 * UserID -> Group -> ActiveGroup
56 * + GroupID 56 * + GroupID
57 * 57 *
58 * UserID -> GroupSessionDropped -> GroupID 58 * UserID -> GroupSessionDropped -> GroupID
59 * UserID -> GroupSessionInvited -> GroupID 59 * UserID -> GroupSessionInvited -> GroupID
60 * 60 *
61 * UserID -> GroupMember -> GroupID 61 * UserID -> GroupMember -> GroupID
62 * + SelectedRoleID [UUID] 62 * + SelectedRoleID [UUID]
63 * + AcceptNotices [bool] 63 * + AcceptNotices [bool]
@@ -65,9 +65,9 @@ using OpenSim.Services.Interfaces;
65 * + Contribution [int] 65 * + Contribution [int]
66 * 66 *
67 * UserID -> GroupRole[GroupID] -> RoleID 67 * UserID -> GroupRole[GroupID] -> RoleID
68 * 68 *
69 * 69 *
70 * GroupID -> Group -> GroupName 70 * GroupID -> Group -> GroupName
71 * + Charter 71 * + Charter
72 * + ShowInList 72 * + ShowInList
73 * + InsigniaID 73 * + InsigniaID
@@ -79,17 +79,17 @@ using OpenSim.Services.Interfaces;
79 * + EveryonePowers 79 * + EveryonePowers
80 * + OwnerRoleID 80 * + OwnerRoleID
81 * + OwnersPowers 81 * + OwnersPowers
82 * 82 *
83 * GroupID -> GroupRole -> RoleID 83 * GroupID -> GroupRole -> RoleID
84 * + Name 84 * + Name
85 * + Description 85 * + Description
86 * + Title 86 * + Title
87 * + Powers 87 * + Powers
88 * 88 *
89 * GroupID -> GroupMemberInvite -> InviteID 89 * GroupID -> GroupMemberInvite -> InviteID
90 * + AgentID 90 * + AgentID
91 * + RoleID 91 * + RoleID
92 * 92 *
93 * GroupID -> GroupNotice -> NoticeID 93 * GroupID -> GroupNotice -> NoticeID
94 * + TimeStamp [uint] 94 * + TimeStamp [uint]
95 * + FromName [string] 95 * + FromName [string]
@@ -106,12 +106,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
106 { 106 {
107 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 107 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
108 108
109 public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | 109 public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome |
110 GroupPowers.Accountable | 110 GroupPowers.Accountable |
111 GroupPowers.JoinChat | 111 GroupPowers.JoinChat |
112 GroupPowers.AllowVoiceChat | 112 GroupPowers.AllowVoiceChat |
113 GroupPowers.ReceiveNotices | 113 GroupPowers.ReceiveNotices |
114 GroupPowers.StartProposal | 114 GroupPowers.StartProposal |
115 GroupPowers.VoteOnProposal; 115 GroupPowers.VoteOnProposal;
116 116
117 // Would this be cleaner as (GroupPowers)ulong.MaxValue; 117 // Would this be cleaner as (GroupPowers)ulong.MaxValue;
@@ -168,12 +168,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
168 private bool m_debugEnabled = false; 168 private bool m_debugEnabled = false;
169 169
170 private Dictionary<string, bool> m_pendingRequests = new Dictionary<string,bool>(); 170 private Dictionary<string, bool> m_pendingRequests = new Dictionary<string,bool>();
171 171
172 private ExpiringCache<string, OSDMap> m_memoryCache; 172 private ExpiringCache<string, OSDMap> m_memoryCache;
173 private int m_cacheTimeout = 30; 173 private int m_cacheTimeout = 30;
174 174
175 // private IUserAccountService m_accountService = null; 175 // private IUserAccountService m_accountService = null;
176 176
177 177
178 #region Region Module interfaceBase Members 178 #region Region Module interfaceBase Members
179 179
@@ -229,10 +229,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
229 m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Timeout set to {0}.", m_cacheTimeout); 229 m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Timeout set to {0}.", m_cacheTimeout);
230 } 230 }
231 231
232 232
233 233
234 m_memoryCache = new ExpiringCache<string,OSDMap>(); 234 m_memoryCache = new ExpiringCache<string,OSDMap>();
235 235
236 236
237 // If we got all the config options we need, lets start'er'up 237 // If we got all the config options we need, lets start'er'up
238 m_connectorEnabled = true; 238 m_connectorEnabled = true;
@@ -244,7 +244,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
244 244
245 public void Close() 245 public void Close()
246 { 246 {
247 m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Closing {0}", this.Name);
248 } 247 }
249 248
250 public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) 249 public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene)
@@ -288,8 +287,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
288 /// <summary> 287 /// <summary>
289 /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. 288 /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role.
290 /// </summary> 289 /// </summary>
291 public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, 290 public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID,
292 int membershipFee, bool openEnrollment, bool allowPublish, 291 int membershipFee, bool openEnrollment, bool allowPublish,
293 bool maturePublish, UUID founderID) 292 bool maturePublish, UUID founderID)
294 { 293 {
295 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 294 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -314,7 +313,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
314 { 313 {
315 AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); 314 AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers);
316 AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); 315 AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers);
317 316
318 AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); 317 AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID);
319 318
320 return GroupID; 319 return GroupID;
@@ -326,8 +325,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
326 } 325 }
327 326
328 327
329 public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, 328 public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList,
330 UUID insigniaID, int membershipFee, bool openEnrollment, 329 UUID insigniaID, int membershipFee, bool openEnrollment,
331 bool allowPublish, bool maturePublish) 330 bool allowPublish, bool maturePublish)
332 { 331 {
333 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 332 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -351,7 +350,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
351 } 350 }
352 351
353 352
354 public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, 353 public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
355 string title, ulong powers) 354 string title, ulong powers)
356 { 355 {
357 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 356 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -394,7 +393,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
394 } 393 }
395 394
396 395
397 public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, 396 public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description,
398 string title, ulong powers) 397 string title, ulong powers)
399 { 398 {
400 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); 399 if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
@@ -435,7 +434,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
435 { 434 {
436 return null; 435 return null;
437 } 436 }
438 } 437 }
439 else if (!string.IsNullOrEmpty(groupName)) 438 else if (!string.IsNullOrEmpty(groupName))
440 { 439 {
441 if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) 440 if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap))
@@ -482,7 +481,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
482 { 481 {
483 MemberGroupProfile.Charter = groupProfile["Charter"].AsString(); 482 MemberGroupProfile.Charter = groupProfile["Charter"].AsString();
484 } 483 }
485 484
486 MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1"; 485 MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1";
487 MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID(); 486 MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID();
488 MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger(); 487 MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger();
@@ -490,7 +489,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
490 MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean(); 489 MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean();
491 MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean(); 490 MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean();
492 MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();; 491 MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();;
493 MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID(); 492 MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID();
494 493
495 Dictionary<UUID, OSDMap> Members; 494 Dictionary<UUID, OSDMap> Members;
496 if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members)) 495 if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members))
@@ -547,7 +546,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
547 { 546 {
548 GroupMemberInfo = new OSDMap(); 547 GroupMemberInfo = new OSDMap();
549 } 548 }
550 549
551 GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices); 550 GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices);
552 GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile); 551 GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile);
553 GroupMemberInfo["Contribution"] = OSD.FromInteger(0); 552 GroupMemberInfo["Contribution"] = OSD.FromInteger(0);
@@ -625,7 +624,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
625 // Remove Group Member information for this group 624 // Remove Group Member information for this group
626 SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString()); 625 SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString());
627 626
628 // By using a Simian Generics Type consisting of a prefix and a groupID, 627 // By using a Simian Generics Type consisting of a prefix and a groupID,
629 // combined with RoleID as key allows us to get a list of roles a particular member 628 // combined with RoleID as key allows us to get a list of roles a particular member
630 // of a group is assigned to. 629 // of a group is assigned to.
631 string GroupRoleMemberType = "GroupRole" + groupID.ToString(); 630 string GroupRoleMemberType = "GroupRole" + groupID.ToString();
@@ -697,7 +696,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
697 { 696 {
698 data.members = 0; 697 data.members = 0;
699 } 698 }
700 699
701 // TODO: sort results? 700 // TODO: sort results?
702 // data.searchOrder = order; 701 // data.searchOrder = order;
703 702
@@ -722,8 +721,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
722 data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); 721 data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean();
723 data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); 722 data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger();
724 data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); 723 data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean();
725 data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); 724 data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID();
726 725
727 /////////////////////////////// 726 ///////////////////////////////
728 // Agent Specific Information: 727 // Agent Specific Information:
729 // 728 //
@@ -731,7 +730,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
731 if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) 730 if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup))
732 { 731 {
733 data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); 732 data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID);
734 } 733 }
735 734
736 /////////////////////////////// 735 ///////////////////////////////
737 // Role Specific Information: 736 // Role Specific Information:
@@ -741,8 +740,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
741 { 740 {
742 data.GroupTitle = GroupRoleInfo["Title"].AsString(); 741 data.GroupTitle = GroupRoleInfo["Title"].AsString();
743 data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); 742 data.GroupPowers = GroupRoleInfo["Powers"].AsULong();
744 } 743 }
745 744
746 /////////////////////////////// 745 ///////////////////////////////
747 // Group Specific Information: 746 // Group Specific Information:
748 // 747 //
@@ -760,7 +759,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
760 data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); 759 data.MembershipFee = GroupInfo["MembershipFee"].AsInteger();
761 data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); 760 data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean();
762 data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); 761 data.ShowInList = GroupInfo["ShowInList"].AsBoolean();
763 } 762 }
764 } 763 }
765 764
766 return data; 765 return data;
@@ -795,7 +794,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
795 memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key))); 794 memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key)));
796 } 795 }
797 } 796 }
798 797
799 return memberships; 798 return memberships;
800 } 799 }
801 800
@@ -1018,7 +1017,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1018 Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket); 1017 Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket);
1019 1018
1020 SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); 1019 SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice);
1021 1020
1022 } 1021 }
1023 #endregion 1022 #endregion
1024 1023
@@ -1251,7 +1250,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1251 { "OwnerID", ownerID.ToString() }, 1250 { "OwnerID", ownerID.ToString() },
1252 { "Type", type } 1251 { "Type", type }
1253 }; 1252 };
1254 1253
1255 1254
1256 1255
1257 OSDMap response = CachedPostRequest(requestArgs); 1256 OSDMap response = CachedPostRequest(requestArgs);
@@ -1358,7 +1357,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1358 || requestArgs["RequestMethod"] == "AddGeneric") 1357 || requestArgs["RequestMethod"] == "AddGeneric")
1359 { 1358 {
1360 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache"); 1359 m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: clearing generics cache");
1361 1360
1362 // Any and all updates cause the cache to clear 1361 // Any and all updates cause the cache to clear
1363 m_memoryCache.Clear(); 1362 m_memoryCache.Clear();
1364 1363
@@ -1384,14 +1383,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1384 { 1383 {
1385 if (m_memoryCache.TryGetValue(CacheKey, out response)) 1384 if (m_memoryCache.TryGetValue(CacheKey, out response))
1386 return response; 1385 return response;
1387 1386
1388 if (! m_pendingRequests.ContainsKey(CacheKey)) 1387 if (! m_pendingRequests.ContainsKey(CacheKey))
1389 { 1388 {
1390 m_pendingRequests.Add(CacheKey,true); 1389 m_pendingRequests.Add(CacheKey,true);
1391 firstRequest = true; 1390 firstRequest = true;
1392 } 1391 }
1393 } 1392 }
1394 1393
1395 if (firstRequest) 1394 if (firstRequest)
1396 { 1395 {
1397 // if it wasn't in the cache, pass the request to the Simian Grid Services 1396 // if it wasn't in the cache, pass the request to the Simian Grid Services
@@ -1403,7 +1402,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1403 { 1402 {
1404 m_log.ErrorFormat("[SIMIAN GROUPS CONNECTOR]: request failed {0}", CacheKey); 1403 m_log.ErrorFormat("[SIMIAN GROUPS CONNECTOR]: request failed {0}", CacheKey);
1405 } 1404 }
1406 1405
1407 // and cache the response 1406 // and cache the response
1408 lock (m_memoryCache) 1407 lock (m_memoryCache)
1409 { 1408 {
@@ -1421,7 +1420,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1421 // { 1420 // {
1422 // m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache"); 1421 // m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: query not in the cache");
1423 // Util.PrintCallStack(); 1422 // Util.PrintCallStack();
1424 1423
1425 // // if it wasn't in the cache, pass the request to the Simian Grid Services 1424 // // if it wasn't in the cache, pass the request to the Simian Grid Services
1426 // response = WebUtil.PostToService(m_groupsServerURI, requestArgs); 1425 // response = WebUtil.PostToService(m_groupsServerURI, requestArgs);
1427 1426
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
index 9a42bac..ccfcd8b 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/Tests/GroupsModuleTests.cs
@@ -74,14 +74,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
74 [Test] 74 [Test]
75 public void TestSendAgentGroupDataUpdate() 75 public void TestSendAgentGroupDataUpdate()
76 { 76 {
77/* AgentGroupDataUpdate is udp
77 TestHelpers.InMethod(); 78 TestHelpers.InMethod();
78// TestHelpers.EnableLogging(); 79// TestHelpers.EnableLogging();
79 80
80 TestScene scene = new SceneHelpers().SetupScene(); 81 TestScene scene = new SceneHelpers().SetupScene();
81 IConfigSource configSource = new IniConfigSource(); 82 IConfigSource configSource = new IniConfigSource();
82 IConfig config = configSource.AddConfig("Groups"); 83 IConfig config = configSource.AddConfig("Groups");
83 config.Set("Enabled", true); 84 config.Set("Enabled", true);
84 config.Set("Module", "GroupsModule"); 85 config.Set("Module", "GroupsModule");
85 config.Set("DebugEnabled", true); 86 config.Set("DebugEnabled", true);
86 87
87 GroupsModule gm = new GroupsModule(); 88 GroupsModule gm = new GroupsModule();
@@ -98,6 +99,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
98 99
99 Hashtable eventsResponse = eqgm.GetEvents(UUID.Zero, sp.UUID); 100 Hashtable eventsResponse = eqgm.GetEvents(UUID.Zero, sp.UUID);
100 101
102 if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK)
103 {
104 eventsResponse = eqgm.GetEvents(UUID.Zero, sp.UUID);
105 if((int)eventsResponse["int_response_code"] != (int)HttpStatusCode.OK)
106 eventsResponse = eqgm.GetEvents(UUID.Zero, sp.UUID);
107 }
108
101 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK)); 109 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK));
102 110
103// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]); 111// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]);
@@ -116,7 +124,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
116 124
117 Assert.That(foundUpdate, Is.True, "Did not find AgentGroupDataUpdate in response"); 125 Assert.That(foundUpdate, Is.True, "Did not find AgentGroupDataUpdate in response");
118 126
119 // TODO: More checking of more actual event data. 127 // TODO: More checking of more actual event data.
128*/
120 } 129 }
121 130
122 [Test] 131 [Test]
@@ -124,7 +133,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
124 { 133 {
125 TestHelpers.InMethod(); 134 TestHelpers.InMethod();
126// TestHelpers.EnableLogging(); 135// TestHelpers.EnableLogging();
127 136
128 TestScene scene = new SceneHelpers().SetupScene(); 137 TestScene scene = new SceneHelpers().SetupScene();
129 138
130 MessageTransferModule mtm = new MessageTransferModule(); 139 MessageTransferModule mtm = new MessageTransferModule();
@@ -135,12 +144,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups.Tests
135 IConfigSource configSource = new IniConfigSource(); 144 IConfigSource configSource = new IniConfigSource();
136 145
137 { 146 {
138 IConfig config = configSource.AddConfig("Messaging"); 147 IConfig config = configSource.AddConfig("Messaging");
139 config.Set("MessageTransferModule", mtm.Name); 148 config.Set("MessageTransferModule", mtm.Name);
140 } 149 }
141 150
142 { 151 {
143 IConfig config = configSource.AddConfig("Groups"); 152 IConfig config = configSource.AddConfig("Groups");
144 config.Set("Enabled", true); 153 config.Set("Enabled", true);
145 config.Set("Module", gm.Name); 154 config.Set("Module", gm.Name);
146 config.Set("DebugEnabled", true); 155 config.Set("DebugEnabled", true);
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
index 20555e4..fab7e8c 100644
--- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
+++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs
@@ -53,17 +53,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
53 53
54 private bool m_debugEnabled = false; 54 private bool m_debugEnabled = false;
55 55
56 public const GroupPowers DefaultEveryonePowers 56 public const GroupPowers DefaultEveryonePowers
57 = GroupPowers.AllowSetHome 57 = GroupPowers.AllowSetHome
58 | GroupPowers.Accountable 58 | GroupPowers.Accountable
59 | GroupPowers.JoinChat 59 | GroupPowers.JoinChat
60 | GroupPowers.AllowVoiceChat 60 | GroupPowers.AllowVoiceChat
61 | GroupPowers.ReceiveNotices 61 | GroupPowers.ReceiveNotices
62 | GroupPowers.StartProposal 62 | GroupPowers.StartProposal
63 | GroupPowers.VoteOnProposal; 63 | GroupPowers.VoteOnProposal;
64 64
65 // Would this be cleaner as (GroupPowers)ulong.MaxValue? 65 // Would this be cleaner as (GroupPowers)ulong.MaxValue?
66 public const GroupPowers DefaultOwnerPowers 66 public const GroupPowers DefaultOwnerPowers
67 = GroupPowers.Accountable 67 = GroupPowers.Accountable
68 | GroupPowers.AllowEditLand 68 | GroupPowers.AllowEditLand
69 | GroupPowers.AllowFly 69 | GroupPowers.AllowFly
@@ -114,7 +114,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
114 114
115 private string m_groupsServerURI = string.Empty; 115 private string m_groupsServerURI = string.Empty;
116 116
117 private bool m_disableKeepAlive = false; 117 private bool m_disableKeepAlive = true;
118 118
119 private string m_groupReadKey = string.Empty; 119 private string m_groupReadKey = string.Empty;
120 private string m_groupWriteKey = string.Empty; 120 private string m_groupWriteKey = string.Empty;
@@ -174,13 +174,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
174 return; 174 return;
175 } 175 }
176 176
177 m_disableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); 177 m_disableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", true);
178 178
179 m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); 179 m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty);
180 m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); 180 m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty);
181 181
182
183 m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); 182 m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30);
183
184 if (m_cacheTimeout == 0) 184 if (m_cacheTimeout == 0)
185 { 185 {
186 m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Disabled."); 186 m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Disabled.");
@@ -200,7 +200,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
200 200
201 public void Close() 201 public void Close()
202 { 202 {
203 m_log.DebugFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name);
204 } 203 }
205 204
206 public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) 205 public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene)
@@ -383,10 +382,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
383 382
384 GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, AgentID, GroupID); 383 GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, AgentID, GroupID);
385 GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); 384 GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData);
386 385 if(MemberInfo != null)
387 MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; 386 {
388 MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; 387 MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle;
389 388 MemberGroupProfile.PowersMask = MemberInfo.GroupPowers;
389 }
390 return MemberGroupProfile; 390 return MemberGroupProfile;
391 } 391 }
392 392
@@ -666,6 +666,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
666 data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; 666 data.ListInProfile = ((string)membership["ListInProfile"]) == "1";
667 data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); 667 data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]);
668 data.Title = (string)membership["Title"]; 668 data.Title = (string)membership["Title"];
669 if(membership.ContainsKey("OnlineStatus"))
670 data.OnlineStatus = (string)membership["OnlineStatus"];
669 671
670 members.Add(data); 672 members.Add(data);
671 } 673 }
@@ -803,11 +805,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
803 { 805 {
804 if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) 806 if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID))
805 { 807 {
808 if (m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
809 m_groupsAgentsInvitedToChatSession[groupID].Remove(agentID);
810
806 // If not in dropped list, add 811 // If not in dropped list, add
807 if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) 812 if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
808 {
809 m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); 813 m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID);
810 }
811 } 814 }
812 } 815 }
813 816
@@ -818,9 +821,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
818 821
819 // If nessesary, remove from dropped list 822 // If nessesary, remove from dropped list
820 if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) 823 if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID))
821 {
822 m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); 824 m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID);
823 } 825
826 if (!m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID))
827 m_groupsAgentsInvitedToChatSession[groupID].Add(agentID);
824 } 828 }
825 829
826 private void CreateGroupChatSessionTracking(UUID groupID) 830 private void CreateGroupChatSessionTracking(UUID groupID)
@@ -975,35 +979,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
975 979
976 try 980 try
977 { 981 {
978 resp = req.Send(m_groupsServerURI, 10000); 982 resp = req.Send(m_groupsServerURI);
979
980 if ((m_cacheTimeout > 0) && (CacheKey != null))
981 {
982 m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout));
983 }
984 } 983 }
985 catch (Exception e) 984 catch (Exception e)
986 { 985 {
987 m_log.ErrorFormat( 986 m_log.ErrorFormat(
988 "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}", 987 "[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method {0} at {1}: {2}",
989 function, m_groupsServerURI); 988 function, m_groupsServerURI, e.Message);
990
991 m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}{1}", e.Message, e.StackTrace);
992 989
993 foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) 990 if(m_debugEnabled)
994 { 991 {
995 m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", ResponseLine); 992 m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", e.StackTrace);
993
994 foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None))
995 {
996 m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", ResponseLine);
997 }
998
999 foreach (string key in param.Keys)
1000 {
1001 m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", key, param[key].ToString());
1002 }
996 } 1003 }
997 1004
998 foreach (string key in param.Keys) 1005 if ((m_cacheTimeout > 0) && (CacheKey != null))
999 { 1006 {
1000 m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", key, param[key].ToString()); 1007 m_memoryCache.AddOrUpdate(CacheKey, resp, 10.0);
1001 } 1008 }
1002
1003 Hashtable respData = new Hashtable(); 1009 Hashtable respData = new Hashtable();
1004 respData.Add("error", e.ToString()); 1010 respData.Add("error", e.ToString());
1005 return respData; 1011 return respData;
1006 } 1012 }
1013
1014 if ((m_cacheTimeout > 0) && (CacheKey != null))
1015 {
1016 m_memoryCache.AddOrUpdate(CacheKey, resp, 10.0);
1017 }
1007 } 1018 }
1008 1019
1009 if (resp.Value is Hashtable) 1020 if (resp.Value is Hashtable)
@@ -1042,7 +1053,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
1042 private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData) 1053 private void LogRespDataToConsoleError(UUID requestingAgentID, string function, Hashtable param, Hashtable respData)
1043 { 1054 {
1044 m_log.ErrorFormat( 1055 m_log.ErrorFormat(
1045 "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}", 1056 "[XMLRPC-GROUPS-CONNECTOR]: Error when calling {0} for {1} with params {2}. Response params are {3}",
1046 function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData)); 1057 function, requestingAgentID, Util.PrettyFormatToSingleLine(param), Util.PrettyFormatToSingleLine(respData));
1047 } 1058 }
1048 1059
@@ -1134,6 +1145,7 @@ namespace Nwc.XmlRpc
1134 request.ContentType = "text/xml"; 1145 request.ContentType = "text/xml";
1135 request.AllowWriteStreamBuffering = true; 1146 request.AllowWriteStreamBuffering = true;
1136 request.KeepAlive = !_disableKeepAlive; 1147 request.KeepAlive = !_disableKeepAlive;
1148 request.Timeout = 30000;
1137 1149
1138 using (Stream stream = request.GetRequestStream()) 1150 using (Stream stream = request.GetRequestStream())
1139 { 1151 {
@@ -1141,7 +1153,7 @@ namespace Nwc.XmlRpc
1141 { 1153 {
1142 _serializer.Serialize(xml, this); 1154 _serializer.Serialize(xml, this);
1143 xml.Flush(); 1155 xml.Flush();
1144 } 1156 }
1145 } 1157 }
1146 1158
1147 XmlRpcResponse resp; 1159 XmlRpcResponse resp;