aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Avatar/Currency
diff options
context:
space:
mode:
authorAdam Frisby2008-04-30 21:16:36 +0000
committerAdam Frisby2008-04-30 21:16:36 +0000
commitf5c312bc3c2567449c7268a54a08a54119f58d53 (patch)
tree424668a4bbec6873ebc5b8256f3671db102f5e9c /OpenSim/Region/Environment/Modules/Avatar/Currency
parent* Adds the AuthbuyerID field to sqlite and makes use of it. (diff)
downloadopensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.zip
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.gz
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.bz2
opensim-SC-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.xz
* Refactored Environment/Modules directory - modules now reside in their own directory with any associated module-specific classes.
* Each module directory is currently inside one of the following category folders: Agent (Anything relating to do with Client<->Server communications.), Avatar (Anything to do with the avatar or presence inworld), Framework (Classes modules can use), Grid (Grid traffic, new OGS2 grid comms), Scripting (Scripting functions, etc), World (The enrivonment/scene, IE Sun/Tree modules.) * This should be moved into a seperate project file.
Diffstat (limited to 'OpenSim/Region/Environment/Modules/Avatar/Currency')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs1491
1 files changed, 1491 insertions, 0 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs
new file mode 100644
index 0000000..0e058ec
--- /dev/null
+++ b/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs
@@ -0,0 +1,1491 @@
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 OpenSim 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
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Net.Sockets;
33using System.Reflection;
34using System.Xml;
35using libsecondlife;
36using log4net;
37using Nini.Config;
38using Nwc.XmlRpc;
39using OpenSim.Framework;
40using OpenSim.Region.Environment.Interfaces;
41using OpenSim.Region.Environment.Scenes;
42
43namespace OpenSim.Region.Environment.Modules.Avatar.Currency.SampleMoney
44{
45 /// <summary>
46 /// Demo Economy/Money Module. This is not a production quality money/economy module!
47 /// This is a demo for you to use when making one that works for you.
48 /// // To use the following you need to add:
49 /// -helperuri <ADDRESS TO HERE OR grid MONEY SERVER>
50 /// to the command line parameters you use to start up your client
51 /// This commonly looks like -helperuri http://127.0.0.1:9000/
52 ///
53 /// Centralized grid structure example using OpenSimWi Redux revision 9+
54 /// svn co https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux
55 /// </summary>
56
57 public delegate void ObjectPaid(LLUUID objectID, LLUUID agentID, int amount);
58
59 public interface IMoneyModule : IRegionModule
60 {
61 bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount);
62
63 event ObjectPaid OnObjectPaid;
64 }
65
66 public class SampleMoneyModule : IMoneyModule
67 {
68 public event ObjectPaid OnObjectPaid;
69
70 private ObjectPaid handerOnObjectPaid;
71
72 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
73
74 /// <summary>
75 /// Region UUIDS indexed by AgentID
76 /// </summary>
77 Dictionary<LLUUID, LLUUID> m_rootAgents = new Dictionary<LLUUID, LLUUID>();
78
79 /// <summary>
80 /// Scenes by Region Handle
81 /// </summary>
82 private Dictionary<ulong,Scene> m_scenel = new Dictionary<ulong,Scene>();
83
84 private IConfigSource m_gConfig;
85
86 private bool m_keepMoneyAcrossLogins = true;
87
88 private int m_minFundsBeforeRefresh = 100;
89
90 private int m_stipend = 1000;
91
92 private bool m_enabled = true;
93
94 private Dictionary<LLUUID, int> m_KnownClientFunds = new Dictionary<LLUUID, int>();
95
96 private bool gridmode = false;
97 private Scene XMLRPCHandler;
98 private float EnergyEfficiency = 0f;
99 private int ObjectCapacity = 45000;
100 private int ObjectCount = 0;
101 private int PriceEnergyUnit = 0;
102 private int PriceGroupCreate = 0;
103 private int PriceObjectClaim = 0;
104 private float PriceObjectRent = 0f;
105 private float PriceObjectScaleFactor = 0f;
106 private int PriceParcelClaim = 0;
107 private float PriceParcelClaimFactor = 0f;
108 private int PriceParcelRent = 0;
109 private int PricePublicObjectDecay = 0;
110 private int PricePublicObjectDelete = 0;
111 private int PriceRentLight = 0;
112 private int PriceUpload = 0;
113 private int TeleportMinPrice = 0;
114 private int UserLevelPaysFees = 2;
115 private string m_MoneyAddress = String.Empty;
116 private string m_LandAddress = String.Empty;
117
118 float TeleportPriceExponent = 0f;
119
120 /// <summary>
121 /// Where Stipends come from and Fees go to.
122 /// </summary>
123 LLUUID EconomyBaseAccount = LLUUID.Zero;
124
125 /// <summary>
126 /// Startup
127 /// </summary>
128 /// <param name="scene"></param>
129 /// <param name="config"></param>
130 public void Initialise(Scene scene, IConfigSource config)
131 {
132 m_gConfig = config;
133
134 IConfig startupConfig = m_gConfig.Configs["Startup"];
135 IConfig economyConfig = m_gConfig.Configs["Economy"];
136
137 scene.RegisterModuleInterface<IMoneyModule>(this);
138
139 ReadConfigAndPopulate(scene, startupConfig, "Startup");
140 ReadConfigAndPopulate(scene, economyConfig, "Economy");
141
142 if (m_enabled)
143 {
144 lock (m_scenel)
145 {
146 if (m_scenel.Count == 0)
147 {
148 XMLRPCHandler = scene;
149
150 // To use the following you need to add:
151 // -helperuri <ADDRESS TO HERE OR grid MONEY SERVER>
152 // to the command line parameters you use to start up your client
153 // This commonly looks like -helperuri http://127.0.0.1:9000/
154
155 if (m_MoneyAddress.Length > 0)
156 {
157 // Centralized grid structure using OpenSimWi Redux revision 9+
158 // https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux
159 scene.AddXmlRPCHandler("balanceUpdateRequest", GridMoneyUpdate);
160 scene.AddXmlRPCHandler("userAlert", UserAlert);
161 }
162 else
163 {
164 // Local Server.. enables functionality only.
165 scene.AddXmlRPCHandler("getCurrencyQuote", quote_func);
166 scene.AddXmlRPCHandler("buyCurrency", buy_func);
167 scene.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func);
168 scene.AddXmlRPCHandler("buyLandPrep", landBuy_func);
169 }
170
171
172 }
173
174 if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle))
175 {
176 m_scenel[scene.RegionInfo.RegionHandle] = scene;
177 }
178 else
179 {
180 m_scenel.Add(scene.RegionInfo.RegionHandle, scene);
181 }
182 }
183
184 scene.EventManager.OnNewClient += OnNewClient;
185 scene.EventManager.OnMoneyTransfer += MoneyTransferAction;
186 scene.EventManager.OnClientClosed += ClientClosed;
187 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
188 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
189 scene.EventManager.OnClientClosed += ClientLoggedOut;
190 scene.EventManager.OnValidateLandBuy += ValidateLandBuy;
191 scene.EventManager.OnLandBuy += processLandBuy;
192
193 }
194 }
195 /// <summary>
196 /// Parse Configuration
197 /// </summary>
198 /// <param name="scene"></param>
199 /// <param name="startupConfig"></param>
200 /// <param name="config"></param>
201 private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string config)
202 {
203 if (config == "Startup" && startupConfig != null)
204 {
205 gridmode = startupConfig.GetBoolean("gridmode", false);
206 m_enabled = (startupConfig.GetString("economymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule");
207 }
208
209 if (config == "Economy" && startupConfig != null)
210 {
211 ObjectCapacity = startupConfig.GetInt("ObjectCapacity", 45000);
212 PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100);
213 PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10);
214 PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4);
215 PricePublicObjectDelete = startupConfig.GetInt("PricePublicObjectDelete", 4);
216 PriceParcelClaim = startupConfig.GetInt("PriceParcelClaim", 1);
217 PriceParcelClaimFactor = startupConfig.GetFloat("PriceParcelClaimFactor", 1f);
218 PriceUpload = startupConfig.GetInt("PriceUpload", 0);
219 PriceRentLight = startupConfig.GetInt("PriceRentLight", 5);
220 TeleportMinPrice = startupConfig.GetInt("TeleportMinPrice", 2);
221 TeleportPriceExponent = startupConfig.GetFloat("TeleportPriceExponent", 2f);
222 EnergyEfficiency = startupConfig.GetFloat("EnergyEfficiency", 1);
223 PriceObjectRent = startupConfig.GetFloat("PriceObjectRent", 1);
224 PriceObjectScaleFactor = startupConfig.GetFloat("PriceObjectScaleFactor", 10);
225 PriceParcelRent = startupConfig.GetInt("PriceParcelRent", 1);
226 PriceGroupCreate = startupConfig.GetInt("PriceGroupCreate", -1);
227 string EBA = startupConfig.GetString("EconomyBaseAccount", LLUUID.Zero.ToString());
228 Helpers.TryParse(EBA,out EconomyBaseAccount);
229
230 UserLevelPaysFees = startupConfig.GetInt("UserLevelPaysFees", -1);
231 m_stipend = startupConfig.GetInt("UserStipend", 500);
232 m_minFundsBeforeRefresh = startupConfig.GetInt("IssueStipendWhenClientIsBelowAmount", 10);
233 m_keepMoneyAcrossLogins = startupConfig.GetBoolean("KeepMoneyAcrossLogins", true);
234 m_MoneyAddress = startupConfig.GetString("CurrencyServer", String.Empty);
235 m_LandAddress = startupConfig.GetString("LandServer", String.Empty);
236 }
237
238 // Send ObjectCapacity to Scene.. Which sends it to the SimStatsReporter.
239 scene.SetObjectCapacity(ObjectCapacity);
240 }
241
242 /// <summary>
243 /// New Client Event Handler
244 /// </summary>
245 /// <param name="client"></param>
246 private void OnNewClient(IClientAPI client)
247 {
248 // Here we check if we're in grid mode
249 // I imagine that the 'check balance'
250 // function for the client should be here or shortly after
251
252 if (gridmode)
253 {
254 if (m_MoneyAddress.Length == 0)
255 {
256
257 CheckExistAndRefreshFunds(client.AgentId);
258 }
259 else
260 {
261 bool childYN = true;
262 ScenePresence agent = null;
263 //client.SecureSessionId;
264 Scene s = LocateSceneClientIn(client.AgentId);
265 if (s != null)
266 {
267 agent = s.GetScenePresence(client.AgentId);
268 if (agent != null)
269 childYN = agent.IsChildAgent;
270 }
271 if (s != null && agent != null && childYN == false)
272 {
273 //s.RegionInfo.RegionHandle;
274 LLUUID agentID = LLUUID.Zero;
275 int funds = 0;
276
277 Hashtable hbinfo = GetBalanceForUserFromMoneyServer(client.AgentId, client.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret);
278 if ((bool)hbinfo["success"] == true)
279 {
280
281 Helpers.TryParse((string)hbinfo["agentId"], out agentID);
282 try
283 {
284 funds = (Int32)hbinfo["funds"];
285 }
286 catch (ArgumentException)
287 {
288 }
289 catch (FormatException)
290 {
291 }
292 catch (OverflowException)
293 {
294 m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentID);
295 client.SendAlertMessage("Unable to get your money balance, money operations will be unavailable");
296 }
297 catch (InvalidCastException)
298 {
299 funds = 0;
300 }
301
302 m_KnownClientFunds[agentID] = funds;
303 }
304 else
305 {
306 m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentID, (string)hbinfo["errorMessage"]);
307 client.SendAlertMessage((string)hbinfo["errorMessage"]);
308 }
309 SendMoneyBalance(client, agentID, client.SessionId, LLUUID.Zero);
310
311 }
312 }
313
314 }
315 else
316 {
317 CheckExistAndRefreshFunds(client.AgentId);
318 }
319
320 // Subscribe to Money messages
321 client.OnEconomyDataRequest += EconomyDataRequestHandler;
322 client.OnMoneyBalanceRequest += SendMoneyBalance;
323 client.OnRequestPayPrice += requestPayPrice;
324 client.OnLogout += ClientClosed;
325
326
327 }
328
329 #region event Handlers
330
331 public void requestPayPrice(IClientAPI client, LLUUID objectID)
332 {
333 Scene scene=LocateSceneClientIn(client.AgentId);
334 if(scene == null)
335 return;
336
337 SceneObjectPart task=scene.GetSceneObjectPart(objectID);
338 if(task == null)
339 return;
340 SceneObjectGroup group=task.ParentGroup;
341 SceneObjectPart root=group.RootPart;
342
343 client.SendPayPrice(objectID, root.PayPrice);
344 }
345
346 /// <summary>
347 /// When the client closes the connection we remove their accounting info from memory to free up resources.
348 /// </summary>
349 /// <param name="AgentID"></param>
350 public void ClientClosed(LLUUID AgentID)
351 {
352 lock (m_KnownClientFunds)
353 {
354 if (m_keepMoneyAcrossLogins && m_MoneyAddress.Length == 0)
355 {
356 }
357 else
358 {
359 m_KnownClientFunds.Remove(AgentID);
360 }
361 }
362 }
363
364 /// <summary>
365 /// Event called Economy Data Request handler.
366 /// </summary>
367 /// <param name="agentId"></param>
368 public void EconomyDataRequestHandler(LLUUID agentId)
369 {
370 IClientAPI user = LocateClientObject(agentId);
371
372 if (user != null)
373 {
374 user.SendEconomyData(EnergyEfficiency, ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate,
375 PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor,
376 PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload,
377 TeleportMinPrice, TeleportPriceExponent);
378 }
379 }
380
381 private void ValidateLandBuy (Object osender, EventManager.LandBuyArgs e)
382 {
383 if (m_MoneyAddress.Length == 0)
384 {
385 lock (m_KnownClientFunds)
386 {
387 if (m_KnownClientFunds.ContainsKey(e.agentId))
388 {
389 // Does the sender have enough funds to give?
390 if (m_KnownClientFunds[e.agentId] >= e.parcelPrice)
391 {
392 lock(e)
393 {
394 e.economyValidated=true;
395 }
396 }
397 }
398 }
399 }
400 else
401 {
402 if(GetRemoteBalance(e.agentId) >= e.parcelPrice)
403 {
404 lock(e)
405 {
406 e.economyValidated=true;
407 }
408 }
409 }
410 }
411
412 private void processLandBuy(Object osender, EventManager.LandBuyArgs e)
413 {
414 lock(e)
415 {
416 if(e.economyValidated == true && e.transactionID == 0)
417 {
418 e.transactionID=Util.UnixTimeSinceEpoch();
419
420 if(doMoneyTransfer(e.agentId, e.parcelOwnerID, e.parcelPrice, 0, "Land purchase"))
421 {
422 lock (e)
423 {
424 e.amountDebited = e.parcelPrice;
425 }
426 }
427 }
428 }
429 }
430
431 /// <summary>
432 /// THis method gets called when someone pays someone else as a gift.
433 /// </summary>
434 /// <param name="osender"></param>
435 /// <param name="e"></param>
436 private void MoneyTransferAction (Object osender, EventManager.MoneyTransferArgs e)
437 {
438 IClientAPI sender = null;
439 IClientAPI receiver = null;
440
441 if(m_MoneyAddress.Length > 0) // Handled on server
442 e.description=String.Empty;
443
444 if(e.transactiontype == 5008) // Object gets paid
445 {
446 sender = LocateClientObject(e.sender);
447 if (sender != null)
448 {
449 SceneObjectPart part=findPrim(e.receiver);
450 if(part == null)
451 return;
452
453 string name=resolveAgentName(part.OwnerID);
454 if(name == String.Empty)
455 name="(hippos)";
456
457 receiver = LocateClientObject(part.OwnerID);
458
459 string description=String.Format("Paid {0} via object {1}", name, e.description);
460 bool transactionresult = doMoneyTransfer(e.sender, part.OwnerID, e.amount, e.transactiontype, description);
461
462 if(transactionresult)
463 {
464 ObjectPaid handlerOnObjectPaid = OnObjectPaid;
465 if(handlerOnObjectPaid != null)
466 {
467 handlerOnObjectPaid(e.receiver, e.sender, e.amount);
468 }
469 }
470
471 if (e.sender != e.receiver)
472 {
473 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender));
474 }
475 if(receiver != null)
476 {
477 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(part.OwnerID));
478 }
479 }
480 return;
481 }
482
483 sender = LocateClientObject(e.sender);
484 if (sender != null)
485 {
486 receiver = LocateClientObject(e.receiver);
487
488 bool transactionresult = doMoneyTransfer(e.sender, e.receiver, e.amount, e.transactiontype, e.description);
489
490 if (e.sender != e.receiver)
491 {
492 if (sender != null)
493 {
494 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender));
495 }
496 }
497
498 if (receiver != null)
499 {
500 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.receiver));
501 }
502 }
503 else
504 {
505 m_log.Warn("[MONEY]: Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + e.sender.ToString() + " Receiver: " + e.receiver.ToString() + " Amount: " + e.amount.ToString());
506 }
507 }
508
509 /// <summary>
510 /// Event Handler for when a root agent becomes a child agent
511 /// </summary>
512 /// <param name="avatar"></param>
513 private void MakeChildAgent(ScenePresence avatar)
514 {
515 lock (m_rootAgents)
516 {
517 if (m_rootAgents.ContainsKey(avatar.UUID))
518 {
519 if (m_rootAgents[avatar.UUID] == avatar.Scene.RegionInfo.originRegionID)
520 {
521 m_rootAgents.Remove(avatar.UUID);
522 m_log.Info("[MONEY]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent");
523 }
524
525 }
526 }
527
528 }
529
530 /// <summary>
531 /// Event Handler for when the client logs out.
532 /// </summary>
533 /// <param name="AgentId"></param>
534 private void ClientLoggedOut(LLUUID AgentId)
535 {
536 lock (m_rootAgents)
537 {
538 if (m_rootAgents.ContainsKey(AgentId))
539 {
540 m_rootAgents.Remove(AgentId);
541 //m_log.Info("[MONEY]: Removing " + AgentId + ". Agent logged out.");
542 }
543 }
544 }
545
546 /// <summary>
547 /// Call this when the client disconnects.
548 /// </summary>
549 /// <param name="client"></param>
550 public void ClientClosed(IClientAPI client)
551 {
552 ClientClosed(client.AgentId);
553 }
554
555 /// <summary>
556 /// Event Handler for when an Avatar enters one of the parcels in the simulator.
557 /// </summary>
558 /// <param name="avatar"></param>
559 /// <param name="localLandID"></param>
560 /// <param name="regionID"></param>
561 private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID)
562 {
563 lock (m_rootAgents)
564 {
565 if (m_rootAgents.ContainsKey(avatar.UUID))
566 {
567 if (avatar.Scene.RegionInfo.originRegionID != m_rootAgents[avatar.UUID])
568 {
569 m_rootAgents[avatar.UUID] = avatar.Scene.RegionInfo.originRegionID;
570 //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + ".");
571 // Claim User! my user! Mine mine mine!
572 if (m_MoneyAddress.Length > 0)
573 {
574 Scene RegionItem = GetSceneByUUID(regionID);
575 if (RegionItem != null)
576 {
577 Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret);
578 if ((bool)hresult["success"] == true)
579 {
580 int funds = 0;
581 try
582 {
583 funds = (Int32)hresult["funds"];
584 }
585 catch (InvalidCastException)
586 {
587
588 }
589 SetLocalFundsForAgentID(avatar.UUID, funds);
590 }
591 else
592 {
593 avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true);
594 }
595 }
596 }
597 }
598 }
599 else
600 {
601 lock (m_rootAgents)
602 {
603 m_rootAgents.Add(avatar.UUID, avatar.Scene.RegionInfo.originRegionID);
604 }
605 if (m_MoneyAddress.Length > 0)
606 {
607 Scene RegionItem = GetSceneByUUID(regionID);
608 if (RegionItem != null)
609 {
610 Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret);
611 if ((bool)hresult["success"] == true)
612 {
613 int funds = 0;
614 try
615 {
616 funds = (Int32)hresult["funds"];
617 }
618 catch (InvalidCastException)
619 {
620
621 }
622 SetLocalFundsForAgentID(avatar.UUID, funds);
623 }
624 else
625 {
626 avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true);
627 }
628 }
629 }
630
631 //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + ".");
632 }
633 }
634 //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString());
635 }
636
637 #endregion
638
639 /// <summary>
640 /// Transfer money
641 /// </summary>
642 /// <param name="Sender"></param>
643 /// <param name="Receiver"></param>
644 /// <param name="amount"></param>
645 /// <returns></returns>
646 private bool doMoneyTransfer(LLUUID Sender, LLUUID Receiver, int amount, int transactiontype, string description)
647 {
648 bool result = false;
649 if (amount >= 0)
650 {
651 lock (m_KnownClientFunds)
652 {
653 // If we don't know about the sender, then the sender can't
654 // actually be here and therefore this is likely fraud or outdated.
655 if (m_MoneyAddress.Length == 0)
656 {
657 if (m_KnownClientFunds.ContainsKey(Sender))
658 {
659 // Does the sender have enough funds to give?
660 if (m_KnownClientFunds[Sender] >= amount)
661 {
662 // Subtract the funds from the senders account
663 m_KnownClientFunds[Sender] -= amount;
664
665 // do we know about the receiver?
666 if (!m_KnownClientFunds.ContainsKey(Receiver))
667 {
668 // Make a record for them so they get the updated balance when they login
669 CheckExistAndRefreshFunds(Receiver);
670 }
671 if (m_enabled)
672 {
673 //Add the amount to the Receiver's funds
674 m_KnownClientFunds[Receiver] += amount;
675 result = true;
676 }
677 }
678 else
679 {
680 // These below are redundant to make this clearer to read
681 result = false;
682 }
683 }
684 else
685 {
686 result = false;
687 }
688 }
689 else
690 {
691 result = TransferMoneyonMoneyServer(Sender, Receiver, amount, transactiontype, description);
692 }
693 }
694 }
695 return result;
696 }
697
698 #region Utility Helpers
699 /// <summary>
700 /// Locates a IClientAPI for the client specified
701 /// </summary>
702 /// <param name="AgentID"></param>
703 /// <returns></returns>
704 private IClientAPI LocateClientObject(LLUUID AgentID)
705 {
706 ScenePresence tPresence = null;
707 IClientAPI rclient = null;
708
709 lock (m_scenel)
710 {
711 foreach (Scene _scene in m_scenel.Values)
712 {
713 tPresence = _scene.GetScenePresence(AgentID);
714 if (tPresence != null)
715 {
716 if (!tPresence.IsChildAgent)
717 {
718 rclient = tPresence.ControllingClient;
719 }
720 }
721 if (rclient != null)
722 {
723 return rclient;
724 }
725 }
726
727 }
728 return null;
729 }
730
731 private Scene LocateSceneClientIn(LLUUID AgentId)
732 {
733 lock (m_scenel)
734 {
735 foreach (Scene _scene in m_scenel.Values)
736 {
737 ScenePresence tPresence = _scene.GetScenePresence(AgentId);
738 if (tPresence != null)
739 {
740 if (!tPresence.IsChildAgent)
741 {
742 return _scene;
743 }
744 }
745
746 }
747
748 }
749 return null;
750 }
751
752 /// <summary>
753 /// Utility function Gets a Random scene in the instance. For when which scene exactly you're doing something with doesn't matter
754 /// </summary>
755 /// <returns></returns>
756 public Scene GetRandomScene()
757 {
758 lock (m_scenel)
759 {
760 foreach (Scene rs in m_scenel.Values)
761 return rs;
762 }
763 return null;
764
765 }
766 /// <summary>
767 /// Utility function to get a Scene by RegionID in a module
768 /// </summary>
769 /// <param name="RegionID"></param>
770 /// <returns></returns>
771 public Scene GetSceneByUUID(LLUUID RegionID)
772 {
773 lock (m_scenel)
774 {
775 foreach (Scene rs in m_scenel.Values)
776 {
777 if (rs.RegionInfo.originRegionID == RegionID)
778 {
779 return rs;
780 }
781 }
782 }
783 return null;
784 }
785 #endregion
786
787
788
789 /// <summary>
790 /// Sends the the stored money balance to the client
791 /// </summary>
792 /// <param name="client"></param>
793 /// <param name="agentID"></param>
794 /// <param name="SessionID"></param>
795 /// <param name="TransactionID"></param>
796 public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID)
797 {
798 if (client.AgentId == agentID && client.SessionId == SessionID)
799 {
800 int returnfunds = 0;
801
802 try
803 {
804 returnfunds = GetFundsForAgentID(agentID);
805 }
806 catch (Exception e)
807 {
808 client.SendAlertMessage(e.Message + " ");
809 }
810
811 client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds);
812 }
813 else
814 {
815 client.SendAlertMessage("Unable to send your money balance to you!");
816 }
817 }
818
819 #region local Fund Management
820 /// <summary>
821 /// Ensures that the agent accounting data is set up in this instance.
822 /// </summary>
823 /// <param name="agentID"></param>
824 private void CheckExistAndRefreshFunds(LLUUID agentID)
825 {
826 lock (m_KnownClientFunds)
827 {
828 if (!m_KnownClientFunds.ContainsKey(agentID))
829 {
830 m_KnownClientFunds.Add(agentID, m_stipend);
831 }
832 else
833 {
834 if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh)
835 {
836 m_KnownClientFunds[agentID] = m_stipend;
837 }
838 }
839 }
840 }
841 /// <summary>
842 /// Gets the amount of Funds for an agent
843 /// </summary>
844 /// <param name="AgentID"></param>
845 /// <returns></returns>
846 private int GetFundsForAgentID(LLUUID AgentID)
847 {
848 int returnfunds = 0;
849 lock (m_KnownClientFunds)
850 {
851 if (m_KnownClientFunds.ContainsKey(AgentID))
852 {
853 returnfunds = m_KnownClientFunds[AgentID];
854 }
855 else
856 {
857 //throw new Exception("Unable to get funds.");
858 }
859 }
860 return returnfunds;
861 }
862 private void SetLocalFundsForAgentID(LLUUID AgentID, int amount)
863 {
864 lock (m_KnownClientFunds)
865 {
866 if (m_KnownClientFunds.ContainsKey(AgentID))
867 {
868 m_KnownClientFunds[AgentID] = amount;
869 }
870 else
871 {
872 m_KnownClientFunds.Add(AgentID, amount);
873 }
874 }
875
876 }
877
878 #endregion
879
880 /// <summary>
881 /// Gets the current balance for the user from the Grid Money Server
882 /// </summary>
883 /// <param name="agentId"></param>
884 /// <param name="secureSessionID"></param>
885 /// <param name="regionId"></param>
886 /// <param name="regionSecret"></param>
887 /// <returns></returns>
888 public Hashtable GetBalanceForUserFromMoneyServer(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret)
889 {
890
891 Hashtable MoneyBalanceRequestParams = new Hashtable();
892 MoneyBalanceRequestParams["agentId"] = agentId.ToString();
893 MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString();
894 MoneyBalanceRequestParams["regionId"] = regionId.ToString();
895 MoneyBalanceRequestParams["secret"] = regionSecret;
896 MoneyBalanceRequestParams["currencySecret"] = ""; // per - region/user currency secret gotten from the money system
897
898 Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorUserBalanceRequest");
899
900 return MoneyRespData;
901 }
902
903
904
905 /// <summary>
906 /// Generic XMLRPC client abstraction
907 /// </summary>
908 /// <param name="ReqParams">Hashtable containing parameters to the method</param>
909 /// <param name="method">Method to invoke</param>
910 /// <returns>Hashtable with success=>bool and other values</returns>
911 public Hashtable genericCurrencyXMLRPCRequest(Hashtable ReqParams, string method)
912 {
913 ArrayList SendParams = new ArrayList();
914 SendParams.Add(ReqParams);
915 // Send Request
916 XmlRpcResponse MoneyResp;
917 try
918 {
919 XmlRpcRequest BalanceRequestReq = new XmlRpcRequest(method, SendParams);
920 MoneyResp = BalanceRequestReq.Send(m_MoneyAddress, 30000);
921 }
922 catch (WebException ex)
923 {
924
925 m_log.ErrorFormat(
926 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}",
927 m_MoneyAddress, ex);
928
929 Hashtable ErrorHash = new Hashtable();
930 ErrorHash["success"] = false;
931 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable";
932 ErrorHash["errorURI"] = "";
933
934 return ErrorHash;
935 //throw (ex);
936 }
937 catch (SocketException ex)
938 {
939
940 m_log.ErrorFormat(
941 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}",
942 m_MoneyAddress, ex);
943
944 Hashtable ErrorHash = new Hashtable();
945 ErrorHash["success"] = false;
946 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable";
947 ErrorHash["errorURI"] = "";
948
949 return ErrorHash;
950 //throw (ex);
951 }
952 catch (XmlException ex)
953 {
954 m_log.ErrorFormat(
955 "[MONEY]: Unable to connect to Money Server {0}. Exception {1}",
956 m_MoneyAddress, ex);
957
958 Hashtable ErrorHash = new Hashtable();
959 ErrorHash["success"] = false;
960 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable";
961 ErrorHash["errorURI"] = "";
962
963 return ErrorHash;
964
965 }
966 if (MoneyResp.IsFault)
967 {
968 Hashtable ErrorHash = new Hashtable();
969 ErrorHash["success"] = false;
970 ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable";
971 ErrorHash["errorURI"] = "";
972
973 return ErrorHash;
974
975 }
976 Hashtable MoneyRespData = (Hashtable)MoneyResp.Value;
977
978 return MoneyRespData;
979 }
980 /// <summary>
981 /// This informs the Money Grid Server that the avatar is in this simulator
982 /// </summary>
983 /// <param name="agentId"></param>
984 /// <param name="secureSessionID"></param>
985 /// <param name="regionId"></param>
986 /// <param name="regionSecret"></param>
987 /// <returns></returns>
988 public Hashtable claim_user(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret)
989 {
990
991 Hashtable MoneyBalanceRequestParams = new Hashtable();
992 MoneyBalanceRequestParams["agentId"] = agentId.ToString();
993 MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString();
994 MoneyBalanceRequestParams["regionId"] = regionId.ToString();
995 MoneyBalanceRequestParams["secret"] = regionSecret;
996
997 Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorClaimUserRequest");
998 IClientAPI sendMoneyBal = LocateClientObject(agentId);
999 if (sendMoneyBal != null)
1000 {
1001 SendMoneyBalance(sendMoneyBal, agentId, sendMoneyBal.SessionId, LLUUID.Zero);
1002 }
1003 return MoneyRespData;
1004 }
1005
1006 private SceneObjectPart findPrim(LLUUID objectID)
1007 {
1008 lock (m_scenel)
1009 {
1010 foreach (Scene s in m_scenel.Values)
1011 {
1012 SceneObjectPart part=s.GetSceneObjectPart(objectID);
1013 if(part != null)
1014 {
1015 return part;
1016 }
1017 }
1018 }
1019 return null;
1020 }
1021
1022 private string resolveObjectName(LLUUID objectID)
1023 {
1024 SceneObjectPart part=findPrim(objectID);
1025 if(part != null)
1026 {
1027 return part.Name;
1028 }
1029 return String.Empty;
1030 }
1031
1032 private string resolveAgentName(LLUUID agentID)
1033 {
1034 // try avatar username surname
1035 Scene scene=GetRandomScene();
1036 UserProfileData profile = scene.CommsManager.UserService.GetUserProfile(agentID);
1037 if (profile != null)
1038 {
1039 string avatarname = profile.FirstName + " " + profile.SurName;
1040 return avatarname;
1041 }
1042 return String.Empty;
1043 }
1044
1045 public bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount)
1046 {
1047 string description=String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID));
1048
1049 bool give_result = doMoneyTransfer(fromID, toID, amount, 2, description);
1050
1051 if (m_MoneyAddress.Length == 0)
1052 BalanceUpdate(fromID, toID, give_result, description);
1053
1054 return give_result;
1055
1056
1057 }
1058 private void BalanceUpdate(LLUUID senderID, LLUUID receiverID, bool transactionresult, string description)
1059 {
1060 IClientAPI sender = LocateClientObject(senderID);
1061 IClientAPI receiver = LocateClientObject(receiverID);
1062
1063 if (senderID != receiverID)
1064 {
1065 if (sender != null)
1066 {
1067 sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(senderID));
1068 }
1069
1070 if (receiver != null)
1071 {
1072 receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(receiverID));
1073 }
1074 }
1075 }
1076
1077 /// <summary>
1078 /// Informs the Money Grid Server of a transfer.
1079 /// </summary>
1080 /// <param name="sourceId"></param>
1081 /// <param name="destId"></param>
1082 /// <param name="amount"></param>
1083 /// <returns></returns>
1084 public bool TransferMoneyonMoneyServer(LLUUID sourceId, LLUUID destId, int amount, int transactiontype, string description)
1085 {
1086 int aggregatePermInventory = 0;
1087 int aggregatePermNextOwner = 0;
1088 int flags = 0;
1089 bool rvalue = false;
1090
1091 IClientAPI cli = LocateClientObject(sourceId);
1092 if (cli != null)
1093 {
1094
1095 Scene userScene = null;
1096 lock (m_rootAgents)
1097 {
1098 userScene = GetSceneByUUID(m_rootAgents[sourceId]);
1099 }
1100 if (userScene != null)
1101 {
1102 Hashtable ht = new Hashtable();
1103 ht["agentId"] = sourceId.ToString();
1104 ht["secureSessionId"] = cli.SecureSessionId.ToString();
1105 ht["regionId"] = userScene.RegionInfo.originRegionID.ToString();
1106 ht["secret"] = userScene.RegionInfo.regionSecret;
1107 ht["currencySecret"] = " ";
1108 ht["destId"] = destId.ToString();
1109 ht["cash"] = amount;
1110 ht["aggregatePermInventory"] = aggregatePermInventory;
1111 ht["aggregatePermNextOwner"] = aggregatePermNextOwner;
1112 ht["flags"] = flags;
1113 ht["transactionType"] = transactiontype;
1114 ht["description"] = description;
1115
1116 Hashtable hresult = genericCurrencyXMLRPCRequest(ht, "regionMoveMoney");
1117
1118 if ((bool)hresult["success"] == true)
1119 {
1120 int funds1 = 0;
1121 int funds2 = 0;
1122 try
1123 {
1124 funds1 = (Int32)hresult["funds"];
1125 }
1126 catch(InvalidCastException)
1127 {
1128 funds1 = 0;
1129 }
1130 SetLocalFundsForAgentID(sourceId, funds1);
1131 if (m_KnownClientFunds.ContainsKey(destId))
1132 {
1133 try
1134 {
1135 funds2 = (Int32)hresult["funds2"];
1136 }
1137 catch (InvalidCastException)
1138 {
1139 funds2 = 0;
1140 }
1141 SetLocalFundsForAgentID(destId, funds2);
1142 }
1143
1144
1145 rvalue = true;
1146 }
1147 else
1148 {
1149 cli.SendAgentAlertMessage((string)hresult["errorMessage"], true);
1150 }
1151
1152 }
1153 }
1154 else
1155 {
1156 m_log.ErrorFormat("[MONEY]: Client {0} not found", sourceId.ToString());
1157 }
1158
1159 return rvalue;
1160
1161 }
1162
1163 public int GetRemoteBalance(LLUUID agentId)
1164 {
1165 int funds = 0;
1166
1167 IClientAPI aClient = LocateClientObject(agentId);
1168 if (aClient != null)
1169 {
1170 Scene s = LocateSceneClientIn(agentId);
1171 if (s != null)
1172 {
1173 if (m_MoneyAddress.Length > 0)
1174 {
1175 Hashtable hbinfo = GetBalanceForUserFromMoneyServer(aClient.AgentId, aClient.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret);
1176 if ((bool)hbinfo["success"] == true)
1177 {
1178 try
1179 {
1180 funds = (Int32)hbinfo["funds"];
1181 }
1182 catch (ArgumentException)
1183 {
1184 }
1185 catch (FormatException)
1186 {
1187 }
1188 catch (OverflowException)
1189 {
1190 m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentId);
1191 aClient.SendAlertMessage("Unable to get your money balance, money operations will be unavailable");
1192 }
1193 catch (InvalidCastException)
1194 {
1195 funds = 0;
1196 }
1197
1198 }
1199 else
1200 {
1201 m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentId, (string)hbinfo["errorMessage"]);
1202 aClient.SendAlertMessage((string)hbinfo["errorMessage"]);
1203 }
1204 }
1205
1206 SetLocalFundsForAgentID(agentId, funds);
1207 SendMoneyBalance(aClient, agentId, aClient.SessionId, LLUUID.Zero);
1208 }
1209 else
1210 {
1211 m_log.Debug("[MONEY]: Got balance request update for agent that is here, but couldn't find which scene.");
1212 }
1213 }
1214 else
1215 {
1216 m_log.Debug("[MONEY]: Got balance request update for agent that isn't here.");
1217 }
1218 return funds;
1219 }
1220
1221 public XmlRpcResponse GridMoneyUpdate(XmlRpcRequest request)
1222 {
1223 m_log.Debug("[MONEY]: Dynamic balance update called.");
1224 Hashtable requestData = (Hashtable)request.Params[0];
1225
1226 if (requestData.ContainsKey("agentId"))
1227 {
1228 LLUUID agentId = LLUUID.Zero;
1229
1230 Helpers.TryParse((string)requestData["agentId"], out agentId);
1231 if (agentId != LLUUID.Zero)
1232 {
1233 GetRemoteBalance(agentId);
1234
1235 }
1236 else
1237 {
1238 m_log.Debug("[MONEY]: invalid agentId specified, dropping.");
1239 }
1240 }
1241 else
1242 {
1243 m_log.Debug("[MONEY]: no agentId specified, dropping.");
1244 }
1245 XmlRpcResponse r = new XmlRpcResponse();
1246 Hashtable rparms = new Hashtable();
1247 rparms["success"] = true;
1248
1249 r.Value = rparms;
1250 return r;
1251 }
1252
1253 /// <summary>
1254 /// XMLRPC handler to send alert message and sound to client
1255 /// </summary>
1256 public XmlRpcResponse UserAlert(XmlRpcRequest request)
1257 {
1258 XmlRpcResponse ret = new XmlRpcResponse();
1259 Hashtable retparam = new Hashtable();
1260 Hashtable requestData = (Hashtable)request.Params[0];
1261
1262 LLUUID agentId = LLUUID.Zero;
1263 LLUUID soundId = LLUUID.Zero;
1264
1265 Helpers.TryParse((string)requestData["agentId"], out agentId);
1266 Helpers.TryParse((string)requestData["soundId"], out soundId);
1267 string text=(string)requestData["text"];
1268 string secret=(string)requestData["secret"];
1269
1270 Scene userScene = GetRandomScene();
1271 if(userScene.RegionInfo.regionSecret.ToString() == secret)
1272 {
1273 IClientAPI client = LocateClientObject(agentId);
1274
1275 if (client != null)
1276 {
1277 if(soundId != LLUUID.Zero)
1278 client.SendPlayAttachedSound(soundId, LLUUID.Zero, LLUUID.Zero, 1.0f, 0);
1279 client.SendBlueBoxMessage(LLUUID.Zero, LLUUID.Zero, "", text);
1280 retparam.Add("success", true);
1281 }
1282 else
1283 {
1284 retparam.Add("success", false);
1285 }
1286 }
1287 else
1288 {
1289 retparam.Add("success", false);
1290 }
1291 ret.Value = retparam;
1292
1293 return ret;
1294 }
1295
1296
1297 # region Standalone box enablers only
1298
1299 public XmlRpcResponse quote_func(XmlRpcRequest request)
1300 {
1301 Hashtable requestData = (Hashtable)request.Params[0];
1302 LLUUID agentId = LLUUID.Zero;
1303 int amount = 0;
1304 Hashtable quoteResponse = new Hashtable();
1305 XmlRpcResponse returnval = new XmlRpcResponse();
1306
1307 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy"))
1308 {
1309 Helpers.TryParse((string)requestData["agentId"], out agentId);
1310 try
1311 {
1312 amount = (Int32)requestData["currencyBuy"];
1313 }
1314 catch (InvalidCastException)
1315 {
1316
1317 }
1318 Hashtable currencyResponse = new Hashtable();
1319 currencyResponse.Add("estimatedCost", 0);
1320 currencyResponse.Add("currencyBuy", amount);
1321
1322 quoteResponse.Add("success", true);
1323 quoteResponse.Add("currency", currencyResponse);
1324 quoteResponse.Add("confirm", "asdfad9fj39ma9fj");
1325
1326 returnval.Value = quoteResponse;
1327 return returnval;
1328 }
1329
1330
1331
1332 quoteResponse.Add("success", false);
1333 quoteResponse.Add("errorMessage", "Invalid parameters passed to the quote box");
1334 quoteResponse.Add("errorURI", "http://www.opensimulator.org/wiki");
1335 returnval.Value = quoteResponse;
1336 return returnval;
1337 }
1338 public XmlRpcResponse buy_func(XmlRpcRequest request)
1339 {
1340
1341 Hashtable requestData = (Hashtable)request.Params[0];
1342 LLUUID agentId = LLUUID.Zero;
1343 int amount = 0;
1344 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy"))
1345 {
1346 Helpers.TryParse((string)requestData["agentId"], out agentId);
1347 try
1348 {
1349 amount = (Int32)requestData["currencyBuy"];
1350 }
1351 catch (InvalidCastException)
1352 {
1353
1354 }
1355 if (agentId != LLUUID.Zero)
1356 {
1357 lock (m_KnownClientFunds)
1358 {
1359 if (m_KnownClientFunds.ContainsKey(agentId))
1360 {
1361 m_KnownClientFunds[agentId] += amount;
1362 }
1363 else
1364 {
1365 m_KnownClientFunds.Add(agentId, amount);
1366 }
1367 }
1368 IClientAPI client = LocateClientObject(agentId);
1369 if (client != null)
1370 {
1371 SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero);
1372 }
1373 }
1374 }
1375 XmlRpcResponse returnval = new XmlRpcResponse();
1376 Hashtable returnresp = new Hashtable();
1377 returnresp.Add("success", true);
1378 returnval.Value = returnresp;
1379 return returnval;
1380 }
1381
1382 public XmlRpcResponse preflightBuyLandPrep_func(XmlRpcRequest request)
1383 {
1384 XmlRpcResponse ret = new XmlRpcResponse();
1385 Hashtable retparam = new Hashtable();
1386 Hashtable membershiplevels = new Hashtable();
1387 ArrayList levels = new ArrayList();
1388 Hashtable level = new Hashtable();
1389 level.Add("id", "00000000-0000-0000-0000-000000000000");
1390 level.Add("description", "some level");
1391 levels.Add(level);
1392 //membershiplevels.Add("levels",levels);
1393
1394 Hashtable landuse = new Hashtable();
1395 landuse.Add("upgrade", false);
1396 landuse.Add("action", "http://invaliddomaininvalid.com/");
1397
1398 Hashtable currency = new Hashtable();
1399 currency.Add("estimatedCost", 0);
1400
1401 Hashtable membership = new Hashtable();
1402 membershiplevels.Add("upgrade", false);
1403 membershiplevels.Add("action", "http://invaliddomaininvalid.com/");
1404 membershiplevels.Add("levels", membershiplevels);
1405
1406 retparam.Add("success", true);
1407 retparam.Add("currency", currency);
1408 retparam.Add("membership", membership);
1409 retparam.Add("landuse", landuse);
1410 retparam.Add("confirm", "asdfajsdkfjasdkfjalsdfjasdf");
1411
1412 ret.Value = retparam;
1413
1414 return ret;
1415
1416 }
1417 public XmlRpcResponse landBuy_func(XmlRpcRequest request)
1418 {
1419 XmlRpcResponse ret = new XmlRpcResponse();
1420 Hashtable retparam = new Hashtable();
1421 Hashtable requestData = (Hashtable)request.Params[0];
1422
1423 LLUUID agentId = LLUUID.Zero;
1424 int amount = 0;
1425 if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy"))
1426 {
1427 Helpers.TryParse((string)requestData["agentId"], out agentId);
1428 try
1429 {
1430 amount = (Int32)requestData["currencyBuy"];
1431 }
1432 catch (InvalidCastException)
1433 {
1434
1435 }
1436 if (agentId != LLUUID.Zero)
1437 {
1438 lock (m_KnownClientFunds)
1439 {
1440 if (m_KnownClientFunds.ContainsKey(agentId))
1441 {
1442 m_KnownClientFunds[agentId] += amount;
1443 }
1444 else
1445 {
1446 m_KnownClientFunds.Add(agentId, amount);
1447 }
1448 }
1449 IClientAPI client = LocateClientObject(agentId);
1450 if (client != null)
1451 {
1452 SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero);
1453 }
1454 }
1455 }
1456 retparam.Add("success", true);
1457 ret.Value = retparam;
1458
1459 return ret;
1460
1461 }
1462 #endregion
1463
1464 public void PostInitialise()
1465 {
1466 }
1467
1468 public void Close()
1469 {
1470 }
1471
1472 public string Name
1473 {
1474 get { return "BetaGridLikeMoneyModule"; }
1475 }
1476
1477 public bool IsSharedModule
1478 {
1479 get { return true; }
1480 }
1481 }
1482
1483 public enum TransactionType : int
1484 {
1485 SystemGenerated=0,
1486 RegionMoneyRequest=1,
1487 Gift=2,
1488 Purchase=3
1489
1490 }
1491} \ No newline at end of file