diff options
author | Michael Cortez | 2009-08-05 11:15:53 -0700 |
---|---|---|
committer | Michael Cortez | 2009-08-05 11:15:53 -0700 |
commit | 989517725d02d8a2d216e599856eb2625b454e25 (patch) | |
tree | 74f31eac6e685361ff5d469cdc6992158964666f /OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | |
parent | force back the Regions directory, which because it was empty in svn never made (diff) | |
download | opensim-SC-989517725d02d8a2d216e599856eb2625b454e25.zip opensim-SC-989517725d02d8a2d216e599856eb2625b454e25.tar.gz opensim-SC-989517725d02d8a2d216e599856eb2625b454e25.tar.bz2 opensim-SC-989517725d02d8a2d216e599856eb2625b454e25.tar.xz |
Begin refactoring XmlRpcGroups to a more generic Groups module that allows for replaceable Groups Service Connectors.
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs')
-rw-r--r-- | OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | 1007 |
1 files changed, 1007 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs new file mode 100644 index 0000000..03fe109 --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs | |||
@@ -0,0 +1,1007 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using Nwc.XmlRpc; | ||
34 | |||
35 | using log4net; | ||
36 | using Nini.Config; | ||
37 | |||
38 | using OpenMetaverse; | ||
39 | using OpenMetaverse.StructuredData; | ||
40 | |||
41 | using OpenSim.Framework; | ||
42 | using OpenSim.Region.Framework.Interfaces; | ||
43 | |||
44 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | ||
45 | { | ||
46 | public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector | ||
47 | { | ||
48 | private static readonly ILog m_log = | ||
49 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | |||
52 | public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | | ||
53 | GroupPowers.Accountable | | ||
54 | GroupPowers.JoinChat | | ||
55 | GroupPowers.AllowVoiceChat | | ||
56 | GroupPowers.ReceiveNotices | | ||
57 | GroupPowers.StartProposal | | ||
58 | GroupPowers.VoteOnProposal; | ||
59 | |||
60 | private bool m_connectorEnabled = false; | ||
61 | |||
62 | private string m_serviceURL = string.Empty; | ||
63 | |||
64 | private bool m_disableKeepAlive = false; | ||
65 | |||
66 | private string m_groupReadKey = string.Empty; | ||
67 | private string m_groupWriteKey = string.Empty; | ||
68 | |||
69 | |||
70 | #region IRegionModuleBase Members | ||
71 | |||
72 | public string Name | ||
73 | { | ||
74 | get { return "XmlRpcGroupsServicesConnector"; } | ||
75 | } | ||
76 | |||
77 | // this module is not intended to be replaced, but there should only be 1 of them. | ||
78 | public Type ReplacableInterface | ||
79 | { | ||
80 | get { return null; } | ||
81 | } | ||
82 | |||
83 | public void Initialise(IConfigSource config) | ||
84 | { | ||
85 | IConfig groupsConfig = config.Configs["Groups"]; | ||
86 | |||
87 | if (groupsConfig == null) | ||
88 | { | ||
89 | // Do not run this module by default. | ||
90 | return; | ||
91 | } | ||
92 | else | ||
93 | { | ||
94 | // if groups aren't enabled, we're not needed. | ||
95 | // if we're not specified as the connector to use, then we're not wanted | ||
96 | if ( (groupsConfig.GetBoolean("Enabled", false) == false) | ||
97 | || (groupsConfig.GetString("GroupsServicesConnectorModule", "Default") != Name)) | ||
98 | { | ||
99 | m_connectorEnabled = false; | ||
100 | return; | ||
101 | } | ||
102 | |||
103 | m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); | ||
104 | |||
105 | m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); | ||
106 | if ((m_serviceURL == null) || | ||
107 | (m_serviceURL == string.Empty)) | ||
108 | { | ||
109 | m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); | ||
110 | m_connectorEnabled = false; | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | m_disableKeepAlive = groupsConfig.GetBoolean("XmlRpcDisableKeepAlive", false); | ||
115 | |||
116 | m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); | ||
117 | m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); | ||
118 | |||
119 | // If we got all the config options we need, lets start'er'up | ||
120 | m_connectorEnabled = true; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | public void Close() | ||
125 | { | ||
126 | m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); | ||
127 | } | ||
128 | |||
129 | public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) | ||
130 | { | ||
131 | if (m_connectorEnabled) | ||
132 | scene.RegisterModuleInterface<IGroupsServicesConnector>(this); | ||
133 | } | ||
134 | |||
135 | public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) | ||
136 | { | ||
137 | if (scene.RequestModuleInterface<IGroupsServicesConnector>() == this) | ||
138 | scene.UnregisterModuleInterface<IGroupsServicesConnector>(this); | ||
139 | } | ||
140 | |||
141 | public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) | ||
142 | { | ||
143 | // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info | ||
144 | // scene.EventManager.OnNewClient += OnNewClient; | ||
145 | } | ||
146 | |||
147 | #endregion | ||
148 | |||
149 | #region ISharedRegionModule Members | ||
150 | |||
151 | public void PostInitialise() | ||
152 | { | ||
153 | // NoOp | ||
154 | } | ||
155 | |||
156 | #endregion | ||
157 | |||
158 | |||
159 | |||
160 | #region IGroupsServicesConnector Members | ||
161 | |||
162 | /// <summary> | ||
163 | /// 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. | ||
164 | /// </summary> | ||
165 | public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, | ||
166 | int membershipFee, bool openEnrollment, bool allowPublish, | ||
167 | bool maturePublish, UUID founderID) | ||
168 | { | ||
169 | UUID GroupID = UUID.Random(); | ||
170 | UUID OwnerRoleID = UUID.Random(); | ||
171 | |||
172 | Hashtable param = new Hashtable(); | ||
173 | param["GroupID"] = GroupID.ToString(); | ||
174 | param["Name"] = name; | ||
175 | param["Charter"] = charter; | ||
176 | param["ShowInList"] = showInList == true ? 1 : 0; | ||
177 | param["InsigniaID"] = insigniaID.ToString(); | ||
178 | param["MembershipFee"] = 0; | ||
179 | param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; | ||
180 | param["AllowPublish"] = allowPublish == true ? 1 : 0; | ||
181 | param["MaturePublish"] = maturePublish == true ? 1 : 0; | ||
182 | param["FounderID"] = founderID.ToString(); | ||
183 | param["EveryonePowers"] = ((ulong)m_DefaultEveryonePowers).ToString(); | ||
184 | param["OwnerRoleID"] = OwnerRoleID.ToString(); | ||
185 | |||
186 | // Would this be cleaner as (GroupPowers)ulong.MaxValue; | ||
187 | GroupPowers OwnerPowers = GroupPowers.Accountable | ||
188 | | GroupPowers.AllowEditLand | ||
189 | | GroupPowers.AllowFly | ||
190 | | GroupPowers.AllowLandmark | ||
191 | | GroupPowers.AllowRez | ||
192 | | GroupPowers.AllowSetHome | ||
193 | | GroupPowers.AllowVoiceChat | ||
194 | | GroupPowers.AssignMember | ||
195 | | GroupPowers.AssignMemberLimited | ||
196 | | GroupPowers.ChangeActions | ||
197 | | GroupPowers.ChangeIdentity | ||
198 | | GroupPowers.ChangeMedia | ||
199 | | GroupPowers.ChangeOptions | ||
200 | | GroupPowers.CreateRole | ||
201 | | GroupPowers.DeedObject | ||
202 | | GroupPowers.DeleteRole | ||
203 | | GroupPowers.Eject | ||
204 | | GroupPowers.FindPlaces | ||
205 | | GroupPowers.Invite | ||
206 | | GroupPowers.JoinChat | ||
207 | | GroupPowers.LandChangeIdentity | ||
208 | | GroupPowers.LandDeed | ||
209 | | GroupPowers.LandDivideJoin | ||
210 | | GroupPowers.LandEdit | ||
211 | | GroupPowers.LandEjectAndFreeze | ||
212 | | GroupPowers.LandGardening | ||
213 | | GroupPowers.LandManageAllowed | ||
214 | | GroupPowers.LandManageBanned | ||
215 | | GroupPowers.LandManagePasses | ||
216 | | GroupPowers.LandOptions | ||
217 | | GroupPowers.LandRelease | ||
218 | | GroupPowers.LandSetSale | ||
219 | | GroupPowers.ModerateChat | ||
220 | | GroupPowers.ObjectManipulate | ||
221 | | GroupPowers.ObjectSetForSale | ||
222 | | GroupPowers.ReceiveNotices | ||
223 | | GroupPowers.RemoveMember | ||
224 | | GroupPowers.ReturnGroupOwned | ||
225 | | GroupPowers.ReturnGroupSet | ||
226 | | GroupPowers.ReturnNonGroup | ||
227 | | GroupPowers.RoleProperties | ||
228 | | GroupPowers.SendNotices | ||
229 | | GroupPowers.SetLandingPoint | ||
230 | | GroupPowers.StartProposal | ||
231 | | GroupPowers.VoteOnProposal; | ||
232 | param["OwnersPowers"] = ((ulong)OwnerPowers).ToString(); | ||
233 | |||
234 | |||
235 | |||
236 | |||
237 | Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); | ||
238 | |||
239 | if (respData.Contains("error")) | ||
240 | { | ||
241 | // UUID is not nullable | ||
242 | |||
243 | return UUID.Zero; | ||
244 | } | ||
245 | |||
246 | return UUID.Parse((string)respData["GroupID"]); | ||
247 | } | ||
248 | |||
249 | public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, | ||
250 | UUID insigniaID, int membershipFee, bool openEnrollment, | ||
251 | bool allowPublish, bool maturePublish) | ||
252 | { | ||
253 | Hashtable param = new Hashtable(); | ||
254 | param["GroupID"] = groupID.ToString(); | ||
255 | param["Charter"] = charter; | ||
256 | param["ShowInList"] = showInList == true ? 1 : 0; | ||
257 | param["InsigniaID"] = insigniaID.ToString(); | ||
258 | param["MembershipFee"] = membershipFee; | ||
259 | param["OpenEnrollment"] = openEnrollment == true ? 1 : 0; | ||
260 | param["AllowPublish"] = allowPublish == true ? 1 : 0; | ||
261 | param["MaturePublish"] = maturePublish == true ? 1 : 0; | ||
262 | |||
263 | XmlRpcCall(requestID, "groups.updateGroup", param); | ||
264 | } | ||
265 | |||
266 | public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, | ||
267 | string title, ulong powers) | ||
268 | { | ||
269 | Hashtable param = new Hashtable(); | ||
270 | param["GroupID"] = groupID.ToString(); | ||
271 | param["RoleID"] = roleID.ToString(); | ||
272 | param["Name"] = name; | ||
273 | param["Description"] = description; | ||
274 | param["Title"] = title; | ||
275 | param["Powers"] = powers.ToString(); | ||
276 | |||
277 | XmlRpcCall(requestID, "groups.addRoleToGroup", param); | ||
278 | } | ||
279 | |||
280 | public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) | ||
281 | { | ||
282 | Hashtable param = new Hashtable(); | ||
283 | param["GroupID"] = groupID.ToString(); | ||
284 | param["RoleID"] = roleID.ToString(); | ||
285 | |||
286 | XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); | ||
287 | } | ||
288 | |||
289 | public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, | ||
290 | string title, ulong powers) | ||
291 | { | ||
292 | Hashtable param = new Hashtable(); | ||
293 | param["GroupID"] = groupID.ToString(); | ||
294 | param["RoleID"] = roleID.ToString(); | ||
295 | if (name != null) | ||
296 | { | ||
297 | param["Name"] = name; | ||
298 | } | ||
299 | if (description != null) | ||
300 | { | ||
301 | param["Description"] = description; | ||
302 | } | ||
303 | if (title != null) | ||
304 | { | ||
305 | param["Title"] = title; | ||
306 | } | ||
307 | param["Powers"] = powers.ToString(); | ||
308 | |||
309 | XmlRpcCall(requestID, "groups.updateGroupRole", param); | ||
310 | } | ||
311 | |||
312 | public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) | ||
313 | { | ||
314 | Hashtable param = new Hashtable(); | ||
315 | if (GroupID != UUID.Zero) | ||
316 | { | ||
317 | param["GroupID"] = GroupID.ToString(); | ||
318 | } | ||
319 | if ((GroupName != null) && (GroupName != string.Empty)) | ||
320 | { | ||
321 | param["Name"] = GroupName.ToString(); | ||
322 | } | ||
323 | |||
324 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); | ||
325 | |||
326 | if (respData.Contains("error")) | ||
327 | { | ||
328 | return null; | ||
329 | } | ||
330 | |||
331 | return GroupProfileHashtableToGroupRecord(respData); | ||
332 | |||
333 | } | ||
334 | |||
335 | public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) | ||
336 | { | ||
337 | Hashtable param = new Hashtable(); | ||
338 | param["GroupID"] = GroupID.ToString(); | ||
339 | |||
340 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); | ||
341 | |||
342 | if (respData.Contains("error")) | ||
343 | { | ||
344 | // GroupProfileData is not nullable | ||
345 | return new GroupProfileData(); | ||
346 | } | ||
347 | |||
348 | GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); | ||
349 | GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); | ||
350 | |||
351 | MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; | ||
352 | MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; | ||
353 | |||
354 | return MemberGroupProfile; | ||
355 | |||
356 | } | ||
357 | |||
358 | |||
359 | |||
360 | public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) | ||
361 | { | ||
362 | Hashtable param = new Hashtable(); | ||
363 | param["AgentID"] = AgentID.ToString(); | ||
364 | param["GroupID"] = GroupID.ToString(); | ||
365 | |||
366 | XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); | ||
367 | } | ||
368 | |||
369 | public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
370 | { | ||
371 | Hashtable param = new Hashtable(); | ||
372 | param["AgentID"] = AgentID.ToString(); | ||
373 | param["GroupID"] = GroupID.ToString(); | ||
374 | param["SelectedRoleID"] = RoleID.ToString(); | ||
375 | |||
376 | XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); | ||
377 | } | ||
378 | |||
379 | public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) | ||
380 | { | ||
381 | Hashtable param = new Hashtable(); | ||
382 | param["AgentID"] = AgentID.ToString(); | ||
383 | param["GroupID"] = GroupID.ToString(); | ||
384 | param["AcceptNotices"] = AcceptNotices ? "1" : "0"; | ||
385 | param["ListInProfile"] = ListInProfile ? "1" : "0"; | ||
386 | |||
387 | XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); | ||
388 | |||
389 | } | ||
390 | |||
391 | public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) | ||
392 | { | ||
393 | Hashtable param = new Hashtable(); | ||
394 | param["InviteID"] = inviteID.ToString(); | ||
395 | param["AgentID"] = agentID.ToString(); | ||
396 | param["RoleID"] = roleID.ToString(); | ||
397 | param["GroupID"] = groupID.ToString(); | ||
398 | |||
399 | XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); | ||
400 | |||
401 | } | ||
402 | |||
403 | public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) | ||
404 | { | ||
405 | Hashtable param = new Hashtable(); | ||
406 | param["InviteID"] = inviteID.ToString(); | ||
407 | |||
408 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); | ||
409 | |||
410 | if (respData.Contains("error")) | ||
411 | { | ||
412 | return null; | ||
413 | } | ||
414 | |||
415 | GroupInviteInfo inviteInfo = new GroupInviteInfo(); | ||
416 | inviteInfo.InviteID = inviteID; | ||
417 | inviteInfo.GroupID = UUID.Parse((string)respData["GroupID"]); | ||
418 | inviteInfo.RoleID = UUID.Parse((string)respData["RoleID"]); | ||
419 | inviteInfo.AgentID = UUID.Parse((string)respData["AgentID"]); | ||
420 | |||
421 | return inviteInfo; | ||
422 | } | ||
423 | |||
424 | public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) | ||
425 | { | ||
426 | Hashtable param = new Hashtable(); | ||
427 | param["InviteID"] = inviteID.ToString(); | ||
428 | |||
429 | XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); | ||
430 | } | ||
431 | |||
432 | public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
433 | { | ||
434 | Hashtable param = new Hashtable(); | ||
435 | param["AgentID"] = AgentID.ToString(); | ||
436 | param["GroupID"] = GroupID.ToString(); | ||
437 | param["RoleID"] = RoleID.ToString(); | ||
438 | |||
439 | XmlRpcCall(requestID, "groups.addAgentToGroup", param); | ||
440 | } | ||
441 | |||
442 | public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) | ||
443 | { | ||
444 | Hashtable param = new Hashtable(); | ||
445 | param["AgentID"] = AgentID.ToString(); | ||
446 | param["GroupID"] = GroupID.ToString(); | ||
447 | |||
448 | XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); | ||
449 | } | ||
450 | |||
451 | public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
452 | { | ||
453 | Hashtable param = new Hashtable(); | ||
454 | param["AgentID"] = AgentID.ToString(); | ||
455 | param["GroupID"] = GroupID.ToString(); | ||
456 | param["RoleID"] = RoleID.ToString(); | ||
457 | |||
458 | XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); | ||
459 | } | ||
460 | |||
461 | public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) | ||
462 | { | ||
463 | Hashtable param = new Hashtable(); | ||
464 | param["AgentID"] = AgentID.ToString(); | ||
465 | param["GroupID"] = GroupID.ToString(); | ||
466 | param["RoleID"] = RoleID.ToString(); | ||
467 | |||
468 | XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); | ||
469 | } | ||
470 | |||
471 | |||
472 | public List<DirGroupsReplyData> FindGroups(GroupRequestID requestID, string search) | ||
473 | { | ||
474 | Hashtable param = new Hashtable(); | ||
475 | param["Search"] = search; | ||
476 | |||
477 | Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); | ||
478 | |||
479 | List<DirGroupsReplyData> findings = new List<DirGroupsReplyData>(); | ||
480 | |||
481 | if (!respData.Contains("error")) | ||
482 | { | ||
483 | Hashtable results = (Hashtable)respData["results"]; | ||
484 | foreach (Hashtable groupFind in results.Values) | ||
485 | { | ||
486 | DirGroupsReplyData data = new DirGroupsReplyData(); | ||
487 | data.groupID = new UUID((string)groupFind["GroupID"]); ; | ||
488 | data.groupName = (string)groupFind["Name"]; | ||
489 | data.members = int.Parse((string)groupFind["Members"]); | ||
490 | // data.searchOrder = order; | ||
491 | |||
492 | findings.Add(data); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | return findings; | ||
497 | } | ||
498 | |||
499 | public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) | ||
500 | { | ||
501 | Hashtable param = new Hashtable(); | ||
502 | param["AgentID"] = AgentID.ToString(); | ||
503 | param["GroupID"] = GroupID.ToString(); | ||
504 | |||
505 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); | ||
506 | |||
507 | if (respData.Contains("error")) | ||
508 | { | ||
509 | return null; | ||
510 | } | ||
511 | |||
512 | GroupMembershipData data = HashTableToGroupMembershipData(respData); | ||
513 | |||
514 | return data; | ||
515 | } | ||
516 | |||
517 | public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) | ||
518 | { | ||
519 | Hashtable param = new Hashtable(); | ||
520 | param["AgentID"] = AgentID.ToString(); | ||
521 | |||
522 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); | ||
523 | |||
524 | if (respData.Contains("error")) | ||
525 | { | ||
526 | return null; | ||
527 | } | ||
528 | |||
529 | return HashTableToGroupMembershipData(respData); | ||
530 | } | ||
531 | |||
532 | |||
533 | public List<GroupMembershipData> GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) | ||
534 | { | ||
535 | Hashtable param = new Hashtable(); | ||
536 | param["AgentID"] = AgentID.ToString(); | ||
537 | |||
538 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); | ||
539 | |||
540 | List<GroupMembershipData> memberships = new List<GroupMembershipData>(); | ||
541 | |||
542 | if (!respData.Contains("error")) | ||
543 | { | ||
544 | foreach (object membership in respData.Values) | ||
545 | { | ||
546 | memberships.Add(HashTableToGroupMembershipData((Hashtable)membership)); | ||
547 | } | ||
548 | } | ||
549 | |||
550 | return memberships; | ||
551 | } | ||
552 | |||
553 | public List<GroupRolesData> GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) | ||
554 | { | ||
555 | Hashtable param = new Hashtable(); | ||
556 | param["AgentID"] = AgentID.ToString(); | ||
557 | param["GroupID"] = GroupID.ToString(); | ||
558 | |||
559 | Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); | ||
560 | |||
561 | List<GroupRolesData> Roles = new List<GroupRolesData>(); | ||
562 | |||
563 | if (respData.Contains("error")) | ||
564 | { | ||
565 | return Roles; | ||
566 | } | ||
567 | |||
568 | foreach (Hashtable role in respData.Values) | ||
569 | { | ||
570 | GroupRolesData data = new GroupRolesData(); | ||
571 | data.RoleID = new UUID((string)role["RoleID"]); | ||
572 | data.Name = (string)role["Name"]; | ||
573 | data.Description = (string)role["Description"]; | ||
574 | data.Powers = ulong.Parse((string)role["Powers"]); | ||
575 | data.Title = (string)role["Title"]; | ||
576 | |||
577 | Roles.Add(data); | ||
578 | } | ||
579 | |||
580 | return Roles; | ||
581 | |||
582 | |||
583 | } | ||
584 | |||
585 | public List<GroupRolesData> GetGroupRoles(GroupRequestID requestID, UUID GroupID) | ||
586 | { | ||
587 | Hashtable param = new Hashtable(); | ||
588 | param["GroupID"] = GroupID.ToString(); | ||
589 | |||
590 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); | ||
591 | |||
592 | List<GroupRolesData> Roles = new List<GroupRolesData>(); | ||
593 | |||
594 | if (respData.Contains("error")) | ||
595 | { | ||
596 | return Roles; | ||
597 | } | ||
598 | |||
599 | foreach (Hashtable role in respData.Values) | ||
600 | { | ||
601 | GroupRolesData data = new GroupRolesData(); | ||
602 | data.Description = (string)role["Description"]; | ||
603 | data.Members = int.Parse((string)role["Members"]); | ||
604 | data.Name = (string)role["Name"]; | ||
605 | data.Powers = ulong.Parse((string)role["Powers"]); | ||
606 | data.RoleID = new UUID((string)role["RoleID"]); | ||
607 | data.Title = (string)role["Title"]; | ||
608 | |||
609 | Roles.Add(data); | ||
610 | } | ||
611 | |||
612 | return Roles; | ||
613 | |||
614 | } | ||
615 | |||
616 | |||
617 | |||
618 | public List<GroupMembersData> GetGroupMembers(GroupRequestID requestID, UUID GroupID) | ||
619 | { | ||
620 | Hashtable param = new Hashtable(); | ||
621 | param["GroupID"] = GroupID.ToString(); | ||
622 | |||
623 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); | ||
624 | |||
625 | List<GroupMembersData> members = new List<GroupMembersData>(); | ||
626 | |||
627 | if (respData.Contains("error")) | ||
628 | { | ||
629 | return members; | ||
630 | } | ||
631 | |||
632 | foreach (Hashtable membership in respData.Values) | ||
633 | { | ||
634 | GroupMembersData data = new GroupMembersData(); | ||
635 | |||
636 | data.AcceptNotices = ((string)membership["AcceptNotices"]) == "1"; | ||
637 | data.AgentID = new UUID((string)membership["AgentID"]); | ||
638 | data.Contribution = int.Parse((string)membership["Contribution"]); | ||
639 | data.IsOwner = ((string)membership["IsOwner"]) == "1"; | ||
640 | data.ListInProfile = ((string)membership["ListInProfile"]) == "1"; | ||
641 | data.AgentPowers = ulong.Parse((string)membership["AgentPowers"]); | ||
642 | data.Title = (string)membership["Title"]; | ||
643 | |||
644 | members.Add(data); | ||
645 | } | ||
646 | |||
647 | return members; | ||
648 | |||
649 | } | ||
650 | |||
651 | public List<GroupRoleMembersData> GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) | ||
652 | { | ||
653 | Hashtable param = new Hashtable(); | ||
654 | param["GroupID"] = GroupID.ToString(); | ||
655 | |||
656 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); | ||
657 | |||
658 | List<GroupRoleMembersData> members = new List<GroupRoleMembersData>(); | ||
659 | |||
660 | if (!respData.Contains("error")) | ||
661 | { | ||
662 | foreach (Hashtable membership in respData.Values) | ||
663 | { | ||
664 | GroupRoleMembersData data = new GroupRoleMembersData(); | ||
665 | |||
666 | data.MemberID = new UUID((string)membership["AgentID"]); | ||
667 | data.RoleID = new UUID((string)membership["RoleID"]); | ||
668 | |||
669 | members.Add(data); | ||
670 | } | ||
671 | } | ||
672 | return members; | ||
673 | } | ||
674 | |||
675 | public List<GroupNoticeData> GetGroupNotices(GroupRequestID requestID, UUID GroupID) | ||
676 | { | ||
677 | Hashtable param = new Hashtable(); | ||
678 | param["GroupID"] = GroupID.ToString(); | ||
679 | |||
680 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); | ||
681 | |||
682 | List<GroupNoticeData> values = new List<GroupNoticeData>(); | ||
683 | |||
684 | if (!respData.Contains("error")) | ||
685 | { | ||
686 | foreach (Hashtable value in respData.Values) | ||
687 | { | ||
688 | GroupNoticeData data = new GroupNoticeData(); | ||
689 | data.NoticeID = UUID.Parse((string)value["NoticeID"]); | ||
690 | data.Timestamp = uint.Parse((string)value["Timestamp"]); | ||
691 | data.FromName = (string)value["FromName"]; | ||
692 | data.Subject = (string)value["Subject"]; | ||
693 | data.HasAttachment = false; | ||
694 | data.AssetType = 0; | ||
695 | |||
696 | values.Add(data); | ||
697 | } | ||
698 | } | ||
699 | return values; | ||
700 | |||
701 | } | ||
702 | public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) | ||
703 | { | ||
704 | Hashtable param = new Hashtable(); | ||
705 | param["NoticeID"] = noticeID.ToString(); | ||
706 | |||
707 | Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); | ||
708 | |||
709 | |||
710 | if (respData.Contains("error")) | ||
711 | { | ||
712 | return null; | ||
713 | } | ||
714 | |||
715 | GroupNoticeInfo data = new GroupNoticeInfo(); | ||
716 | data.GroupID = UUID.Parse((string)respData["GroupID"]); | ||
717 | data.Message = (string)respData["Message"]; | ||
718 | data.BinaryBucket = Utils.HexStringToBytes((string)respData["BinaryBucket"], true); | ||
719 | data.noticeData.NoticeID = UUID.Parse((string)respData["NoticeID"]); | ||
720 | data.noticeData.Timestamp = uint.Parse((string)respData["Timestamp"]); | ||
721 | data.noticeData.FromName = (string)respData["FromName"]; | ||
722 | data.noticeData.Subject = (string)respData["Subject"]; | ||
723 | data.noticeData.HasAttachment = false; | ||
724 | data.noticeData.AssetType = 0; | ||
725 | |||
726 | if (data.Message == null) | ||
727 | { | ||
728 | data.Message = string.Empty; | ||
729 | } | ||
730 | |||
731 | return data; | ||
732 | } | ||
733 | public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) | ||
734 | { | ||
735 | string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); | ||
736 | |||
737 | Hashtable param = new Hashtable(); | ||
738 | param["GroupID"] = groupID.ToString(); | ||
739 | param["NoticeID"] = noticeID.ToString(); | ||
740 | param["FromName"] = fromName; | ||
741 | param["Subject"] = subject; | ||
742 | param["Message"] = message; | ||
743 | param["BinaryBucket"] = binBucket; | ||
744 | param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); | ||
745 | |||
746 | XmlRpcCall(requestID, "groups.addGroupNotice", param); | ||
747 | } | ||
748 | #endregion | ||
749 | |||
750 | #region XmlRpcHashtableMarshalling | ||
751 | private GroupProfileData GroupProfileHashtableToGroupProfileData(Hashtable groupProfile) | ||
752 | { | ||
753 | GroupProfileData group = new GroupProfileData(); | ||
754 | group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); | ||
755 | group.Name = (string)groupProfile["Name"]; | ||
756 | |||
757 | if (groupProfile["Charter"] != null) | ||
758 | { | ||
759 | group.Charter = (string)groupProfile["Charter"]; | ||
760 | } | ||
761 | |||
762 | group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; | ||
763 | group.InsigniaID = UUID.Parse((string)groupProfile["InsigniaID"]); | ||
764 | group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); | ||
765 | group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; | ||
766 | group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; | ||
767 | group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; | ||
768 | group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); | ||
769 | group.OwnerRole = UUID.Parse((string)groupProfile["OwnerRoleID"]); | ||
770 | |||
771 | group.GroupMembershipCount = int.Parse((string)groupProfile["GroupMembershipCount"]); | ||
772 | group.GroupRolesCount = int.Parse((string)groupProfile["GroupRolesCount"]); | ||
773 | |||
774 | return group; | ||
775 | } | ||
776 | |||
777 | private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) | ||
778 | { | ||
779 | |||
780 | GroupRecord group = new GroupRecord(); | ||
781 | group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); | ||
782 | group.GroupName = groupProfile["Name"].ToString(); | ||
783 | if (groupProfile["Charter"] != null) | ||
784 | { | ||
785 | group.Charter = (string)groupProfile["Charter"]; | ||
786 | } | ||
787 | group.ShowInList = ((string)groupProfile["ShowInList"]) == "1"; | ||
788 | group.GroupPicture = UUID.Parse((string)groupProfile["InsigniaID"]); | ||
789 | group.MembershipFee = int.Parse((string)groupProfile["MembershipFee"]); | ||
790 | group.OpenEnrollment = ((string)groupProfile["OpenEnrollment"]) == "1"; | ||
791 | group.AllowPublish = ((string)groupProfile["AllowPublish"]) == "1"; | ||
792 | group.MaturePublish = ((string)groupProfile["MaturePublish"]) == "1"; | ||
793 | group.FounderID = UUID.Parse((string)groupProfile["FounderID"]); | ||
794 | group.OwnerRoleID = UUID.Parse((string)groupProfile["OwnerRoleID"]); | ||
795 | |||
796 | return group; | ||
797 | } | ||
798 | private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) | ||
799 | { | ||
800 | GroupMembershipData data = new GroupMembershipData(); | ||
801 | data.AcceptNotices = ((string)respData["AcceptNotices"] == "1"); | ||
802 | data.Contribution = int.Parse((string)respData["Contribution"]); | ||
803 | data.ListInProfile = ((string)respData["ListInProfile"] == "1"); | ||
804 | |||
805 | data.ActiveRole = new UUID((string)respData["SelectedRoleID"]); | ||
806 | data.GroupTitle = (string)respData["Title"]; | ||
807 | |||
808 | data.GroupPowers = ulong.Parse((string)respData["GroupPowers"]); | ||
809 | |||
810 | // Is this group the agent's active group | ||
811 | |||
812 | data.GroupID = new UUID((string)respData["GroupID"]); | ||
813 | |||
814 | UUID ActiveGroup = new UUID((string)respData["ActiveGroupID"]); | ||
815 | data.Active = data.GroupID.Equals(ActiveGroup); | ||
816 | |||
817 | data.AllowPublish = ((string)respData["AllowPublish"] == "1"); | ||
818 | if (respData["Charter"] != null) | ||
819 | { | ||
820 | data.Charter = (string)respData["Charter"]; | ||
821 | } | ||
822 | data.FounderID = new UUID((string)respData["FounderID"]); | ||
823 | data.GroupID = new UUID((string)respData["GroupID"]); | ||
824 | data.GroupName = (string)respData["GroupName"]; | ||
825 | data.GroupPicture = new UUID((string)respData["InsigniaID"]); | ||
826 | data.MaturePublish = ((string)respData["MaturePublish"] == "1"); | ||
827 | data.MembershipFee = int.Parse((string)respData["MembershipFee"]); | ||
828 | data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); | ||
829 | data.ShowInList = ((string)respData["ShowInList"] == "1"); | ||
830 | return data; | ||
831 | } | ||
832 | |||
833 | #endregion | ||
834 | |||
835 | /// <summary> | ||
836 | /// Encapsulate the XmlRpc call to standardize security and error handling. | ||
837 | /// </summary> | ||
838 | private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) | ||
839 | { | ||
840 | if (requestID == null) | ||
841 | { | ||
842 | requestID = new GroupRequestID(); | ||
843 | } | ||
844 | param.Add("RequestingAgentID", requestID.AgentID.ToString()); | ||
845 | param.Add("RequestingAgentUserService", requestID.UserServiceURL); | ||
846 | param.Add("RequestingSessionID", requestID.SessionID.ToString()); | ||
847 | |||
848 | |||
849 | param.Add("ReadKey", m_groupReadKey); | ||
850 | param.Add("WriteKey", m_groupWriteKey); | ||
851 | |||
852 | |||
853 | IList parameters = new ArrayList(); | ||
854 | parameters.Add(param); | ||
855 | |||
856 | XmlRpcRequest req; | ||
857 | if (!m_disableKeepAlive) | ||
858 | { | ||
859 | req = new XmlRpcRequest(function, parameters); | ||
860 | } | ||
861 | else | ||
862 | { | ||
863 | // This seems to solve a major problem on some windows servers | ||
864 | req = new NoKeepAliveXmlRpcRequest(function, parameters); | ||
865 | } | ||
866 | |||
867 | XmlRpcResponse resp = null; | ||
868 | |||
869 | try | ||
870 | { | ||
871 | resp = req.Send(m_serviceURL, 10000); | ||
872 | } | ||
873 | catch (Exception e) | ||
874 | { | ||
875 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); | ||
876 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); | ||
877 | |||
878 | |||
879 | foreach (string key in param.Keys) | ||
880 | { | ||
881 | m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); | ||
882 | } | ||
883 | |||
884 | Hashtable respData = new Hashtable(); | ||
885 | respData.Add("error", e.ToString()); | ||
886 | return respData; | ||
887 | } | ||
888 | |||
889 | if (resp.Value is Hashtable) | ||
890 | { | ||
891 | Hashtable respData = (Hashtable)resp.Value; | ||
892 | if (respData.Contains("error") && !respData.Contains("succeed")) | ||
893 | { | ||
894 | LogRespDataToConsoleError(respData); | ||
895 | } | ||
896 | |||
897 | return respData; | ||
898 | } | ||
899 | |||
900 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); | ||
901 | |||
902 | if (resp.Value is ArrayList) | ||
903 | { | ||
904 | ArrayList al = (ArrayList)resp.Value; | ||
905 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); | ||
906 | |||
907 | foreach (object o in al) | ||
908 | { | ||
909 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); | ||
910 | } | ||
911 | } | ||
912 | else | ||
913 | { | ||
914 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); | ||
915 | } | ||
916 | |||
917 | Hashtable error = new Hashtable(); | ||
918 | error.Add("error", "invalid return value"); | ||
919 | return error; | ||
920 | } | ||
921 | |||
922 | private void LogRespDataToConsoleError(Hashtable respData) | ||
923 | { | ||
924 | m_log.Error("[XMLRPCGROUPDATA]: Error:"); | ||
925 | |||
926 | foreach (string key in respData.Keys) | ||
927 | { | ||
928 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); | ||
929 | |||
930 | string[] lines = respData[key].ToString().Split(new char[] { '\n' }); | ||
931 | foreach (string line in lines) | ||
932 | { | ||
933 | m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); | ||
934 | } | ||
935 | |||
936 | } | ||
937 | } | ||
938 | |||
939 | |||
940 | } | ||
941 | |||
942 | public class GroupNoticeInfo | ||
943 | { | ||
944 | public GroupNoticeData noticeData = new GroupNoticeData(); | ||
945 | public UUID GroupID = UUID.Zero; | ||
946 | public string Message = string.Empty; | ||
947 | public byte[] BinaryBucket = new byte[0]; | ||
948 | } | ||
949 | } | ||
950 | |||
951 | namespace Nwc.XmlRpc | ||
952 | { | ||
953 | using System; | ||
954 | using System.Collections; | ||
955 | using System.IO; | ||
956 | using System.Xml; | ||
957 | using System.Net; | ||
958 | using System.Text; | ||
959 | using System.Reflection; | ||
960 | |||
961 | /// <summary>Class supporting the request side of an XML-RPC transaction.</summary> | ||
962 | public class NoKeepAliveXmlRpcRequest : XmlRpcRequest | ||
963 | { | ||
964 | private Encoding _encoding = new ASCIIEncoding(); | ||
965 | private XmlRpcRequestSerializer _serializer = new XmlRpcRequestSerializer(); | ||
966 | private XmlRpcResponseDeserializer _deserializer = new XmlRpcResponseDeserializer(); | ||
967 | |||
968 | /// <summary>Instantiate an <c>XmlRpcRequest</c> for a specified method and parameters.</summary> | ||
969 | /// <param name="methodName"><c>String</c> designating the <i>object.method</i> on the server the request | ||
970 | /// should be directed to.</param> | ||
971 | /// <param name="parameters"><c>ArrayList</c> of XML-RPC type parameters to invoke the request with.</param> | ||
972 | public NoKeepAliveXmlRpcRequest(String methodName, IList parameters) | ||
973 | { | ||
974 | MethodName = methodName; | ||
975 | _params = parameters; | ||
976 | } | ||
977 | |||
978 | /// <summary>Send the request to the server.</summary> | ||
979 | /// <param name="url"><c>String</c> The url of the XML-RPC server.</param> | ||
980 | /// <returns><c>XmlRpcResponse</c> The response generated.</returns> | ||
981 | public XmlRpcResponse Send(String url) | ||
982 | { | ||
983 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); | ||
984 | if (request == null) | ||
985 | throw new XmlRpcException(XmlRpcErrorCodes.TRANSPORT_ERROR, | ||
986 | XmlRpcErrorCodes.TRANSPORT_ERROR_MSG + ": Could not create request with " + url); | ||
987 | request.Method = "POST"; | ||
988 | request.ContentType = "text/xml"; | ||
989 | request.AllowWriteStreamBuffering = true; | ||
990 | request.KeepAlive = false; | ||
991 | |||
992 | Stream stream = request.GetRequestStream(); | ||
993 | XmlTextWriter xml = new XmlTextWriter(stream, _encoding); | ||
994 | _serializer.Serialize(xml, this); | ||
995 | xml.Flush(); | ||
996 | xml.Close(); | ||
997 | |||
998 | HttpWebResponse response = (HttpWebResponse)request.GetResponse(); | ||
999 | StreamReader input = new StreamReader(response.GetResponseStream()); | ||
1000 | |||
1001 | XmlRpcResponse resp = (XmlRpcResponse)_deserializer.Deserialize(input); | ||
1002 | input.Close(); | ||
1003 | response.Close(); | ||
1004 | return resp; | ||
1005 | } | ||
1006 | } | ||
1007 | } | ||