319 lines
11 KiB
C#
319 lines
11 KiB
C#
/*
|
|
* Copyright (c) Contributors, http://opensimulator.org/
|
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the OpenSim Project nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
using Nini.Config;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using OpenSim.Framework;
|
|
using OpenSim.Framework.Console;
|
|
using OpenSim.Region.Environment.Interfaces;
|
|
using OpenSim.Region.Environment.Scenes;
|
|
using libsecondlife;
|
|
using MoneyTransferArgs = OpenSim.Region.Environment.Scenes.EventManager.MoneyTransferArgs;
|
|
|
|
namespace OpenSim.Region.Environment.Modules
|
|
{
|
|
public class BetaGridLikeMoneyModule: IRegionModule
|
|
{
|
|
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
private Dictionary<ulong,Scene> m_scenel = new Dictionary<ulong,Scene>();
|
|
|
|
private IConfigSource m_gConfig;
|
|
|
|
private bool m_keepMoneyAcrossLogins = true;
|
|
|
|
private int m_minFundsBeforeRefresh = 100;
|
|
|
|
private int m_stipend = 1000;
|
|
|
|
private bool m_enabled = true;
|
|
|
|
|
|
|
|
private Dictionary<LLUUID, int> m_KnownClientFunds = new Dictionary<LLUUID, int>();
|
|
|
|
|
|
|
|
private bool gridmode = false;
|
|
|
|
public void Initialise(Scene scene, IConfigSource config)
|
|
{
|
|
m_gConfig = config;
|
|
ReadConfigAndPopulate();
|
|
|
|
if (m_enabled)
|
|
{
|
|
lock (m_scenel)
|
|
{
|
|
|
|
if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle))
|
|
{
|
|
m_scenel[scene.RegionInfo.RegionHandle] = scene;
|
|
}
|
|
else
|
|
{
|
|
m_scenel.Add(scene.RegionInfo.RegionHandle, scene);
|
|
}
|
|
}
|
|
|
|
scene.EventManager.OnNewClient += OnNewClient;
|
|
scene.EventManager.OnMoneyTransfer += MoneyTransferAction;
|
|
scene.EventManager.OnClientClosed += ClientClosed;
|
|
}
|
|
}
|
|
private void ReadConfigAndPopulate()
|
|
{
|
|
IConfig startupConfig = m_gConfig.Configs["Startup"];
|
|
gridmode = startupConfig.GetBoolean("gridmode", false);
|
|
m_enabled = (startupConfig.GetString("moneymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule");
|
|
|
|
}
|
|
|
|
private void OnNewClient(IClientAPI client)
|
|
{
|
|
// Here we check if we're in grid mode
|
|
// I imagine that the 'check balance'
|
|
// function for the client should be here or shortly after
|
|
|
|
if (gridmode)
|
|
{
|
|
CheckExistAndRefreshFunds(client.AgentId);
|
|
}
|
|
else
|
|
{
|
|
CheckExistAndRefreshFunds(client.AgentId);
|
|
}
|
|
|
|
// Subscribe to Money messages
|
|
client.OnMoneyBalanceRequest += SendMoneyBalance;
|
|
client.OnLogout += ClientClosed;
|
|
|
|
}
|
|
|
|
public void ClientClosed(LLUUID AgentID)
|
|
{
|
|
lock (m_KnownClientFunds)
|
|
{
|
|
if (!m_keepMoneyAcrossLogins)
|
|
m_KnownClientFunds.Remove(AgentID);
|
|
}
|
|
|
|
}
|
|
|
|
private void MoneyTransferAction (Object osender, MoneyTransferArgs e)
|
|
{
|
|
IClientAPI sender = null;
|
|
IClientAPI receiver = null;
|
|
|
|
sender = LocateClientObject(e.sender);
|
|
if (sender != null)
|
|
{
|
|
|
|
|
|
receiver = LocateClientObject(e.reciever);
|
|
bool transactionresult = doMoneyTranfer(e.sender, e.reciever, e.amount);
|
|
|
|
if (e.sender != e.reciever)
|
|
{
|
|
if (sender != null)
|
|
{
|
|
sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender));
|
|
}
|
|
}
|
|
|
|
if (receiver != null)
|
|
{
|
|
receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.reciever));
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
m_log.Warn("[MONEY]: Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + e.sender.ToString() + " Reciver: " + e.reciever.ToString() + " Amount: " + e.amount.ToString());
|
|
}
|
|
}
|
|
|
|
private bool doMoneyTranfer(LLUUID Sender, LLUUID Receiver, int amount)
|
|
{
|
|
bool result = false;
|
|
if (amount >= 0)
|
|
{
|
|
lock (m_KnownClientFunds)
|
|
{
|
|
// If we don't know about the sender, then the sender can't
|
|
// actually be here and therefore this is likely fraud or outdated.
|
|
if (m_KnownClientFunds.ContainsKey(Sender))
|
|
{
|
|
// Does the sender have enough funds to give?
|
|
if (m_KnownClientFunds[Sender] >= amount)
|
|
{
|
|
// Subtract the funds from the senders account
|
|
m_KnownClientFunds[Sender] -= amount;
|
|
|
|
// do we know about the receiver?
|
|
if (!m_KnownClientFunds.ContainsKey(Receiver))
|
|
{
|
|
// Make a record for them so they get the updated balance when they login
|
|
CheckExistAndRefreshFunds(Receiver);
|
|
}
|
|
|
|
//Add the amount to the Receiver's funds
|
|
m_KnownClientFunds[Receiver] += amount;
|
|
result = true;
|
|
}
|
|
else
|
|
{
|
|
// These below are redundant to make this clearer to read
|
|
result = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
result = false;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private IClientAPI LocateClientObject(LLUUID AgentID)
|
|
{
|
|
ScenePresence tPresence = null;
|
|
IClientAPI rclient = null;
|
|
|
|
lock (m_scenel)
|
|
{
|
|
foreach (Scene _scene in m_scenel.Values)
|
|
{
|
|
tPresence = _scene.GetScenePresence(AgentID);
|
|
if (tPresence != null)
|
|
{
|
|
if (!tPresence.IsChildAgent)
|
|
{
|
|
rclient = tPresence.ControllingClient;
|
|
}
|
|
}
|
|
if (rclient != null)
|
|
{
|
|
return rclient;
|
|
}
|
|
}
|
|
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void ClientClosed(IClientAPI client)
|
|
{
|
|
ClientClosed(client.AgentId);
|
|
}
|
|
|
|
public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID)
|
|
{
|
|
if (client.AgentId == agentID && client.SessionId == SessionID)
|
|
{
|
|
|
|
int returnfunds = 0;
|
|
|
|
try
|
|
{
|
|
returnfunds = GetFundsForAgentID(agentID);
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
client.SendAlertMessage(e.Message + " ");
|
|
}
|
|
|
|
client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds);
|
|
}
|
|
else
|
|
{
|
|
client.SendAlertMessage("Unable to send your money balance to you!");
|
|
}
|
|
}
|
|
|
|
private void CheckExistAndRefreshFunds(LLUUID agentID)
|
|
{
|
|
lock (m_KnownClientFunds)
|
|
{
|
|
if (!m_KnownClientFunds.ContainsKey(agentID))
|
|
{
|
|
m_KnownClientFunds.Add(agentID, m_stipend);
|
|
}
|
|
else
|
|
{
|
|
if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh)
|
|
{
|
|
m_KnownClientFunds[agentID] = m_stipend;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private int GetFundsForAgentID(LLUUID AgentID)
|
|
{
|
|
int returnfunds = 0;
|
|
lock (m_KnownClientFunds)
|
|
{
|
|
if (m_KnownClientFunds.ContainsKey(AgentID))
|
|
{
|
|
returnfunds = m_KnownClientFunds[AgentID];
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Unable to get funds.");
|
|
}
|
|
}
|
|
return returnfunds;
|
|
}
|
|
|
|
public void PostInitialise()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
public void Close()
|
|
{
|
|
}
|
|
|
|
public string Name
|
|
{
|
|
get { return "BetaGridLikeMoneyModule"; }
|
|
}
|
|
|
|
public bool IsSharedModule
|
|
{
|
|
get { return true; }
|
|
}
|
|
}
|
|
|
|
}
|