mirror of
https://github.com/ManfredAabye/opensimcurrencyserver-dotnet-tests.git
synced 2026-07-31 04:07:26 +00:00
4324 lines
201 KiB
C#
4324 lines
201 KiB
C#
/*
|
|
* Copyright (c) Contributors, http://opensimulator.org/, http://www.nsl.tuis.ac.jp/ 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.
|
|
|
|
Funktion
|
|
Diese Klasse ist das zentrale XML-RPC Modul für den OpenSim MoneyServer. Sie erweitert MoneyDBService und implementiert das Interface IMoneyDBService. Ihre Aufgaben:
|
|
|
|
Verwaltung und Verarbeitung von XML-RPC-Anfragen für Geldtransaktionen, Landkauf, Session-Management und mehr.
|
|
Bindung von HTTP- und XML-RPC-Handlern an den HTTP-Server.
|
|
Zugriff und Manipulation von Benutzerguthaben, Transaktionen und Gruppenmitgliedschaften über die Datenbank.
|
|
Spezialfunktionen für Cashbook-Ausgaben, Konsolenbefehle und Logging.
|
|
|
|
Null-Pointer-Checks & Fehlerquellen
|
|
1. Konstruktor & Initialisierung
|
|
Alle kritischen Dependencies (moneyDBService, moneyCore) werden mit ArgumentNullException.ThrowIfNull() geprüft.
|
|
Konfigurationswerte werden aus INI geladen und auf null/Fehlwerte geprüft.
|
|
Dictionaries und andere Felder werden direkt initialisiert oder nachgeladen.
|
|
|
|
2. HTTP/XML-RPC-Handler
|
|
Viele Methoden prüfen die Eingabeparameter (z.B. ob ein Request-Objekt null ist).
|
|
Bei fehlerhaften Requests oder Sessions wird ein Fehler geloggt und eine Standardantwort zurückgegeben.
|
|
Beispiel:
|
|
C#
|
|
|
|
if (httpRequest == null || httpResponse == null) { ... return; }
|
|
if (request == null) { ... return new XmlRpcResponse { Value = new Hashtable { { "success", false } } }; }
|
|
|
|
Bei Session-Handling wird vor jedem Zugriff geprüft, ob die Dictionary-Schlüssel existieren.
|
|
Bei Datenbankoperationen werden Exceptions gefangen und führen nicht zu Abstürzen, sondern zu Logging und Fehlerantwort.
|
|
|
|
3. Datenbankzugriffe
|
|
Datenbankverbindungen werden immer in einem Try-Catch-Finally-Block verwendet, wobei im finally-Block die Verbindung freigegeben wird (dbm.Release()).
|
|
Bei Datenbankoperationen wird auf mögliche Null-Rückgaben geachtet (z.B. FetchUserInfo kann null liefern).
|
|
|
|
4. Spezielle Fehlerquellen
|
|
Parsen von XML-Requests: Hier können null-Werte entstehen, werden aber meistens abgefangen.
|
|
Zahlreiche Methoden prüfen, ob Parameter null/leer sind, bevor sie verwendet werden (z.B. agentId, groupId).
|
|
SQL-Parameter werden mit AddWithValue gesetzt, was SQL-Injection weitgehend verhindert.
|
|
|
|
5. Allgemeine Fehlerbehandlung
|
|
Bei Fehlern wird stets ins Log geschrieben.
|
|
Rückgabewerte für Fehlerfälle sind konsistent (meistens false, null oder ein Hashtable mit "success": false).
|
|
Fehler in der Verarbeitung führen zu keinen unkontrollierten Null-Pointern oder Abstürzen.
|
|
|
|
Beispiele für Null-Checks und Fehlerbehandlung
|
|
|
|
Session-Checks:
|
|
C#
|
|
|
|
if (m_sessionDic.ContainsKey(senderID) && m_secureSessionDic.ContainsKey(senderID)) { ... }
|
|
else { responseData["message"] = "Session check failure, please re-login later!"; return response; }
|
|
|
|
Datenbankobjekte:
|
|
C#
|
|
|
|
UserInfo rcvr = m_moneyDBService.FetchUserInfo(receiverID);
|
|
if (rcvr == null) { m_log.ErrorFormat(...); return response; }
|
|
|
|
Catch-All für Exceptions:
|
|
C#
|
|
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: ... Exception occurred: {0}", ex.Message);
|
|
return new XmlRpcResponse();
|
|
}
|
|
|
|
Hashtable-Zugriffe:
|
|
C#
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
if (requestData == null) { ... }
|
|
|
|
Verbesserungsmöglichkeiten
|
|
|
|
In einigen Methoden werden Werte aus Hashtables direkt abgerufen, ohne vorher zu prüfen,
|
|
ob sie wirklich existieren oder den erwarteten Typ haben (z.B. int.Parse direkt auf einen String aus einer Hashtable). Hier könnten defensive Checks ergänzt werden.
|
|
XML-Parsing könnte robuster gestaltet werden, um fehlerhafte oder absichtlich manipulierte Requests besser abzufangen.
|
|
Teilweise könnten Methoden Parameter noch expliziter auf Plausibilität prüfen (z.B. Range-Checks bei Beträgen).
|
|
|
|
Fazit
|
|
|
|
Sehr robust gegen NullPointer-Fehler und allgemeine Fehlerquellen!
|
|
|
|
Alle kritischen Zugriffe werden defensiv behandelt.
|
|
Fehler werden stets geloggt und führen zu konsistenten Fehlerantworten.
|
|
Ressourcen werden ordentlich freigegeben.
|
|
Die Funktionalität ist klar: XML-RPC-Endpoint-Management, Geldtransaktionen, User-Sessions, Gruppen-Checks, Logging, Cashbook, etc.
|
|
|
|
Empfehlung:
|
|
Das Modul ist für produktiven Einsatz gut vorbereitet. Zusätzliche defensive Checks bei Daten aus externen Quellen (z.B. XML/Hashtable) wären sinnvoll, sind aber kein kritischer Mangel.
|
|
*/
|
|
|
|
using log4net;
|
|
|
|
using MySql.Data.MySqlClient;
|
|
|
|
using Nini.Config;
|
|
|
|
using NSL.Certificate.Tools;
|
|
using NSL.Network.XmlRpc;
|
|
|
|
using Nwc.XmlRpc;
|
|
|
|
using OpenMetaverse;
|
|
using OpenMetaverse.ImportExport.Collada14;
|
|
|
|
using OpenSim.Data.MySQL.MySQLMoneyDataWrapper;
|
|
using OpenSim.Framework;
|
|
using OpenSim.Framework.Console;
|
|
using OpenSim.Framework.Servers.HttpServer;
|
|
using OpenSim.Grid.MoneyServer;
|
|
using OpenSim.Modules.Currency;
|
|
using OpenSim.Region.Framework.Scenes;
|
|
using OpenSim.Server.Base;
|
|
using OpenSim.Services.Interfaces;
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Specialized;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.RegularExpressions;
|
|
using System.Transactions;
|
|
using System.Xml;
|
|
|
|
using static Mono.Security.X509.X520;
|
|
using static OpenMetaverse.DllmapConfigHelper;
|
|
using static System.Collections.Specialized.BitVector32;
|
|
|
|
using System.Text.Json.Serialization;
|
|
|
|
|
|
namespace OpenSim.Grid.MoneyServer
|
|
{
|
|
class MoneyXmlRpcModule : MoneyDBService, IMoneyDBService
|
|
{
|
|
// ################## Initial ##################
|
|
#region Setup Initial
|
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
|
|
|
|
private int m_realMoney = 1000; // Beispielwert oder aus der MoneyServer.ini geladen
|
|
private int m_gameMoney = 10000; // Beispielwert oder aus der MoneyServer.ini geladen
|
|
|
|
// MoneyServer settings
|
|
public int m_defaultBalance = 1000;
|
|
|
|
private bool m_forceTransfer = false;
|
|
private string m_bankerAvatar = "";
|
|
|
|
// Testbereich
|
|
// Maximum pro Tag:
|
|
public int m_TotalDay = 100;
|
|
// Maximum pro Woche:
|
|
public int m_TotalWeek = 250;
|
|
// Maximum pro Monat:
|
|
public int m_TotalMonth = 500;
|
|
// Maximum Besitz:
|
|
public int m_CurrencyMaximum;
|
|
// Geldkauf abschalten:
|
|
public string m_CurrencyOnOff;
|
|
// Geldkauf nur für Gruppe:
|
|
public bool m_CurrencyGroupOnly = false;
|
|
public bool m_UserMailLock = false;
|
|
public string m_CurrencyGroupName = "";
|
|
public string m_CurrencyGroupID = "";
|
|
|
|
// Script settings
|
|
private bool m_scriptSendMoney = false;
|
|
private string m_scriptAccessKey = "";
|
|
private string m_scriptIPaddress = "127.0.0.1";
|
|
|
|
// PHP settings
|
|
private string m_scriptApiKey = ""; // API Key aus der INI
|
|
private string m_scriptAllowedUser = ""; // AllowedUser aus der INI
|
|
|
|
// HG settings
|
|
private bool m_hg_enable = false;
|
|
private bool m_gst_enable = false;
|
|
private int m_hg_defaultBalance = 0;
|
|
private int m_gst_defaultBalance = 0;
|
|
private int m_CalculateCurrency = 0;
|
|
|
|
// XMLRPC Debug settings
|
|
private bool m_DebugConsole = false;
|
|
private bool m_DebugFile = false;
|
|
|
|
// Certificate settings
|
|
private bool m_checkServerCert = false;
|
|
private string m_cacertFilename = "";
|
|
private string m_certFilename = "";
|
|
private string m_certPassword = "";
|
|
|
|
// SSL settings
|
|
private string m_sslCommonName = "";
|
|
|
|
private Dictionary<ulong, Scene> m_scenes = new Dictionary<ulong, Scene>();
|
|
|
|
private NSLCertificateVerify m_certVerify = new NSLCertificateVerify();
|
|
|
|
private string m_BalanceMessageLandSale = "Paid the Money L${0} for Land.";
|
|
private string m_BalanceMessageRcvLandSale = "";
|
|
private string m_BalanceMessageSendGift = "Sent Gift L${0} to {1}.";
|
|
private string m_BalanceMessageReceiveGift = "Received Gift L${0} from {1}.";
|
|
private string m_BalanceMessagePayCharge = "";
|
|
private string m_BalanceMessageBuyObject = "Bought the Object {2} from {1} by L${0}.";
|
|
private string m_BalanceMessageSellObject = "{1} bought the Object {2} by L${0}.";
|
|
private string m_BalanceMessageGetMoney = "Got the Money L${0} from {1}.";
|
|
private string m_BalanceMessageBuyMoney = "Bought the Money L${0}.";
|
|
private string m_BalanceMessageRollBack = "RollBack the Transaction: L${0} from/to {1}.";
|
|
private string m_BalanceMessageSendMoney = "Paid the Money L${0} to {1}.";
|
|
private string m_BalanceMessageReceiveMoney = "Received L${0} from {1}.";
|
|
|
|
private bool m_enableAmountZero = false;
|
|
|
|
const int MONEYMODULE_REQUEST_TIMEOUT = 30 * 1000; //30 seconds
|
|
private long TicksToEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
|
|
|
|
private IMoneyDBService m_moneyDBService;
|
|
// Konfig fuer Konsolenbefehle.
|
|
private IConfigSource m_config;
|
|
private IMoneyServiceCore m_moneyCore;
|
|
|
|
protected IConfig m_server_config;
|
|
protected IConfig m_cert_config;
|
|
|
|
/// <value>
|
|
/// Used to notify old regions as to which OpenSim version to upgrade to
|
|
/// </value>
|
|
//private string m_opensimVersion;
|
|
|
|
private Dictionary<string, string> m_sessionDic;
|
|
private Dictionary<string, string> m_secureSessionDic;
|
|
private Dictionary<string, string> m_webSessionDic;
|
|
|
|
protected BaseHttpServer m_httpServer;
|
|
|
|
|
|
/// <summary>Initializes a new instance of the <see cref="MoneyXmlRpcModule" /> class.</summary>
|
|
public MoneyXmlRpcModule(string connectionString, int maxDBConnections)
|
|
{
|
|
Initialise(connectionString, maxDBConnections);
|
|
}
|
|
|
|
/// <summary>Initialises the specified opensim version.</summary>
|
|
/// <param name="opensimVersion">The opensim version.</param>
|
|
/// <param name="moneyDBService">The money database service.</param>
|
|
/// <param name="moneyCore">The money core.</param>
|
|
public void Initialise(string opensimVersion, IMoneyDBService moneyDBService, IMoneyServiceCore moneyCore, IConfigSource config)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(moneyDBService);
|
|
|
|
ArgumentNullException.ThrowIfNull(moneyCore);
|
|
|
|
m_moneyDBService = moneyDBService;
|
|
m_moneyCore = moneyCore;
|
|
|
|
// Get server configuration
|
|
var serverConfig = m_moneyCore.GetServerConfig() ?? throw new InvalidOperationException("Server configuration is not available");
|
|
|
|
// Get certificate configuration
|
|
var certConfig = m_moneyCore.GetCertConfig() ?? throw new InvalidOperationException("Certificate configuration is not available");
|
|
|
|
// Load configuration values
|
|
m_defaultBalance = serverConfig.GetInt("DefaultBalance", m_defaultBalance);
|
|
m_forceTransfer = serverConfig.GetBoolean("EnableForceTransfer", m_forceTransfer);
|
|
m_bankerAvatar = serverConfig.GetString("BankerAvatar", m_bankerAvatar).ToLower();
|
|
|
|
m_moneyDBService = moneyDBService;
|
|
m_moneyCore = moneyCore;
|
|
m_server_config = m_moneyCore.GetServerConfig(); // [MoneyServer] Section
|
|
m_cert_config = m_moneyCore.GetCertConfig(); // [Certificate] Section
|
|
|
|
m_TotalDay = serverConfig.GetInt("TotalDay", m_TotalDay);
|
|
m_TotalWeek = serverConfig.GetInt("TotalWeek", m_TotalWeek);
|
|
m_TotalMonth = serverConfig.GetInt("TotalMonth", m_TotalMonth);
|
|
m_CurrencyMaximum = serverConfig.GetInt("CurrencyMaximum", m_CurrencyMaximum);
|
|
|
|
m_CurrencyOnOff = serverConfig.GetString("CurrencyOnOff", m_CurrencyOnOff);
|
|
m_CurrencyGroupOnly = serverConfig.GetBoolean("CurrencyGroupOnly", m_CurrencyGroupOnly);
|
|
m_UserMailLock = serverConfig.GetBoolean("UserMailLock", m_UserMailLock);
|
|
|
|
m_CurrencyGroupName = serverConfig.GetString("CurrencyGroupName", m_CurrencyGroupName);
|
|
m_CurrencyGroupID = serverConfig.GetString("CurrencyGroupID", m_CurrencyGroupID);
|
|
|
|
// [MoneyServer] Section
|
|
m_defaultBalance = m_server_config.GetInt("DefaultBalance", m_defaultBalance);
|
|
|
|
m_forceTransfer = m_server_config.GetBoolean("EnableForceTransfer", m_forceTransfer);
|
|
|
|
string banker = m_server_config.GetString("BankerAvatar", m_bankerAvatar);
|
|
m_bankerAvatar = banker.ToLower();
|
|
|
|
m_enableAmountZero = m_server_config.GetBoolean("EnableAmountZero", m_enableAmountZero);
|
|
m_scriptSendMoney = m_server_config.GetBoolean("EnableScriptSendMoney", m_scriptSendMoney);
|
|
m_scriptAccessKey = m_server_config.GetString("MoneyScriptAccessKey", m_scriptAccessKey);
|
|
m_scriptIPaddress = m_server_config.GetString("MoneyScriptIPaddress", m_scriptIPaddress);
|
|
|
|
m_scriptApiKey = m_server_config.GetString("ApiKey", m_scriptApiKey); // New feature
|
|
m_scriptAllowedUser = m_server_config.GetString("AllowedUser", m_scriptAllowedUser); // New feature
|
|
|
|
m_CalculateCurrency = m_server_config.GetInt("CalculateCurrency", m_CalculateCurrency); // New feature
|
|
m_DebugConsole = m_server_config.GetBoolean("DebugConsole", m_DebugConsole); // New feature
|
|
m_DebugFile = m_server_config.GetBoolean("m_DebugFile", m_DebugFile); // New feature
|
|
|
|
m_TotalDay = m_server_config.GetInt("TotalDay", m_TotalDay);
|
|
m_TotalWeek = m_server_config.GetInt("TotalWeek", m_TotalWeek);
|
|
m_TotalMonth = m_server_config.GetInt("TotalMonth", m_TotalMonth);
|
|
m_CurrencyMaximum = m_server_config.GetInt("CurrencyMaximum", m_CurrencyMaximum);
|
|
|
|
m_CurrencyOnOff = m_server_config.GetString("CurrencyOnOff", m_CurrencyOnOff);
|
|
m_CurrencyGroupOnly = m_server_config.GetBoolean("CurrencyGroupOnly", m_CurrencyGroupOnly);
|
|
m_UserMailLock = m_server_config.GetBoolean("UserMailLock", m_UserMailLock);
|
|
|
|
m_CurrencyGroupName = m_server_config.GetString("CurrencyGroupName", m_CurrencyGroupName);
|
|
m_CurrencyGroupID = m_server_config.GetString("CurrencyGroupID", m_CurrencyGroupID);
|
|
|
|
if (m_CurrencyMaximum <= 0) m_CurrencyMaximum = 1000;
|
|
|
|
// Hyper Grid Avatar
|
|
m_hg_enable = m_server_config.GetBoolean("EnableHGAvatar", m_hg_enable);
|
|
m_gst_enable = m_server_config.GetBoolean("EnableGuestAvatar", m_gst_enable);
|
|
m_hg_defaultBalance = m_server_config.GetInt("HGAvatarDefaultBalance", m_hg_defaultBalance);
|
|
m_gst_defaultBalance = m_server_config.GetInt("GuestAvatarDefaultBalance", m_gst_defaultBalance);
|
|
|
|
// Update Balance Messages
|
|
m_BalanceMessageLandSale = m_server_config.GetString("BalanceMessageLandSale", m_BalanceMessageLandSale);
|
|
m_BalanceMessageRcvLandSale = m_server_config.GetString("BalanceMessageRcvLandSale", m_BalanceMessageRcvLandSale);
|
|
m_BalanceMessageSendGift = m_server_config.GetString("BalanceMessageSendGift", m_BalanceMessageSendGift);
|
|
m_BalanceMessageReceiveGift = m_server_config.GetString("BalanceMessageReceiveGift", m_BalanceMessageReceiveGift);
|
|
m_BalanceMessagePayCharge = m_server_config.GetString("BalanceMessagePayCharge", m_BalanceMessagePayCharge);
|
|
m_BalanceMessageBuyObject = m_server_config.GetString("BalanceMessageBuyObject", m_BalanceMessageBuyObject);
|
|
m_BalanceMessageSellObject = m_server_config.GetString("BalanceMessageSellObject", m_BalanceMessageSellObject);
|
|
m_BalanceMessageGetMoney = m_server_config.GetString("BalanceMessageGetMoney", m_BalanceMessageGetMoney);
|
|
m_BalanceMessageBuyMoney = m_server_config.GetString("BalanceMessageBuyMoney", m_BalanceMessageBuyMoney);
|
|
m_BalanceMessageRollBack = m_server_config.GetString("BalanceMessageRollBack", m_BalanceMessageRollBack);
|
|
m_BalanceMessageSendMoney = m_server_config.GetString("BalanceMessageSendMoney", m_BalanceMessageSendMoney);
|
|
m_BalanceMessageReceiveMoney = m_server_config.GetString("BalanceMessageReceiveMoney", m_BalanceMessageReceiveMoney);
|
|
|
|
// [Certificate] Section
|
|
|
|
// XML RPC to Region Server (Client Mode)
|
|
// Client Certificate
|
|
m_certFilename = m_cert_config.GetString("ClientCertFilename", m_certFilename);
|
|
m_certPassword = m_cert_config.GetString("ClientCertPassword", m_certPassword);
|
|
if (m_certFilename != "")
|
|
{
|
|
m_certVerify.SetPrivateCert(m_certFilename, m_certPassword);
|
|
m_log.Info("[MONEY XMLRPC]: Initialise: Issue Authentication of Client. Cert file is " + m_certFilename);
|
|
}
|
|
|
|
// Server Authentication
|
|
// CA : MoneyServer config for checking the server certificate of the web server for XMLRPC
|
|
m_checkServerCert = m_cert_config.GetBoolean("CheckServerCert", m_checkServerCert);
|
|
m_cacertFilename = m_cert_config.GetString("CACertFilename", m_cacertFilename);
|
|
|
|
if (m_cacertFilename != "")
|
|
{
|
|
m_certVerify.SetPrivateCA(m_cacertFilename);
|
|
}
|
|
else
|
|
{
|
|
m_checkServerCert = false;
|
|
}
|
|
|
|
if (m_checkServerCert)
|
|
{
|
|
m_log.Info("[MONEY XMLRPC]: Initialise: Execute Authentication of Server. CA file is " + m_cacertFilename);
|
|
}
|
|
else
|
|
{
|
|
m_log.Info("[MONEY XMLRPC]: CheckServerCert is false.");
|
|
}
|
|
|
|
m_moneyDBService = moneyDBService;
|
|
m_config = config;
|
|
|
|
m_sessionDic = m_moneyCore.GetSessionDic();
|
|
m_secureSessionDic = m_moneyCore.GetSecureSessionDic();
|
|
m_webSessionDic = m_moneyCore.GetWebSessionDic();
|
|
RegisterHandlers();
|
|
|
|
RegisterStreamHandlers();
|
|
}
|
|
|
|
private void RegisterStreamHandlers()
|
|
{
|
|
m_log.Info("[MONEY XMLRPC]: Registering currency.php handlers.");
|
|
m_httpServer.AddSimpleStreamHandler(new CurrencyStreamHandler("/currency.php", CurrencyProcessPHP));
|
|
|
|
m_log.Info("[MONEY XMLRPC]: Registering landtool.php handlers.");
|
|
m_httpServer.AddSimpleStreamHandler(new LandtoolStreamHandler("/landtool.php", LandtoolProcessPHP));
|
|
|
|
if (!string.IsNullOrWhiteSpace(m_scriptApiKey) && !string.IsNullOrWhiteSpace(m_scriptAllowedUser))
|
|
{
|
|
m_httpServer.AddSimpleStreamHandler(new JsonStreamHandler("/api/json", JsonApiProcess));
|
|
m_log.Info("[MONEY XMLRPC]: JSON API handler registered (/api/json).");
|
|
}
|
|
else
|
|
{
|
|
m_log.Info("[MONEY XMLRPC]: JSON API handler NOT registered, missing ApiKey or AllowedUser!");
|
|
}
|
|
|
|
m_log.InfoFormat("[MONEY MODULE]: Registered /currency.php , /landtool.php and JSON API handler on Port: {0}", m_httpServer.Port);
|
|
}
|
|
|
|
/// <summary>Posts the initialise.</summary>
|
|
public void PostInitialise()
|
|
{
|
|
}
|
|
|
|
private Dictionary<string, XmlRpcMethod> m_rpcHandlers = new Dictionary<string, XmlRpcMethod>();
|
|
|
|
|
|
/// <summary>Registers the handlers.</summary>
|
|
public void RegisterHandlers()
|
|
{
|
|
m_httpServer = m_moneyCore.GetHttpServer();
|
|
m_httpServer.AddXmlRPCHandler("ClientLogin", handleClientLogin);
|
|
m_httpServer.AddXmlRPCHandler("ClientLogout", handleClientLogout);
|
|
m_httpServer.AddXmlRPCHandler("GetBalance", handleGetBalance);
|
|
m_httpServer.AddXmlRPCHandler("GetTransaction", handleGetTransaction);
|
|
|
|
m_httpServer.AddXmlRPCHandler("CancelTransfer", handleCancelTransfer);
|
|
|
|
m_httpServer.AddXmlRPCHandler("TransferMoney", handleTransaction);
|
|
m_httpServer.AddXmlRPCHandler("ForceTransferMoney", handleForceTransaction); // added
|
|
m_httpServer.AddXmlRPCHandler("PayMoneyCharge", handlePayMoneyCharge); // added
|
|
m_httpServer.AddXmlRPCHandler("AddBankerMoney", handleAddBankerMoney); // added
|
|
|
|
m_httpServer.AddXmlRPCHandler("SendMoney", handleScriptTransaction);
|
|
m_httpServer.AddXmlRPCHandler("MoveMoney", handleScriptTransaction);
|
|
|
|
// this is from original DTL. not check yet.
|
|
m_httpServer.AddXmlRPCHandler("WebLogin", handleWebLogin);
|
|
m_httpServer.AddXmlRPCHandler("WebLogout", handleWebLogout);
|
|
m_httpServer.AddXmlRPCHandler("WebGetBalance", handleWebGetBalance);
|
|
m_httpServer.AddXmlRPCHandler("WebGetTransaction", handleWebGetTransaction);
|
|
m_httpServer.AddXmlRPCHandler("WebGetTransactionNum", handleWebGetTransactionNum);
|
|
|
|
// Land Buy Test
|
|
m_httpServer.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep);
|
|
m_httpServer.AddXmlRPCHandler("buyLandPrep", buyLandPrep);
|
|
|
|
// Currency Buy Test
|
|
// getCurrencyQuote", quote_func
|
|
// buyCurrency", buy_func
|
|
m_httpServer.AddXmlRPCHandler("getCurrencyQuote", getCurrencyQuote);
|
|
m_httpServer.AddXmlRPCHandler("buyCurrency", buyCurrency);
|
|
|
|
// Money Transfer Test
|
|
m_httpServer.AddXmlRPCHandler("OnMoneyTransfered", OnMoneyTransferedHandler);
|
|
m_httpServer.AddXmlRPCHandler("UpdateBalance", BalanceUpdateHandler);
|
|
m_httpServer.AddXmlRPCHandler("UserAlert", UserAlertHandler);
|
|
|
|
// Angebot oder eine Information zu einem Kaufpreis
|
|
// m_httpServer.AddXmlRPCHandler("quote", getCurrencyQuote);
|
|
}
|
|
#endregion
|
|
// ################## Land Buy ##################
|
|
#region Land Buy
|
|
|
|
// Flexibilität: Die gesamte Logik wird innerhalb von LandtoolProcessPHP und ihren Hilfsfunktionen abgewickelt.
|
|
// Fehlerbehandlung: Umfassende Überprüfung auf fehlende Daten oder Fehler während der Verarbeitung.
|
|
// Unabhängigkeit: Keine Abhängigkeit von externen Funktionen oder Modulen.
|
|
|
|
private void LandtoolProcessPHP(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: LANDTOOL PROCESS PHP starting...");
|
|
|
|
if (httpRequest == null || httpResponse == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC MODULE]: Invalid request or response object.");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
// XML-String aus Anfrage lesen
|
|
string requestBody;
|
|
using (var reader = new StreamReader(httpRequest.InputStream, Encoding.UTF8))
|
|
{
|
|
requestBody = reader.ReadToEnd();
|
|
}
|
|
|
|
// XML-Daten parsen
|
|
XmlDocument doc = new XmlDocument();
|
|
doc.LoadXml(requestBody);
|
|
|
|
// Methode extrahieren
|
|
XmlNode methodNameNode = doc.SelectSingleNode("/methodCall/methodName");
|
|
if (methodNameNode == null)
|
|
{
|
|
throw new Exception("Missing method name in XML-RPC request.");
|
|
}
|
|
|
|
string methodName = methodNameNode.InnerText;
|
|
XmlNodeList members = doc.SelectNodes("//param/value/struct/member");
|
|
|
|
// Variablen für Landanfrage initialisieren
|
|
string agentId = null, secureSessionId = null, language = null;
|
|
int billableArea = 0, currencyBuy = 0;
|
|
|
|
// Werte aus der XML-Struktur extrahieren
|
|
foreach (XmlNode member in members)
|
|
{
|
|
string name = member.SelectSingleNode("name")?.InnerText;
|
|
string value = member.SelectSingleNode("value")?.InnerText;
|
|
|
|
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) continue;
|
|
|
|
switch (name)
|
|
{
|
|
case "agentId": agentId = value; break;
|
|
case "billableArea": billableArea = int.Parse(value); break;
|
|
case "currencyBuy": currencyBuy = int.Parse(value); break;
|
|
case "language": language = value; break;
|
|
case "secureSessionId": secureSessionId = value; break;
|
|
}
|
|
}
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: agentId ", agentId);
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: billableArea", billableArea);
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: currencyBuy", currencyBuy);
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: language", language);
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: secureSessionId", secureSessionId);
|
|
|
|
if (methodName == "preflightBuyLandPrep")
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: Processing Preflight Land Purchase Request for AgentId: {0}, BillableArea: {1}",
|
|
agentId, billableArea);
|
|
|
|
// Preflight-Prüfung
|
|
Hashtable preflightResponse = PerformPreflightLandCheck(agentId, billableArea, currencyBuy, language, secureSessionId);
|
|
if (!(bool)preflightResponse["success"])
|
|
{
|
|
m_log.Error("[MONEY XMLRPC MODULE]: Preflight check failed.");
|
|
httpResponse.StatusCode = 400;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Preflight check failed</response>");
|
|
return;
|
|
}
|
|
|
|
// Erfolgreiche Antwort zurückgeben
|
|
httpResponse.StatusCode = 200;
|
|
XmlRpcResponse xmlResponse = new XmlRpcResponse { Value = preflightResponse };
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes(xmlResponse.ToString());
|
|
}
|
|
else if (methodName == "buyLandPrep")
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: Processing Land Purchase Request for AgentId: {0}, BillableArea: {1}",
|
|
agentId, billableArea);
|
|
|
|
// Landkauf durchführen
|
|
Hashtable purchaseResponse = ProcessLandPurchase(agentId, billableArea, currencyBuy, language, secureSessionId);
|
|
|
|
// Überprüfung der Antwort
|
|
if (!(bool)purchaseResponse["success"])
|
|
{
|
|
m_log.Error("[MONEY XMLRPC MODULE]: Land purchase failed.");
|
|
httpResponse.StatusCode = 400;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Land purchase failed</response>");
|
|
return;
|
|
}
|
|
|
|
// Erfolgreiche Antwort zurückgeben
|
|
httpResponse.StatusCode = 200;
|
|
XmlRpcResponse xmlResponse = new XmlRpcResponse { Value = purchaseResponse };
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes(xmlResponse.ToString());
|
|
}
|
|
else
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC MODULE]: Unknown landtool method name: {0}", methodName);
|
|
httpResponse.StatusCode = 400;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Invalid method name</response>");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC MODULE]: Error processing LANDTOOL request. Error: {0}", ex.ToString());
|
|
httpResponse.StatusCode = 500;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Error</response>");
|
|
}
|
|
}
|
|
|
|
// Beispiel einer Funktion zur Preflight-Prüfung
|
|
// PerformPreflightLandCheck:
|
|
// Simuliert die Preflight-Prüfung für den Landkauf.
|
|
// Gibt eine Erfolgsmeldung in Form einer Hashtable zurück.
|
|
private Hashtable PerformPreflightLandCheck(string agentId, int billableArea, int currencyBuy, string language, string secureSessionId)
|
|
{
|
|
// Beispielhafte Logik für Preflight-Prüfung
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: Preflight check for AgentId: {0}, Area: {1}, CurrencyBuy: {2}", agentId, billableArea, currencyBuy);
|
|
|
|
// Erfolg simulieren
|
|
return new Hashtable
|
|
{
|
|
{ "success", true },
|
|
{ "agentId", agentId },
|
|
{ "billableArea", billableArea },
|
|
{ "currencyBuy", currencyBuy },
|
|
{ "message", "Preflight check passed" }
|
|
};
|
|
}
|
|
|
|
// Beispiel einer Funktion zur Bearbeitung eines Landkaufs
|
|
// ProcessLandPurchase:
|
|
// Simuliert die Durchführung des Landkaufs.
|
|
// Gibt ebenfalls eine Erfolgsmeldung als Hashtable zurück.
|
|
private Hashtable ProcessLandPurchase(string agentId, int billableArea, int currencyBuy, string language, string secureSessionId)
|
|
{
|
|
// Beispielhafte Logik für Landkauf
|
|
m_log.InfoFormat("[MONEY XMLRPC MODULE]: Processing land purchase for AgentId: {0}, Area: {1}, CurrencyBuy: {2}", agentId, billableArea, currencyBuy);
|
|
|
|
// Erfolg simulieren
|
|
return new Hashtable
|
|
{
|
|
{ "success", true },
|
|
{ "agentId", agentId },
|
|
{ "billableArea", billableArea },
|
|
{ "currencyBuy", currencyBuy },
|
|
{ "message", "Land purchase completed successfully" }
|
|
};
|
|
}
|
|
private XmlRpcResponse preflightBuyLandPrep(XmlRpcRequest request, IPEndPoint client)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: preflightBuyLandPrep starting...");
|
|
|
|
if (request == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: preflightBuyLandPrep: request is null.");
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
|
|
if (client == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: preflightBuyLandPrep: client is null.");
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
|
|
try
|
|
{
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
if (requestData == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: preflightBuyLandPrep: request data is null.");
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
|
|
int billableArea = Convert.ToInt32(requestData["billableArea"]);
|
|
int currencyBuy = Convert.ToInt32(requestData["currencyBuy"]);
|
|
|
|
// Log the received data for debugging
|
|
m_log.InfoFormat("[MONEY XMLRPC]: Received billableArea = {0}, currencyBuy = {1}", billableArea, currencyBuy);
|
|
|
|
// Process preflight logic here
|
|
if (billableArea < 0 || currencyBuy < 0)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: preflightBuyLandPrep: Invalid input values.");
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
|
|
// Simulate sending response
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseValue = new Hashtable
|
|
{
|
|
{ "success", true },
|
|
{ "billableArea", billableArea },
|
|
{ "currencyBuy", currencyBuy }
|
|
};
|
|
response.Value = responseValue;
|
|
return response;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: preflightBuyLandPrep: {0}", ex.Message);
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
}
|
|
private XmlRpcResponse buyLandPrep(XmlRpcRequest request, IPEndPoint client)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: buyLandPrep starting...");
|
|
|
|
if (request == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: buyLandPrep: request is null.");
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
|
|
if (client == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: buyLandPrep: client is null.");
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
|
|
try
|
|
{
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
if (requestData == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: buyLandPrep: request data is null.");
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
|
|
string agentId = requestData["agentId"]?.ToString();
|
|
string secureSessionId = requestData["secureSessionId"]?.ToString();
|
|
string language = requestData["language"]?.ToString();
|
|
int billableArea = Convert.ToInt32(requestData["billableArea"]);
|
|
int currencyBuy = Convert.ToInt32(requestData["currencyBuy"]);
|
|
|
|
// Log the received data for debugging
|
|
m_log.InfoFormat("[MONEY XMLRPC]: Received agentId = {0}, secureSessionId = {1}, billableArea = {2}, currencyBuy = {3}",
|
|
agentId, secureSessionId, billableArea, currencyBuy);
|
|
|
|
if (string.IsNullOrEmpty(agentId) || string.IsNullOrEmpty(secureSessionId))
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: buyLandPrep: Missing required parameters.");
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
|
|
// Process purchase logic here
|
|
bool purchaseSuccessful = ProcessLandPurchase(agentId, secureSessionId, billableArea, currencyBuy);
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseValue = new Hashtable
|
|
{
|
|
{ "success", purchaseSuccessful }
|
|
};
|
|
response.Value = responseValue;
|
|
return response;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: buyLandPrep: {0}", ex.Message);
|
|
return new XmlRpcResponse { Value = new Hashtable { { "success", false } } };
|
|
}
|
|
}
|
|
|
|
// Helper function to simulate land purchase logic
|
|
private bool ProcessLandPurchase(string agentId, string secureSessionId, int billableArea, int currencyBuy)
|
|
{
|
|
// Simulate some purchase validation
|
|
if (billableArea > 0 && currencyBuy >= billableArea * 10) // Example: each square meter costs 10 currency units
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: ProcessLandPurchase: Purchase successful for Agent {0}.", agentId);
|
|
return true;
|
|
}
|
|
|
|
m_log.WarnFormat("[MONEY XMLRPC]: ProcessLandPurchase: Purchase failed for Agent {0}.", agentId);
|
|
return false;
|
|
}
|
|
#endregion
|
|
// ################## Currency Buy ##################
|
|
#region Currency Buy
|
|
|
|
private void CurrencyProcessPHP(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
{
|
|
m_log.InfoFormat("[CURRENCY PROCESS PHP]: Currency Process Starting...");
|
|
|
|
if (httpRequest == null || httpResponse == null)
|
|
{
|
|
m_log.Error("[CURRENCY PROCESS PHP]: Invalid request or response object.");
|
|
httpResponse.StatusCode = 400;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Invalid request</response>");
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
string requestBody;
|
|
using (var reader = new StreamReader(httpRequest.InputStream, Encoding.UTF8))
|
|
{
|
|
requestBody = reader.ReadToEnd();
|
|
}
|
|
|
|
XmlDocument doc = new XmlDocument();
|
|
doc.LoadXml(requestBody);
|
|
|
|
XmlNode methodNameNode = doc.SelectSingleNode("/methodCall/methodName");
|
|
if (methodNameNode == null)
|
|
{
|
|
throw new Exception("Missing method name in XML-RPC request.");
|
|
}
|
|
|
|
string methodName = methodNameNode.InnerText;
|
|
|
|
Hashtable parameters = ExtractXmlRpcParams(doc);
|
|
|
|
string agentId = parameters["agentId"]?.ToString();
|
|
string secureSessionId = parameters["secureSessionId"]?.ToString();
|
|
int currencyBuy = int.Parse(parameters["currencyBuy"]?.ToString() ?? "0");
|
|
|
|
m_log.InfoFormat("[CURRENCY PROCESS PHP]: Parsed values - AgentId: {0}, CurrencyBuy: {1}, SecureSessionId: {2}", agentId, currencyBuy, secureSessionId);
|
|
|
|
string transactionID = parameters["transactionID"]?.ToString();
|
|
string userID = parameters["agentId"]?.ToString();
|
|
int amount = int.Parse(parameters["currencyBuy"]?.ToString() ?? "0");
|
|
|
|
if (string.IsNullOrEmpty(transactionID))
|
|
{
|
|
transactionID = secureSessionId;
|
|
}
|
|
|
|
m_log.InfoFormat("[CURRENCY PROCESS PHP]: Parsed values - transactionID: {0}, userID: {1}, amount: {2}", transactionID, userID, amount);
|
|
|
|
if (m_CurrencyGroupOnly && m_CurrencyGroupID != "00000000-0000-0000-0000-000000000000" && !IsUserInGroup(agentId, m_CurrencyGroupID))
|
|
{
|
|
m_log.InfoFormat("[CURRENCY PROCESS PHP]: User {0} is not a member of the required group {1}.", agentId, m_CurrencyGroupID);
|
|
httpResponse.StatusCode = 403;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>User is not a member of the required group</response>");
|
|
return;
|
|
}
|
|
|
|
if (m_UserMailLock && !UserMailLock(agentId))
|
|
{
|
|
m_log.InfoFormat("[CURRENCY PROCESS PHP]: User {0} does not have a registered email address.", agentId);
|
|
httpResponse.StatusCode = 403;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>User does not have a registered email address</response>");
|
|
return;
|
|
}
|
|
|
|
if (m_CurrencyOnOff != "off" && !CheckGroupMoney(agentId, m_CurrencyGroupID))
|
|
{
|
|
m_log.Info("[CURRENCY PROCESS PHP]: Currency purchase is turned off for this user.");
|
|
httpResponse.StatusCode = 403;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Currency purchase is turned off</response>");
|
|
return;
|
|
}
|
|
|
|
m_log.InfoFormat("[CURRENCY PROCESS PHP]: Currency Maximum loaded: {0}", m_CurrencyMaximum);
|
|
|
|
if (methodName == "getCurrencyQuote")
|
|
{
|
|
Hashtable quoteResponse = PerformGetCurrencyQuote(agentId, currencyBuy, secureSessionId);
|
|
|
|
int excessAmount = CheckMaximumMoney(agentId, m_CurrencyMaximum);
|
|
if (excessAmount > 0)
|
|
{
|
|
quoteResponse["message"] = $"Your balance was reduced by {excessAmount} to enforce the maximum limit.";
|
|
}
|
|
|
|
XmlRpcResponse xmlResponse = new XmlRpcResponse { Value = quoteResponse };
|
|
httpResponse.StatusCode = 200;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes(xmlResponse.ToString());
|
|
}
|
|
else if (methodName == "buyCurrency")
|
|
{
|
|
Hashtable purchaseResponse = PerformBuyCurrency(agentId, currencyBuy, secureSessionId);
|
|
|
|
if ((bool)purchaseResponse["success"])
|
|
{
|
|
m_log.Info("[CURRENCY PROCESS PHP]: Purchase successful. Proceeding to credit currency.");
|
|
PerformMoneyTransfer("BANKER", agentId, currencyBuy);
|
|
UpdateBalance(agentId, "Currency purchase successful.");
|
|
|
|
CheckMaximumMoney(agentId, m_CurrencyMaximum);
|
|
|
|
XmlRpcResponse xmlResponse = new XmlRpcResponse { Value = purchaseResponse };
|
|
httpResponse.StatusCode = 200;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes(xmlResponse.ToString());
|
|
}
|
|
else
|
|
{
|
|
m_log.Error("[CURRENCY PROCESS PHP]: Currency purchase failed.");
|
|
httpResponse.StatusCode = 400;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Currency purchase failed</response>");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_log.ErrorFormat("[CURRENCY PROCESS PHP]: Unknown method name: {0}", methodName);
|
|
httpResponse.StatusCode = 400;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Invalid method name</response>");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[CURRENCY PROCESS PHP]: Error processing request. Error: {0}", ex.ToString());
|
|
httpResponse.StatusCode = 500;
|
|
httpResponse.RawBuffer = Encoding.UTF8.GetBytes("<response>Error</response>");
|
|
}
|
|
}
|
|
|
|
|
|
private bool UserMailLock(string userID)
|
|
{
|
|
m_log.InfoFormat("[USER MAIL LOCK]: Checking if user {0} has a registered email address", userID);
|
|
|
|
MySQLSuperManager dbm = GetLockedConnection();
|
|
|
|
try
|
|
{
|
|
// SQL-Abfrage zum Überprüfen, ob der Benutzer eine hinterlegte E-Mail-Adresse hat
|
|
string sql = "SELECT email FROM `UserAccounts` WHERE PrincipalID = ?userID";
|
|
string email = null;
|
|
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?userID", userID);
|
|
|
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
|
{
|
|
if (reader.Read())
|
|
{
|
|
email = reader.GetString("email");
|
|
m_log.InfoFormat("[USER MAIL LOCK]: User {0} email address is {1}", userID, email);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Überprüfen, ob die E-Mail-Adresse leer ist oder null
|
|
if (string.IsNullOrEmpty(email))
|
|
{
|
|
m_log.InfoFormat("[USER MAIL LOCK]: User {0} does not have a registered email address", userID);
|
|
return false; // Benutzer hat keine hinterlegte E-Mail-Adresse
|
|
}
|
|
|
|
m_log.InfoFormat("[USER MAIL LOCK]: User {0} has a registered email address", userID);
|
|
return true; // Benutzer hat eine hinterlegte E-Mail-Adresse
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[USER MAIL LOCK]: Error checking user email: {0}", ex.Message);
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
dbm.Release();
|
|
}
|
|
}
|
|
|
|
private bool CheckGroupMoney(string agentId, string groupId)
|
|
{
|
|
m_log.InfoFormat("[CHECK GROUP MONEY]: Checking group membership for agentId: {0}, groupId: {1}", agentId, groupId);
|
|
|
|
if (string.IsNullOrEmpty(groupId) || groupId == "00000000-0000-0000-0000-000000000000")
|
|
{
|
|
m_log.Info("[CHECK GROUP MONEY]: groupId is empty or set to accept all groups, returning true");
|
|
return true;
|
|
}
|
|
|
|
MySQLSuperManager dbm = GetLockedConnection();
|
|
|
|
try
|
|
{
|
|
string sql = "SELECT COUNT(*) FROM os_groups_membership WHERE PrincipalID = ?agentId AND GroupID = ?groupId";
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?agentId", agentId);
|
|
cmd.Parameters.AddWithValue("?groupId", groupId);
|
|
|
|
int count = Convert.ToInt32(cmd.ExecuteScalar());
|
|
m_log.InfoFormat("[CHECK GROUP MONEY]: Query result: count={0}", count);
|
|
return count > 0;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[CHECK GROUP MONEY]: Error checking group membership: {0}", ex.Message);
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
dbm.Release();
|
|
}
|
|
}
|
|
|
|
|
|
// Überprüfen, ob der Benutzer Mitglied der angegebenen Gruppe ist
|
|
private bool IsUserInGroup(string agentId, string groupId)
|
|
{
|
|
// IClientAPI
|
|
m_log.DebugFormat("[IsUserInGroup]: Checking group membership for agentId={0}, groupId={1}", agentId, groupId);
|
|
|
|
if (string.IsNullOrEmpty(groupId))
|
|
{
|
|
m_log.Debug("[IsUserInGroup]: groupId is empty, returning true");
|
|
return true; // Keine Einschränkung, wenn groupId nicht gesetzt ist
|
|
}
|
|
|
|
MySQLSuperManager dbm = GetLockedConnection();
|
|
|
|
try
|
|
{
|
|
// SQL-Abfrage zum Überprüfen der Gruppenmitgliedschaft
|
|
string sql = "SELECT COUNT(*) FROM os_groups_membership WHERE PrincipalID = ?agentId AND GroupID = ?groupId";
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?agentId", agentId);
|
|
cmd.Parameters.AddWithValue("?groupId", groupId);
|
|
|
|
int count = Convert.ToInt32(cmd.ExecuteScalar());
|
|
m_log.DebugFormat("[IsUserInGroup]: Query result: count={0}", count);
|
|
return count > 0;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[IsUserInGroup]: Error checking group membership: {0}", ex.Message);
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
dbm.Release();
|
|
}
|
|
}
|
|
|
|
public new int CheckMaximumMoney(string userID, int m_CurrencyMaximum)
|
|
{
|
|
MySQLSuperManager dbm = GetLockedConnection();
|
|
m_log.InfoFormat("[CHECK MAXIMUM MONEY]: Checking for userID: {0}, Currency Maximum: {1}", userID, m_CurrencyMaximum);
|
|
|
|
try
|
|
{
|
|
// Ausnahmen für SYSTEM und BANKER
|
|
if (userID == "SYSTEM" || userID == "BANKER" || userID == m_bankerAvatar)
|
|
{
|
|
m_log.InfoFormat("[CHECK MAXIMUM MONEY]: User {0} is SYSTEM or BANKER, skipping check.", userID);
|
|
return 0; // Keine Begrenzung für diese Benutzer
|
|
}
|
|
|
|
// Abrufen des aktuellen Guthabens des Benutzers
|
|
string sql = "SELECT balance FROM balances WHERE user = ?userID";
|
|
int currentBalance = 0;
|
|
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?userID", userID);
|
|
|
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
|
{
|
|
if (reader.Read())
|
|
{
|
|
currentBalance = reader.GetInt32("balance");
|
|
m_log.InfoFormat("[CHECK MAXIMUM MONEY]: Current balance for user {0} is {1}", userID, currentBalance);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Überprüfen, ob das Guthaben über dem Maximum liegt und ggf. abziehen
|
|
if (currentBalance > m_CurrencyMaximum)
|
|
{
|
|
int excessAmount = currentBalance - m_CurrencyMaximum;
|
|
|
|
// Guthaben auf das Maximum reduzieren
|
|
sql = "UPDATE balances SET balance = ?newBalance WHERE user = ?userID";
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?newBalance", m_CurrencyMaximum);
|
|
cmd.Parameters.AddWithValue("?userID", userID);
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
|
|
m_log.InfoFormat("[CHECK MAXIMUM MONEY]: Reduced balance for user {0} by {1} to enforce maximum limit of {2}", userID, excessAmount, m_CurrencyMaximum);
|
|
return excessAmount; // Rückgabe des abgezogenen Betrags
|
|
}
|
|
|
|
m_log.InfoFormat("[CHECK MAXIMUM MONEY]: No adjustment needed for user {0}", userID);
|
|
return 0; // Keine Änderung, falls das Guthaben innerhalb des Limits liegt
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[CHECK MAXIMUM MONEY]: Error checking and updating user balance: {0}", ex.Message);
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
dbm.Release();
|
|
}
|
|
}
|
|
|
|
private Hashtable ExtractXmlRpcParams(XmlDocument doc)
|
|
{
|
|
Hashtable parameters = new Hashtable();
|
|
XmlNodeList members = doc.SelectNodes("//param/value/struct/member");
|
|
|
|
foreach (XmlNode member in members)
|
|
{
|
|
string name = member.SelectSingleNode("name")?.InnerText;
|
|
string value = member.SelectSingleNode("value")?.InnerText;
|
|
|
|
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
|
|
{
|
|
parameters[name] = value;
|
|
}
|
|
}
|
|
return parameters;
|
|
}
|
|
|
|
private Hashtable PerformGetCurrencyQuote(string agentId, int currencyBuy, string secureSessionId)
|
|
{
|
|
m_log.InfoFormat("[PERFORM GET CURRENCY QUOTE]: Generating currency quote for AgentId: {0}", agentId);
|
|
|
|
int rate = 100; // 1 = 100L$
|
|
return new Hashtable
|
|
{
|
|
{ "success", true },
|
|
{ "currency", new Hashtable
|
|
{
|
|
{ "estimatedCost", currencyBuy / rate }, // Kosten in
|
|
{ "currencyBuy", currencyBuy } // Angeforderte Spielwährung
|
|
}
|
|
},
|
|
{ "confirm", Guid.NewGuid().ToString() }
|
|
};
|
|
}
|
|
|
|
private Hashtable PerformBuyCurrency(string agentId, int currencyBuy, string secureSessionId)
|
|
{
|
|
if (string.IsNullOrEmpty(agentId))
|
|
{
|
|
m_log.Error("[PERFORM BUY CURRENCY]: AgentId is null or empty.");
|
|
return new Hashtable
|
|
{
|
|
{ "success", false },
|
|
{ "message", "AgentId is required." }
|
|
};
|
|
}
|
|
|
|
if (currencyBuy <= 0)
|
|
{
|
|
m_log.Error("[PERFORM BUY CURRENCY]: Invalid currencyBuy amount.");
|
|
return new Hashtable
|
|
{
|
|
{ "success", false },
|
|
{ "message", "Invalid currencyBuy amount." }
|
|
};
|
|
}
|
|
|
|
m_log.InfoFormat("[PERFORM BUY CURRENCY]: Processing currency purchase for AgentId: {0}, Amount: {1}", agentId, currencyBuy);
|
|
return new Hashtable
|
|
{
|
|
{ "success", true },
|
|
{ "message", $"Successfully purchased {currencyBuy}L$ for {agentId}" }
|
|
};
|
|
}
|
|
public XmlRpcResponse getCurrencyQuote(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
int amount = 0;
|
|
|
|
// Protokolliere die eingehende XML-Anfrage
|
|
m_log.InfoFormat("[GET CURRENCY QUOTE]: Incoming XML Request: {0}", ToXmlString((Hashtable)request.Params[0]));
|
|
|
|
try
|
|
{
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
amount = (int)requestData["currencyBuy"];
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[GET CURRENCY QUOTE]: Error parsing request: {0}", ex.Message);
|
|
}
|
|
|
|
// Berechnung und Antwortvorbereitung
|
|
Hashtable currencyResponse = new Hashtable
|
|
{
|
|
{ "estimatedCost", amount * 0.01 }, // Berechnung für Kosten
|
|
{ "currencyBuy", amount }
|
|
};
|
|
|
|
Hashtable quoteResponse = new Hashtable
|
|
{
|
|
{ "success", true },
|
|
{ "currency", currencyResponse },
|
|
{ "confirm", Guid.NewGuid().ToString() }
|
|
};
|
|
|
|
// Protokolliere die Antwort, bevor sie zurückgegeben wird
|
|
m_log.InfoFormat("[GET CURRENCY QUOTE]: XML Response: {0}", ToXmlString(quoteResponse));
|
|
|
|
// Erstelle die Antwort
|
|
XmlRpcResponse returnval = new XmlRpcResponse { Value = quoteResponse };
|
|
|
|
// Füge ein weiteres Log hinzu, um sicherzustellen, dass die Antwort korrekt erstellt wurde
|
|
m_log.InfoFormat("[GET CURRENCY QUOTE]: Returning response for getCurrencyQuote: {0}", ToXmlString((Hashtable)returnval.Value));
|
|
|
|
return returnval;
|
|
}
|
|
public XmlRpcResponse buyCurrency(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
string agentId = requestData["agentId"]?.ToString();
|
|
int amount = (int)requestData["currencyBuy"];
|
|
|
|
// Protokolliere die eingehende XML-Anfrage
|
|
m_log.InfoFormat("[BUY CURRENCY]: Incoming XML Request: {0}", ToXmlString((Hashtable)request.Params[0]));
|
|
|
|
// Verarbeite den Kauf und logge die Details
|
|
m_log.InfoFormat("[BUY CURRENCY]: Processing currency purchase for AgentId: {0}, Amount: {1}, Banker: {2}", agentId, amount, m_bankerAvatar);
|
|
|
|
// Hier erfolgt der Transfer an den Money Banker (BankerAvatar als Sender)
|
|
string senderID = m_bankerAvatar; // Der Sender ist der BankerAvatar
|
|
string receiverID = agentId; // Der Empfänger ist der Agent
|
|
UUID transactionUUID = UUID.Random(); // Eine eindeutige Transaktions-ID für die Transaktion
|
|
|
|
Hashtable responseData = new Hashtable();
|
|
responseData["success"] = false;
|
|
|
|
// Versuche, die Transaktion auszuführen
|
|
try
|
|
{
|
|
// Logge die Übertragung
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handlePayMoneyCharge: Transferring money from {0} to {1}, Amount = {2}", senderID, receiverID, amount);
|
|
|
|
// Führe die tatsächliche Transaktion durch, indem die handlePayMoneyCharge-Methode aufgerufen wird
|
|
XmlRpcResponse transferResponse = handlePayMoneyCharge(request, remoteClient); // Übergibt die Anfrage an die tatsächliche Überweisungsmethode
|
|
|
|
// Überprüfe, ob die Antwort erfolgreich war
|
|
if (transferResponse != null && transferResponse.Value is Hashtable transferResult &&
|
|
transferResult.ContainsKey("success") && (bool)transferResult["success"])
|
|
{
|
|
// Wenn die Transaktion erfolgreich war, setze die Antwortdaten
|
|
responseData["success"] = true;
|
|
responseData["message"] = $"Successfully purchased {amount} currency for AgentId {agentId}";
|
|
}
|
|
else
|
|
{
|
|
// Fehler bei der Überweisung
|
|
responseData["message"] = "Currency purchase failed during money transfer.";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
// Fehlerbehandlung
|
|
m_log.Error($"[BUY CURRENCY]: Error processing currency purchase: {ex.Message}");
|
|
responseData["message"] = "Currency purchase failed.";
|
|
}
|
|
|
|
// Erstelle die Antwort
|
|
XmlRpcResponse returnval = new XmlRpcResponse { Value = responseData };
|
|
|
|
// Protokolliere die XML-Antwort
|
|
m_log.InfoFormat("[BUY CURRENCY]: XML Response: {0}", ToXmlString(responseData));
|
|
|
|
return returnval;
|
|
}
|
|
public new bool PerformMoneyTransfer(string senderID, string receiverID, int amount)
|
|
{
|
|
//m_log.InfoFormat("[MONEY TRANSFER]: Transferring {0} from {1} to {2}.", amount, senderID, receiverID);
|
|
try
|
|
{
|
|
MySQLSuperManager dbm = GetLockedConnection();
|
|
string sql = "UPDATE balances SET balance = balance - ?amount WHERE user = ?senderID; " +
|
|
"UPDATE balances SET balance = balance + ?amount WHERE user = ?receiverID";
|
|
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?amount", amount);
|
|
cmd.Parameters.AddWithValue("?senderID", senderID);
|
|
cmd.Parameters.AddWithValue("?receiverID", receiverID);
|
|
|
|
int rowsAffected = cmd.ExecuteNonQuery();
|
|
bool result = (rowsAffected > 0);
|
|
|
|
if (result)
|
|
{
|
|
LogTransaction(UUID.Random(), senderID, -amount);
|
|
LogTransaction(UUID.Random(), receiverID, amount);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
//m_log.ErrorFormat("[MONEY TRANSFER]: Error transferring money: {0}", ex.Message);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public new void InitializeUserCurrency(string agentId)
|
|
{
|
|
m_log.InfoFormat("[INITIALIZE USER CURRENCY]: Initializing currency for new user: {0}", agentId);
|
|
|
|
try
|
|
{
|
|
MySQLSuperManager dbm = GetLockedConnection();
|
|
string sql = "INSERT INTO balances (user, balance) VALUES (?agentId, ?realMoney), (?agentId, ?gameMoney)";
|
|
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?agentId", agentId);
|
|
cmd.Parameters.AddWithValue("?realMoney", m_realMoney);
|
|
cmd.Parameters.AddWithValue("?gameMoney", m_gameMoney);
|
|
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
|
|
m_log.InfoFormat("[INITIALIZE USER CURRENCY]: User {0} initialized with {1} and {2}L$.", agentId, m_realMoney, m_gameMoney);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[INITIALIZE USER CURRENCY]: Error initializing user currency: {0}", ex.Message);
|
|
}
|
|
}
|
|
|
|
public new Hashtable ApplyFallbackCredit(string agentId)
|
|
{
|
|
m_log.WarnFormat("[FALLBACK CREDIT]: Applying fallback credit for user {0}", agentId);
|
|
|
|
try
|
|
{
|
|
MySQLSuperManager dbm = GetLockedConnection();
|
|
string sql = "UPDATE balances SET balance = balance + 100 WHERE user = ?agentId";
|
|
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?agentId", agentId);
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[FALLBACK CREDIT]: Error applying fallback credit: {0}", ex.Message);
|
|
}
|
|
|
|
return new Hashtable
|
|
{
|
|
{ "success", true },
|
|
{ "creditedAmount", 100 },
|
|
{ "message", "Fallback credit applied due to transaction failure." }
|
|
};
|
|
}
|
|
|
|
public bool ValidateTransaction(UUID transactionID, string secureCode)
|
|
{
|
|
// Die Methode ValidateTransfer aus IMoneyDBService verwenden
|
|
bool isValid = ValidateTransfer(secureCode, transactionID);
|
|
if (!isValid)
|
|
{
|
|
m_log.ErrorFormat("[MONEY SERVER]: Transaction validation failed for TransactionID: {0}", transactionID);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public bool AddMoney(UUID transactionUUID)
|
|
{
|
|
// Geld zu einer Transaktion hinzufügen
|
|
bool success = DoAddMoney(transactionUUID);
|
|
if (!success)
|
|
{
|
|
m_log.ErrorFormat("[MONEY SERVER]: Failed to add money for TransactionUUID: {0}", transactionUUID);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public bool WithdrawMoney(UUID transactionID, string senderID, int amount)
|
|
{
|
|
bool success = withdrawMoney(transactionID, senderID, amount);
|
|
if (!success)
|
|
{
|
|
m_log.ErrorFormat("[MONEY SERVER]: Failed to withdraw {0} for sender {1} in TransactionID: {2}", amount, senderID, transactionID);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public bool GiveMoney(UUID transactionID, string receiverID, int amount)
|
|
{
|
|
bool success = giveMoney(transactionID, receiverID, amount);
|
|
if (!success)
|
|
{
|
|
m_log.ErrorFormat("[MONEY SERVER]: Failed to give {0} to receiver {1} in TransactionID: {2}", amount, receiverID, transactionID);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public bool UpdateTransactionStatus(UUID transactionID, int status, string description)
|
|
{
|
|
bool success = updateTransactionStatus(transactionID, status, description);
|
|
if (!success)
|
|
{
|
|
m_log.ErrorFormat("[MONEY SERVER]: Failed to update status for TransactionID: {0} with Status: {1}", transactionID, status);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public bool AddUser(string userID, int balance, int status, int type)
|
|
{
|
|
bool success = addUser(userID, balance, status, type);
|
|
if (!success)
|
|
{
|
|
m_log.ErrorFormat("[MONEY SERVER]: Failed to add user {0} with balance {1}", userID, balance);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public new IEnumerable<TransactionData> GetTransactionHistory(string userID, int startTime, int endTime)
|
|
{
|
|
return GetTransactionHistory(userID, startTime, endTime);
|
|
}
|
|
public new UserInfo FetchUserInfo(string userID)
|
|
{
|
|
return FetchUserInfo(userID);
|
|
}
|
|
public new bool UserExists(string userID)
|
|
{
|
|
return UserExists(userID);
|
|
}
|
|
public bool PerformTransaction(UUID transactionUUID)
|
|
{
|
|
bool success = DoTransfer(transactionUUID);
|
|
if (!success)
|
|
{
|
|
m_log.ErrorFormat("[MONEY SERVER]: Failed to perform transaction for TransactionUUID: {0}", transactionUUID);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public static bool IsValidEmail(string email)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(email))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Regular Expression für gültige E-Mail-Adressen
|
|
const string pattern = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$";
|
|
|
|
// Überprüfen, ob die E-Mail-Adresse das Muster erfüllt
|
|
return Regex.IsMatch(email, pattern, RegexOptions.Compiled);
|
|
}
|
|
|
|
private Dictionary<UUID, int> balances = new Dictionary<UUID, int>();
|
|
|
|
public int GetBalance(UUID uuid)
|
|
{
|
|
if (balances.TryGetValue(uuid, out int balance))
|
|
{
|
|
return balance;
|
|
}
|
|
else
|
|
{
|
|
// Return a default value if the UUID is not found
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public void SetBalance(UUID uuid, int balance)
|
|
{
|
|
balances[uuid] = balance;
|
|
}
|
|
|
|
#endregion
|
|
// ################## XMLRPC Pasing ##################
|
|
#region XMLRPC Pasing
|
|
|
|
|
|
public static string ToXmlStringMini(Hashtable data)
|
|
{
|
|
XmlDocument doc = new XmlDocument();
|
|
XmlElement root = doc.CreateElement("methodResponse");
|
|
doc.AppendChild(root);
|
|
|
|
XmlElement paramsElement = doc.CreateElement("params");
|
|
root.AppendChild(paramsElement);
|
|
|
|
foreach (DictionaryEntry entry in data)
|
|
{
|
|
XmlElement param = doc.CreateElement("param");
|
|
XmlElement value = doc.CreateElement("value");
|
|
value.InnerText = entry.Value.ToString();
|
|
param.AppendChild(value);
|
|
paramsElement.AppendChild(param);
|
|
}
|
|
|
|
return doc.OuterXml;
|
|
}
|
|
private string ToXmlString(Hashtable data)
|
|
{
|
|
XmlDocument doc = new XmlDocument();
|
|
XmlNode methodCallNode = doc.CreateElement("methodCall");
|
|
|
|
XmlNode methodNameNode = doc.CreateElement("methodName");
|
|
methodNameNode.InnerText = "response";
|
|
methodCallNode.AppendChild(methodNameNode);
|
|
|
|
XmlNode paramsNode = doc.CreateElement("params");
|
|
foreach (DictionaryEntry entry in data)
|
|
{
|
|
XmlNode paramNode = doc.CreateElement("param");
|
|
|
|
XmlNode valueNode = doc.CreateElement("value");
|
|
if (entry.Value is Hashtable)
|
|
{
|
|
XmlNode structNode = doc.CreateElement("struct");
|
|
foreach (DictionaryEntry structEntry in (Hashtable)entry.Value)
|
|
{
|
|
XmlNode memberNode = doc.CreateElement("member");
|
|
XmlNode nameNode = doc.CreateElement("name");
|
|
nameNode.InnerText = structEntry.Key.ToString();
|
|
XmlNode valueNode2 = doc.CreateElement("value");
|
|
valueNode2.InnerText = structEntry.Value.ToString();
|
|
memberNode.AppendChild(nameNode);
|
|
memberNode.AppendChild(valueNode2);
|
|
structNode.AppendChild(memberNode);
|
|
}
|
|
valueNode.AppendChild(structNode);
|
|
}
|
|
else
|
|
{
|
|
valueNode.InnerText = entry.Value.ToString();
|
|
}
|
|
|
|
paramNode.AppendChild(valueNode);
|
|
paramsNode.AppendChild(paramNode);
|
|
}
|
|
|
|
methodCallNode.AppendChild(paramsNode);
|
|
doc.AppendChild(methodCallNode);
|
|
return doc.OuterXml;
|
|
}
|
|
|
|
// Methode zur Verarbeitung und Parsing der XML-RPC-Anfrage
|
|
private object ParseXmlRpcRequest(string xml)
|
|
{
|
|
XmlDocument doc = new XmlDocument();
|
|
doc.LoadXml(xml);
|
|
|
|
XmlNode methodCallNode = doc.SelectSingleNode("/methodCall");
|
|
XmlNode methodNameNode = methodCallNode.SelectSingleNode("methodName");
|
|
|
|
if (methodNameNode == null)
|
|
throw new Exception("Missing method name");
|
|
|
|
string methodName = methodNameNode.InnerText;
|
|
XmlNodeList members = methodCallNode.SelectNodes("//param/value/struct/member");
|
|
|
|
if (methodName == "getCurrencyQuote")
|
|
{
|
|
CurrencyQuoteRequest request = new CurrencyQuoteRequest();
|
|
foreach (XmlNode member in members)
|
|
{
|
|
string name = member.SelectSingleNode("name").InnerText;
|
|
string value = member.SelectSingleNode("value").InnerText;
|
|
|
|
switch (name)
|
|
{
|
|
case "agentId": request.AgentId = value; break;
|
|
case "currencyBuy": request.CurrencyBuy = int.Parse(value); break;
|
|
case "language": request.Language = value; break;
|
|
case "secureSessionId": request.SecureSessionId = value; break;
|
|
case "viewerBuildVersion": request.ViewerBuildVersion = value; break;
|
|
case "viewerChannel": request.ViewerChannel = value; break;
|
|
case "viewerMajorVersion": request.ViewerMajorVersion = int.Parse(value); break;
|
|
case "viewerMinorVersion": request.ViewerMinorVersion = int.Parse(value); break;
|
|
case "viewerPatchVersion": request.ViewerPatchVersion = int.Parse(value); break;
|
|
}
|
|
}
|
|
m_log.InfoFormat("[MONEY XML RPC MODULE]: Processed Currency Quote Request for AgentId: {0}", request.AgentId);
|
|
return request;
|
|
|
|
}
|
|
else if (methodName == "preflightBuyLandPrep")
|
|
{
|
|
LandPurchaseRequest request = new LandPurchaseRequest();
|
|
foreach (XmlNode member in members)
|
|
{
|
|
string name = member.SelectSingleNode("name").InnerText;
|
|
string value = member.SelectSingleNode("value").InnerText;
|
|
|
|
switch (name)
|
|
{
|
|
case "agentId": request.AgentId = value; break;
|
|
case "billableArea": request.BillableArea = int.Parse(value); break;
|
|
case "currencyBuy": request.CurrencyBuy = int.Parse(value); break;
|
|
case "language": request.Language = value; break;
|
|
case "secureSessionId": request.SecureSessionId = value; break;
|
|
}
|
|
}
|
|
m_log.InfoFormat("[MONEY XML RPC MODULE]: Processed Land Purchase Request for AgentId: {0}, BillableArea: {1}", request.AgentId, request.BillableArea);
|
|
return request;
|
|
}
|
|
m_log.ErrorFormat("[MONEY XML RPC MODULE]: Unknown method name: {0}", methodName);
|
|
throw new Exception("Unknown method name: " + methodName);
|
|
}
|
|
|
|
|
|
private void LogXmlRpcRequestFile(IOSHttpRequest request)
|
|
{
|
|
try
|
|
{
|
|
// Erstelle einen Dateipfad für das Log
|
|
string logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "xmlrpc_debug.log");
|
|
|
|
// Lies den Request-Body
|
|
string requestBody;
|
|
using (var reader = new StreamReader(request.InputStream, Encoding.UTF8))
|
|
{
|
|
requestBody = reader.ReadToEnd();
|
|
}
|
|
|
|
// Bereite den Logeintrag vor
|
|
string logEntry = $"{DateTime.UtcNow}: {request.RawUrl}\n{requestBody}\n\n";
|
|
|
|
// Schreibe den Logeintrag in die Datei
|
|
File.AppendAllText(logFilePath, logEntry);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XML RPC MODULE DEBUG]: Error logging XML-RPC request: {0}", ex.Message);
|
|
}
|
|
}
|
|
|
|
private void LogXmlRpcRequestConsole(IOSHttpRequest request)
|
|
{
|
|
m_log.InfoFormat("[MONEY XML RPC MODULE]: {0}", new StreamReader(request.InputStream).ReadToEnd()); // TODO: test
|
|
|
|
try
|
|
{
|
|
// Lies den Request-Body
|
|
string requestBody;
|
|
using (var reader = new StreamReader(request.InputStream, Encoding.UTF8))
|
|
{
|
|
requestBody = reader.ReadToEnd();
|
|
}
|
|
|
|
// Bereite den Logeintrag vor
|
|
string logEntry = $"{DateTime.UtcNow}: {request.RawUrl}\n{requestBody}\n\n";
|
|
|
|
// Schreibe den Logeintrag in das Log
|
|
m_log.Info(logEntry);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XML RPC MODULE DEBUG]: Error logging XML-RPC request: {0}", ex.Message);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
// ################## Cashbook ##################
|
|
#region Cashbook
|
|
|
|
public List<CashbookEntry> GetCashbook(string userID, int limit = 20)
|
|
{
|
|
List<CashbookEntry> cashbook = new List<CashbookEntry>();
|
|
string query = "SELECT time, description, amount, sender, receiver FROM transactions WHERE sender = ?userID OR receiver = ?userID ORDER BY time ASC LIMIT ?limit";
|
|
|
|
MySQLSuperManager dbm = ((MoneyDBService)m_moneyDBService).GetLockedConnection();
|
|
int saldo = 0;
|
|
|
|
try
|
|
{
|
|
using (MySqlCommand cmd = new MySqlCommand(query, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?userID", userID);
|
|
cmd.Parameters.AddWithValue("?limit", limit);
|
|
|
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
int amount = reader.GetInt32("amount");
|
|
string sender = reader.GetString("sender");
|
|
string receiver = reader.GetString("receiver");
|
|
string description = !reader.IsDBNull(reader.GetOrdinal("description")) ? reader.GetString("description") : "";
|
|
|
|
bool isIncome = userID == receiver;
|
|
bool isExpense = userID == sender;
|
|
|
|
int? income = isIncome ? amount : (int?)null;
|
|
int? expense = isExpense ? amount : (int?)null;
|
|
|
|
saldo += (isIncome ? amount : 0) - (isExpense ? amount : 0);
|
|
|
|
var entry = new CashbookEntry
|
|
{
|
|
Date = UnixTimeStampToDateTime(reader.GetInt32("time")).ToString("yyyy-MM-dd"),
|
|
Description = description,
|
|
Income = isIncome ? amount : (int?)null,
|
|
Expense = isExpense ? amount : (int?)null,
|
|
Balance = saldo
|
|
};
|
|
cashbook.Add(entry);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[Cashbook]: Error building cashbook for userID: {0}. Exception: {1}", userID, ex);
|
|
}
|
|
finally
|
|
{
|
|
dbm.Release();
|
|
}
|
|
return cashbook;
|
|
}
|
|
|
|
// Hilfsfunktion:
|
|
private DateTime UnixTimeStampToDateTime(int unixTimeStamp)
|
|
{
|
|
System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
|
|
dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime();
|
|
return dtDateTime;
|
|
}
|
|
|
|
#endregion
|
|
|
|
// ################## handler ##################
|
|
#region handler
|
|
|
|
|
|
// Im Konstruktor oder Init registrieren:
|
|
// new JsonStreamHandler("/api/cashbook", CashbookRequestHandler);
|
|
|
|
private void CashbookRequestHandler(IOSHttpRequest req, IOSHttpResponse resp)
|
|
{
|
|
m_log.Info("[CASHBOOK HANDLER]: CashbookRequestHandler gestartet");
|
|
|
|
// Schritt 1: Request-Body einlesen
|
|
string requestBody;
|
|
using (var reader = new StreamReader(req.InputStream, Encoding.UTF8))
|
|
{
|
|
requestBody = reader.ReadToEnd();
|
|
}
|
|
|
|
// Schritt 2: JSON parsen
|
|
string userID = null;
|
|
int limit = 20;
|
|
try
|
|
{
|
|
using (JsonDocument doc = JsonDocument.Parse(requestBody))
|
|
{
|
|
JsonElement root = doc.RootElement;
|
|
if (root.TryGetProperty("userID", out JsonElement userIdProp))
|
|
userID = userIdProp.GetString();
|
|
if (root.TryGetProperty("limit", out JsonElement limitProp) && limitProp.TryGetInt32(out int l))
|
|
limit = l;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
resp.StatusCode = 400;
|
|
resp.RawBuffer = Encoding.UTF8.GetBytes("{\"success\":false,\"error\":\"Ungültiges JSON.\"}");
|
|
m_log.ErrorFormat("[CASHBOOK HANDLER]: JSON Fehler: {0}", ex.Message);
|
|
return;
|
|
}
|
|
|
|
// Schritt 3: Parameter validieren
|
|
if (string.IsNullOrWhiteSpace(userID))
|
|
{
|
|
resp.StatusCode = 400;
|
|
resp.RawBuffer = Encoding.UTF8.GetBytes("{\"success\":false,\"error\":\"Missing userID\"}");
|
|
return;
|
|
}
|
|
|
|
// Schritt 4: Cashbook abrufen (Service-Layer)
|
|
List<CashbookEntry> cashbook = null;
|
|
try
|
|
{
|
|
cashbook = m_moneyDBService.FetchCashbook(userID, limit);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
resp.StatusCode = 500;
|
|
resp.RawBuffer = Encoding.UTF8.GetBytes("{\"success\":false,\"error\":\"Serverfehler bei Datenbankabfrage.\"}");
|
|
m_log.ErrorFormat("[CASHBOOK HANDLER]: DB Fehler: {0}", ex.Message);
|
|
return;
|
|
}
|
|
|
|
// Schritt 5: Antwort senden
|
|
var responseObj = new
|
|
{
|
|
success = true,
|
|
userID = userID,
|
|
cashbook = cashbook
|
|
};
|
|
string responseJson = JsonSerializer.Serialize(responseObj);
|
|
resp.StatusCode = 200;
|
|
resp.RawBuffer = Encoding.UTF8.GetBytes(responseJson);
|
|
}
|
|
|
|
private void JsonApiProcess(IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
|
|
{
|
|
m_log.Info("[JSON API] Request erhalten!");
|
|
|
|
try
|
|
{
|
|
string body;
|
|
using (var reader = new StreamReader(httpRequest.InputStream, Encoding.UTF8))
|
|
body = reader.ReadToEnd();
|
|
|
|
m_log.Info($"[JSON API] Empfangenes JSON: {body}");
|
|
|
|
JsonElement json;
|
|
try
|
|
{
|
|
json = JsonDocument.Parse(body).RootElement;
|
|
}
|
|
catch (Exception parseEx)
|
|
{
|
|
m_log.Warn($"[JSON API] Fehler beim JSON-Parsing: {parseEx.Message}");
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Invalid JSON" });
|
|
return;
|
|
}
|
|
|
|
// Authentifizierung prüfen
|
|
string apiKeyFromRequest = null;
|
|
string allowedUserFromRequest = null;
|
|
bool apiKeyOk = TryGetProperty(json, "apiKey", out apiKeyFromRequest);
|
|
bool allowedUserOk = TryGetProperty(json, "allowedUser", out allowedUserFromRequest);
|
|
|
|
if (!apiKeyOk || !allowedUserOk ||
|
|
string.IsNullOrWhiteSpace(m_scriptApiKey) ||
|
|
string.IsNullOrWhiteSpace(m_scriptAllowedUser) ||
|
|
apiKeyFromRequest != m_scriptApiKey ||
|
|
allowedUserFromRequest != m_scriptAllowedUser)
|
|
{
|
|
m_log.Warn($"[JSON API] Authentifizierung fehlgeschlagen. apiKey: {apiKeyFromRequest}, allowedUser: {allowedUserFromRequest}");
|
|
SetJsonResponse(httpResponse, 401, new { success = false, error = "Unauthorized" });
|
|
return;
|
|
}
|
|
|
|
// Action & userID prüfen (sofern nötig)
|
|
if (!TryGetProperty(json, "action", out string action))
|
|
{
|
|
m_log.Warn("[JSON API] action fehlt in der Anfrage.");
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing action" });
|
|
return;
|
|
}
|
|
string userID = TryGetProperty(json, "userID", out string uID) ? uID : null;
|
|
|
|
m_log.Info($"[JSON API] action={action} userID={userID}");
|
|
|
|
switch (action)
|
|
{
|
|
case "getCashbook":
|
|
{
|
|
// userID konsistent holen (wie in anderen Cases)
|
|
if (!TryGetProperty(json, "userID", out string cashbookUserId))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID" });
|
|
return;
|
|
}
|
|
|
|
int limit = 20;
|
|
if (TryGetInt(json, "limit", out int parsedLimit))
|
|
limit = parsedLimit;
|
|
|
|
var cashbook = GetCashbook(cashbookUserId, limit);
|
|
|
|
SetJsonResponse(httpResponse, 200, new
|
|
{
|
|
success = true,
|
|
userID = cashbookUserId,
|
|
cashbook = cashbook
|
|
});
|
|
return;
|
|
}
|
|
|
|
case "getbalance":
|
|
if (string.IsNullOrEmpty(userID))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID" });
|
|
return;
|
|
}
|
|
int balance = m_moneyDBService.getBalance(userID);
|
|
SetJsonResponse(httpResponse, 200, new { success = true, balance });
|
|
break;
|
|
|
|
case "getTransactionNum":
|
|
if (string.IsNullOrEmpty(userID) ||
|
|
!TryGetInt(json, "startTime", out int stT) ||
|
|
!TryGetInt(json, "endTime", out int enT))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID, startTime or endTime" });
|
|
return;
|
|
}
|
|
int num = m_moneyDBService.getTransactionNum(userID, stT, enT);
|
|
SetJsonResponse(httpResponse, 200, new { success = true, num }); // Feldname: num
|
|
break;
|
|
|
|
case "UserExists":
|
|
if (string.IsNullOrEmpty(userID))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID" });
|
|
return;
|
|
}
|
|
bool exists = m_moneyDBService.UserExists(userID);
|
|
SetJsonResponse(httpResponse, 200, new { exists = exists });
|
|
break;
|
|
|
|
case "withdrawMoney":
|
|
if (string.IsNullOrEmpty(userID) ||
|
|
!TryGetGuid(json, "transactionID", out Guid withdrawTid) ||
|
|
!TryGetInt(json, "amount", out int withdrawAmount))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID, transactionID or amount" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
if (!m_moneyDBService.UserExists(userID))
|
|
{
|
|
SetJsonResponse(httpResponse, 404, new { success = false, error = "User not found" });
|
|
return;
|
|
}
|
|
bool wSuccess = m_moneyDBService.withdrawMoney(withdrawTid, userID, withdrawAmount);
|
|
SetJsonResponse(httpResponse, wSuccess ? 200 : 400, new { success = wSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "giveMoney":
|
|
if (!TryGetGuid(json, "transactionID", out Guid giveTid) ||
|
|
!TryGetProperty(json, "receiverID", out string receiverID) ||
|
|
!TryGetInt(json, "amount", out int giveAmount))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing transactionID, receiverID or amount" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
bool gSuccess = m_moneyDBService.giveMoney(giveTid, receiverID, giveAmount);
|
|
SetJsonResponse(httpResponse, gSuccess ? 200 : 400, new { success = gSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "BuyMoney":
|
|
if (string.IsNullOrEmpty(userID) ||
|
|
!TryGetGuid(json, "transactionID", out Guid buyTid) ||
|
|
!TryGetInt(json, "amount", out int buyAmount))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID, transactionID or amount" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
bool bSuccess = m_moneyDBService.BuyMoney(buyTid, userID, buyAmount);
|
|
SetJsonResponse(httpResponse, bSuccess ? 200 : 400, new { success = bSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "addTransaction":
|
|
if (!json.TryGetProperty("transaction", out JsonElement transactionElement))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing transaction" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
var transactionObj = JsonSerializer.Deserialize<TransactionData>(transactionElement.GetRawText());
|
|
bool tSuccess = m_moneyDBService.addTransaction(transactionObj);
|
|
SetJsonResponse(httpResponse, tSuccess ? 200 : 400, new { success = tSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "addUser":
|
|
if (string.IsNullOrEmpty(userID) ||
|
|
!TryGetInt(json, "balance", out int addBalance) ||
|
|
!TryGetInt(json, "status", out int addStatus) ||
|
|
!TryGetInt(json, "type", out int addType))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID, balance, status or type" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
if (m_moneyDBService.UserExists(userID))
|
|
{
|
|
SetJsonResponse(httpResponse, 409, new { success = false, error = "User already exists" });
|
|
return;
|
|
}
|
|
bool aSuccess = m_moneyDBService.addUser(userID, addBalance, addStatus, addType);
|
|
SetJsonResponse(httpResponse, aSuccess ? 200 : 400, new { success = aSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "BuyCurrency":
|
|
if (string.IsNullOrEmpty(userID) ||
|
|
!TryGetInt(json, "amount", out int buyCurrencyAmount))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID or amount" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
bool bcSuccess = m_moneyDBService.BuyCurrency(userID, buyCurrencyAmount);
|
|
SetJsonResponse(httpResponse, bcSuccess ? 200 : 400, new { success = bcSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "SetTransExpired":
|
|
if (!TryGetInt(json, "deadTime", out int deadTime))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing deadTime" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
bool seSuccess = m_moneyDBService.SetTransExpired(deadTime);
|
|
SetJsonResponse(httpResponse, seSuccess ? 200 : 400, new { success = seSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "ValidateTransfer":
|
|
if (!TryGetProperty(json, "secureCode", out string secureCode) ||
|
|
!TryGetGuid(json, "transactionID", out Guid valTid))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing secureCode or transactionID" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
bool valid = m_moneyDBService.ValidateTransfer(secureCode, valTid);
|
|
SetJsonResponse(httpResponse, 200, new { valid = valid });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "FetchUserInfo":
|
|
if (string.IsNullOrEmpty(userID))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID" });
|
|
return;
|
|
}
|
|
var userInfo = m_moneyDBService.FetchUserInfo(userID);
|
|
if (userInfo != null)
|
|
{
|
|
SetJsonResponse(httpResponse, 200, new
|
|
{
|
|
userID = userInfo.UserID, // Nur EIN Feld!
|
|
SimIP = userInfo.SimIP,
|
|
Avatar = userInfo.Avatar,
|
|
PswHash = userInfo.PswHash,
|
|
Type = userInfo.Type,
|
|
Class = userInfo.Class,
|
|
ServerURL = userInfo.ServerURL
|
|
});
|
|
}
|
|
else
|
|
{
|
|
SetJsonResponse(httpResponse, 404, new { success = false, error = "User not found" });
|
|
}
|
|
break;
|
|
|
|
case "updateTransactionStatus":
|
|
if (string.IsNullOrEmpty(userID) ||
|
|
!TryGetGuid(json, "transactionID", out Guid updTid) ||
|
|
!TryGetInt(json, "status", out int updStatus) ||
|
|
!TryGetProperty(json, "description", out string updDescription))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID, transactionID, status or description" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
bool uSuccess = m_moneyDBService.updateTransactionStatus(updTid, updStatus, updDescription);
|
|
SetJsonResponse(httpResponse, uSuccess ? 200 : 400, new { success = uSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "DoTransfer":
|
|
if (!TryGetGuid(json, "transactionID", out Guid doTransferTid))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing transactionID" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
bool dtSuccess = m_moneyDBService.DoTransfer(doTransferTid);
|
|
SetJsonResponse(httpResponse, dtSuccess ? 200 : 400, new { success = dtSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "DoAddMoney":
|
|
if (!TryGetGuid(json, "transactionID", out Guid doAddTid))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing transactionID" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
bool daSuccess = m_moneyDBService.DoAddMoney(doAddTid);
|
|
SetJsonResponse(httpResponse, daSuccess ? 200 : 400, new { success = daSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "FetchTransaction":
|
|
if (string.IsNullOrEmpty(userID) ||
|
|
!TryGetInt(json, "startTime", out int ftStartTime) ||
|
|
!TryGetInt(json, "endTime", out int ftEndTime) ||
|
|
!TryGetInt(json, "lastIndex", out int lastIndex))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID, startTime, endTime or lastIndex" });
|
|
return;
|
|
}
|
|
var transaction = m_moneyDBService.FetchTransaction(userID, ftStartTime, ftEndTime, lastIndex);
|
|
if (transaction != null)
|
|
{
|
|
SetJsonResponse(httpResponse, 200, new { transactions = new[] { transaction } });
|
|
}
|
|
else
|
|
{
|
|
SetJsonResponse(httpResponse, 404, new { success = false, error = "No transaction found", transactions = new object[0] });
|
|
}
|
|
break;
|
|
|
|
case "TryAddUserInfo":
|
|
if (!json.TryGetProperty("user", out JsonElement userElem))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing user" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
var userInfoObj = JsonSerializer.Deserialize<UserInfo>(userElem.GetRawText());
|
|
bool taSuccess = m_moneyDBService.TryAddUserInfo(userInfoObj);
|
|
SetJsonResponse(httpResponse, taSuccess ? 200 : 400, new { success = taSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
case "UpdateUserInfo":
|
|
if (string.IsNullOrEmpty(userID) ||
|
|
!json.TryGetProperty("user", out JsonElement upUserElem))
|
|
{
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Missing userID or user" });
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
var updatedInfo = JsonSerializer.Deserialize<UserInfo>(upUserElem.GetRawText());
|
|
bool upSuccess = m_moneyDBService.UpdateUserInfo(userID, updatedInfo);
|
|
SetJsonResponse(httpResponse, upSuccess ? 200 : 400, new { success = upSuccess });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
break;
|
|
|
|
default:
|
|
SetJsonResponse(httpResponse, 400, new { success = false, error = "Invalid action" });
|
|
break;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.Error($"[JSON API] Ausnahme: {ex}");
|
|
SetJsonResponse(httpResponse, 500, new { success = false, error = ex.Message });
|
|
}
|
|
}
|
|
|
|
#region Hilfsmethoden
|
|
|
|
private void SetJsonResponse(IOSHttpResponse response, int statusCode, object obj)
|
|
{
|
|
response.StatusCode = statusCode;
|
|
response.RawBuffer = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(obj));
|
|
response.ContentType = "application/json";
|
|
}
|
|
|
|
private bool TryGetProperty(JsonElement json, string key, out string value)
|
|
{
|
|
value = null;
|
|
if (json.TryGetProperty(key, out var prop) && prop.ValueKind == JsonValueKind.String)
|
|
{
|
|
value = prop.GetString();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool TryGetInt(JsonElement json, string key, out int value)
|
|
{
|
|
value = 0;
|
|
if (json.TryGetProperty(key, out var prop) && prop.ValueKind == JsonValueKind.Number)
|
|
{
|
|
return prop.TryGetInt32(out value);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool TryGetGuid(JsonElement json, string key, out Guid value)
|
|
{
|
|
value = Guid.Empty;
|
|
if (TryGetProperty(json, key, out string str) && Guid.TryParse(str, out value))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
#region Action-Handler (Beispiele, du kannst sie beliebig erweitern)
|
|
|
|
private void HandleGetBalance(IOSHttpResponse response, string userID)
|
|
{
|
|
int balance = m_moneyDBService.getBalance(userID);
|
|
SetJsonResponse(response, 200, new { success = true, balance });
|
|
}
|
|
|
|
private void HandleWithdrawMoney(IOSHttpResponse response, Guid transactionID, string userID, int amount)
|
|
{
|
|
bool success = m_moneyDBService.withdrawMoney(transactionID, userID, amount);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleGiveMoney(IOSHttpResponse response, Guid transactionID, string receiverID, int amount)
|
|
{
|
|
bool success = m_moneyDBService.giveMoney(transactionID, receiverID, amount);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleBuyMoney(IOSHttpResponse response, Guid transactionID, string userID, int amount)
|
|
{
|
|
bool success = m_moneyDBService.BuyMoney(transactionID, userID, amount);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleBuyCurrency(IOSHttpResponse response, string userID, int amount)
|
|
{
|
|
bool success = m_moneyDBService.BuyCurrency(userID, amount);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleAddTransaction(IOSHttpResponse response, TransactionData transaction)
|
|
{
|
|
bool success = m_moneyDBService.addTransaction(transaction);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleAddUser(IOSHttpResponse response, string userID, int balance, int status, int type)
|
|
{
|
|
bool success = m_moneyDBService.addUser(userID, balance, status, type);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleUpdateTransactionStatus(IOSHttpResponse response, Guid transactionID, int status, string description)
|
|
{
|
|
bool success = m_moneyDBService.updateTransactionStatus(transactionID, status, description);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleSetTransExpired(IOSHttpResponse response, int deadTime)
|
|
{
|
|
bool success = m_moneyDBService.SetTransExpired(deadTime);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleValidateTransfer(IOSHttpResponse response, string secureCode, Guid transactionID)
|
|
{
|
|
bool success = m_moneyDBService.ValidateTransfer(secureCode, transactionID);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleGetTransactionNum(IOSHttpResponse response, string userID, int startTime, int endTime)
|
|
{
|
|
int count = m_moneyDBService.getTransactionNum(userID, startTime, endTime);
|
|
SetJsonResponse(response, 200, new { success = true, count });
|
|
}
|
|
|
|
private void HandleDoTransfer(IOSHttpResponse response, Guid transactionID)
|
|
{
|
|
bool success = m_moneyDBService.DoTransfer(transactionID);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleDoAddMoney(IOSHttpResponse response, Guid transactionID)
|
|
{
|
|
bool success = m_moneyDBService.DoAddMoney(transactionID);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleTryAddUserInfo(IOSHttpResponse response, UserInfo user)
|
|
{
|
|
bool success = m_moneyDBService.TryAddUserInfo(user);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
private void HandleFetchTransaction(IOSHttpResponse response, string userID, int startTime, int endTime, int lastIndex)
|
|
{
|
|
var transactions = m_moneyDBService.FetchTransaction(userID, startTime, endTime, lastIndex);
|
|
SetJsonResponse(response, 200, transactions);
|
|
}
|
|
|
|
private void HandleFetchUserInfo(IOSHttpResponse response, string userID)
|
|
{
|
|
var userInfo = m_moneyDBService.FetchUserInfo(userID);
|
|
SetJsonResponse(response, 200, userInfo);
|
|
}
|
|
|
|
private void HandleUserExists(IOSHttpResponse response, string userID)
|
|
{
|
|
bool exists = m_moneyDBService.UserExists(userID);
|
|
SetJsonResponse(response, 200, new { exists });
|
|
}
|
|
|
|
private void HandleUpdateUserInfo(IOSHttpResponse response, string userID, UserInfo updatedInfo)
|
|
{
|
|
bool success = m_moneyDBService.UpdateUserInfo(userID, updatedInfo);
|
|
SetJsonResponse(response, success ? 200 : 400, new { success });
|
|
}
|
|
|
|
#endregion
|
|
|
|
// Du kannst die Handler (Handle...) beliebig erweitern oder anpassen, je nachdem was dein m_moneyDBService anbietet.
|
|
|
|
|
|
// Spezifische Handler BalanceUpdateHandler: Verarbeitet Updates zum Kontostand.
|
|
public XmlRpcResponse BalanceUpdateHandler(XmlRpcRequest request, IPEndPoint client)
|
|
{
|
|
if (request == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: BalanceUpdateHandler: request is null.");
|
|
return new XmlRpcResponse();
|
|
}
|
|
|
|
if (client == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: BalanceUpdateHandler: client is null.");
|
|
return new XmlRpcResponse();
|
|
}
|
|
|
|
try
|
|
{
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
string balanceUpdateData = (string)requestData["balanceUpdateData"];
|
|
|
|
// Process the balance update data
|
|
m_log.InfoFormat("[MONEY XMLRPC]: BalanceUpdateHandler: Updating balance for user {0}", balanceUpdateData);
|
|
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
responseData.Add("success", true);
|
|
response.Value = responseData;
|
|
return response;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: BalanceUpdateHandler: Exception occurred: {0}", ex.Message);
|
|
return new XmlRpcResponse();
|
|
}
|
|
}
|
|
|
|
// Spezifische Handler UserAlertHandler: Handhabt Benutzerbenachrichtigungen.
|
|
public XmlRpcResponse UserAlertHandler(XmlRpcRequest request, IPEndPoint client)
|
|
{
|
|
try
|
|
{
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
string alertMessage = (string)requestData["alertMessage"];
|
|
|
|
// Process the alert message
|
|
m_log.InfoFormat("[MONEY XMLRPC]: UserAlertHandler: Alert message received: {0}", alertMessage);
|
|
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
responseData.Add("success", true);
|
|
response.Value = responseData;
|
|
return response;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: UserAlertHandler: Exception occurred: {0}", ex.Message);
|
|
return new XmlRpcResponse();
|
|
}
|
|
}
|
|
|
|
public XmlRpcResponse handleClientLogin(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogin: Start.");
|
|
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
responseData["success"] = false;
|
|
responseData["clientBalance"] = 0;
|
|
|
|
// Check Client Cert
|
|
if (m_moneyCore.IsCheckClientCert())
|
|
{
|
|
string commonName = GetSSLCommonName();
|
|
if (commonName == "")
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleClientLogin: Warnning: Check Client Cert is set, but SSL Common Name is empty.");
|
|
responseData["success"] = false;
|
|
responseData["description"] = "SSL Common Name is empty";
|
|
return response;
|
|
}
|
|
else
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogin: SSL Common Name is \"{0}\"", commonName);
|
|
}
|
|
|
|
}
|
|
|
|
string universalID = string.Empty;
|
|
string clientUUID = string.Empty;
|
|
string sessionID = string.Empty;
|
|
string secureID = string.Empty;
|
|
string simIP = string.Empty;
|
|
string userName = string.Empty;
|
|
int balance = 0;
|
|
int avatarType = (int)AvatarType.UNKNOWN_AVATAR;
|
|
int avatarClass = (int)AvatarType.UNKNOWN_AVATAR;
|
|
|
|
if (requestData.ContainsKey("clientUUID")) clientUUID = (string)requestData["clientUUID"];
|
|
if (requestData.ContainsKey("clientSessionID")) sessionID = (string)requestData["clientSessionID"];
|
|
if (requestData.ContainsKey("clientSecureSessionID")) secureID = (string)requestData["clientSecureSessionID"];
|
|
if (requestData.ContainsKey("universalID")) universalID = (string)requestData["universalID"];
|
|
if (requestData.ContainsKey("userName")) userName = (string)requestData["userName"];
|
|
if (requestData.ContainsKey("openSimServIP")) simIP = (string)requestData["openSimServIP"];
|
|
if (requestData.ContainsKey("avatarType")) avatarType = Convert.ToInt32(requestData["avatarType"]);
|
|
if (requestData.ContainsKey("avatarClass")) avatarClass = Convert.ToInt32(requestData["avatarClass"]);
|
|
|
|
string firstName = string.Empty;
|
|
string lastName = string.Empty;
|
|
string serverURL = string.Empty;
|
|
string securePsw = string.Empty;
|
|
|
|
if (!String.IsNullOrEmpty(universalID))
|
|
{
|
|
UUID uuid;
|
|
Util.ParseUniversalUserIdentifier(universalID, out uuid, out serverURL, out firstName, out lastName, out securePsw);
|
|
}
|
|
if (String.IsNullOrEmpty(userName))
|
|
{
|
|
userName = firstName + " " + lastName;
|
|
}
|
|
|
|
// Information from DB
|
|
UserInfo userInfo = m_moneyDBService.FetchUserInfo(clientUUID);
|
|
if (userInfo != null)
|
|
{
|
|
avatarType = userInfo.Type; // Avatar Type is not updated
|
|
if (avatarType == (int)AvatarType.LOCAL_AVATAR) avatarClass = (int)AvatarType.LOCAL_AVATAR;
|
|
if (avatarClass == (int)AvatarType.UNKNOWN_AVATAR) avatarClass = userInfo.Class;
|
|
if (String.IsNullOrEmpty(userName)) userName = userInfo.Avatar;
|
|
}
|
|
|
|
if (avatarType == (int)AvatarType.UNKNOWN_AVATAR) avatarType = avatarClass;
|
|
if (String.IsNullOrEmpty(serverURL)) avatarClass = (int)AvatarType.NPC_AVATAR;
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogon: Avatar {0} ({1}) is logged on.", userName, clientUUID);
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogon: Avatar Type is {0} and Avatar Class is {1}", avatarType, avatarClass);
|
|
|
|
// Check Avatar
|
|
if (avatarClass == (int)AvatarType.GUEST_AVATAR && !m_gst_enable)
|
|
{
|
|
responseData["description"] = "Avatar is a Guest avatar. But this Money Server does not support Guest avatars.";
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogon: {0}", responseData["description"]);
|
|
return response;
|
|
}
|
|
else if (avatarClass == (int)AvatarType.HG_AVATAR && !m_hg_enable)
|
|
{
|
|
responseData["description"] = "Avatar is a HG avatar. But this Money Server does not support HG avatars.";
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogon: {0}", responseData["description"]);
|
|
return response;
|
|
}
|
|
else if (avatarClass == (int)AvatarType.FOREIGN_AVATAR)
|
|
{
|
|
responseData["description"] = "Avatar is a Foreign avatar.";
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogon: {0}", responseData["description"]);
|
|
return response;
|
|
}
|
|
else if (avatarClass == (int)AvatarType.UNKNOWN_AVATAR)
|
|
{
|
|
responseData["description"] = "Avatar is a Unknown avatar.";
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogon: {0}", responseData["description"]);
|
|
return response;
|
|
}
|
|
// NPC
|
|
else if (avatarClass == (int)AvatarType.NPC_AVATAR)
|
|
{
|
|
responseData["success"] = true;
|
|
responseData["clientBalance"] = 0;
|
|
responseData["description"] = "Avatar is a NPC.";
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogon: {0}", responseData["description"]);
|
|
return response;
|
|
}
|
|
|
|
//Update the session and secure session dictionary
|
|
lock (m_sessionDic)
|
|
{
|
|
if (!m_sessionDic.ContainsKey(clientUUID))
|
|
{
|
|
m_sessionDic.Add(clientUUID, sessionID);
|
|
}
|
|
else m_sessionDic[clientUUID] = sessionID;
|
|
}
|
|
lock (m_secureSessionDic)
|
|
{
|
|
if (!m_secureSessionDic.ContainsKey(clientUUID))
|
|
{
|
|
m_secureSessionDic.Add(clientUUID, secureID);
|
|
}
|
|
else m_secureSessionDic[clientUUID] = secureID;
|
|
}
|
|
|
|
try
|
|
{
|
|
if (userInfo == null) userInfo = new UserInfo();
|
|
userInfo.UserID = clientUUID;
|
|
userInfo.SimIP = simIP;
|
|
userInfo.Avatar = userName;
|
|
userInfo.PswHash = UUID.Zero.ToString();
|
|
userInfo.Type = avatarType;
|
|
userInfo.Class = avatarClass;
|
|
userInfo.ServerURL = serverURL;
|
|
if (!String.IsNullOrEmpty(securePsw)) userInfo.PswHash = securePsw;
|
|
|
|
if (!m_moneyDBService.TryAddUserInfo(userInfo))
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleClientLogin: Unable to refresh information for user \"{0}\" in DB.", userName);
|
|
responseData["success"] = true; // for FireStorm
|
|
responseData["description"] = "Update or add user information to db failed";
|
|
return response;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleClientLogin: Can't update userinfo for user {0}: {1}", clientUUID, e.ToString());
|
|
responseData["description"] = "Exception occured" + e.ToString();
|
|
return response;
|
|
}
|
|
|
|
try
|
|
{
|
|
balance = m_moneyDBService.getBalance(clientUUID);
|
|
|
|
//add user to balances table if not exist. (if balance is -1, it means avatar is not exist at balances table)
|
|
if (balance == -1)
|
|
{
|
|
int default_balance = m_defaultBalance;
|
|
if (avatarClass == (int)AvatarType.HG_AVATAR) default_balance = m_hg_defaultBalance;
|
|
if (avatarClass == (int)AvatarType.GUEST_AVATAR) default_balance = m_gst_defaultBalance;
|
|
|
|
if (m_moneyDBService.addUser(clientUUID, default_balance, 0, avatarType))
|
|
{
|
|
responseData["success"] = true;
|
|
responseData["description"] = "add user successfully";
|
|
responseData["clientBalance"] = default_balance;
|
|
}
|
|
else
|
|
{
|
|
responseData["description"] = "add user failed";
|
|
}
|
|
}
|
|
//Success
|
|
else if (balance >= 0)
|
|
{
|
|
responseData["success"] = true;
|
|
responseData["description"] = "get user balance successfully";
|
|
responseData["clientBalance"] = balance;
|
|
}
|
|
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleClientLogin: Can't get balance of user {0}: {1}", clientUUID, e.ToString());
|
|
responseData["description"] = "Exception occured" + e.ToString();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
|
|
public XmlRpcResponse handleClientLogout(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string clientUUID = string.Empty;
|
|
if (requestData.ContainsKey("clientUUID")) clientUUID = (string)requestData["clientUUID"];
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleClientLogout: User {0} is logging off.", clientUUID);
|
|
try
|
|
{
|
|
lock (m_sessionDic)
|
|
{
|
|
if (m_sessionDic.ContainsKey(clientUUID))
|
|
{
|
|
m_sessionDic.Remove(clientUUID);
|
|
}
|
|
}
|
|
|
|
lock (m_secureSessionDic)
|
|
{
|
|
if (m_secureSessionDic.ContainsKey(clientUUID))
|
|
{
|
|
m_secureSessionDic.Remove(clientUUID);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleClientLogout: Failed to delete user session: " + e.ToString());
|
|
responseData["success"] = false;
|
|
return response;
|
|
}
|
|
|
|
responseData["success"] = true;
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleTransaction(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleTransaction:");
|
|
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
int amount = 0;
|
|
int transactionType = 0;
|
|
string senderID = string.Empty;
|
|
string receiverID = string.Empty;
|
|
string senderSessionID = string.Empty;
|
|
string senderSecureSessionID = string.Empty;
|
|
string objectID = string.Empty;
|
|
string objectName = string.Empty;
|
|
string regionHandle = string.Empty;
|
|
string regionUUID = string.Empty;
|
|
string description = "Newly added on";
|
|
|
|
responseData["success"] = false;
|
|
UUID transactionUUID = UUID.Random();
|
|
|
|
if (requestData.ContainsKey("senderID")) senderID = (string)requestData["senderID"];
|
|
if (requestData.ContainsKey("receiverID")) receiverID = (string)requestData["receiverID"];
|
|
if (requestData.ContainsKey("senderSessionID")) senderSessionID = (string)requestData["senderSessionID"];
|
|
if (requestData.ContainsKey("senderSecureSessionID")) senderSecureSessionID = (string)requestData["senderSecureSessionID"];
|
|
if (requestData.ContainsKey("amount")) amount = Convert.ToInt32(requestData["amount"]);
|
|
if (requestData.ContainsKey("objectID")) objectID = (string)requestData["objectID"];
|
|
if (requestData.ContainsKey("objectName")) objectName = (string)requestData["objectName"];
|
|
if (requestData.ContainsKey("regionHandle")) regionHandle = (string)requestData["regionHandle"];
|
|
if (requestData.ContainsKey("regionUUID")) regionUUID = (string)requestData["regionUUID"];
|
|
if (requestData.ContainsKey("transactionType")) transactionType = Convert.ToInt32(requestData["transactionType"]);
|
|
if (requestData.ContainsKey("description")) description = (string)requestData["description"];
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleTransaction: Transfering money from {0} to {1}, Amount = {2}", senderID, receiverID, amount);
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleTransaction: Object ID = {0}, Object Name = {1}", objectID, objectName);
|
|
|
|
if (m_sessionDic.ContainsKey(senderID) && m_secureSessionDic.ContainsKey(senderID))
|
|
{
|
|
if (m_sessionDic[senderID] == senderSessionID && m_secureSessionDic[senderID] == senderSecureSessionID)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleTransaction: Transfering money from {0} to {1}", senderID, receiverID);
|
|
int time = (int)((DateTime.UtcNow.Ticks - TicksToEpoch) / 10000000);
|
|
try
|
|
{
|
|
TransactionData transaction = new TransactionData();
|
|
transaction.TransUUID = transactionUUID;
|
|
transaction.Sender = senderID;
|
|
transaction.Receiver = receiverID;
|
|
transaction.Amount = amount;
|
|
transaction.ObjectUUID = objectID;
|
|
transaction.ObjectName = objectName;
|
|
transaction.RegionHandle = regionHandle;
|
|
transaction.RegionUUID = regionUUID;
|
|
transaction.Type = transactionType;
|
|
transaction.Time = time;
|
|
transaction.SecureCode = UUID.Random().ToString();
|
|
transaction.Status = (int)Status.PENDING_STATUS;
|
|
transaction.CommonName = GetSSLCommonName();
|
|
transaction.Description = description + " " + DateTime.UtcNow.ToString();
|
|
|
|
UserInfo rcvr = m_moneyDBService.FetchUserInfo(receiverID);
|
|
if (rcvr == null)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleTransaction: Receive User is not yet in DB {0}", receiverID);
|
|
return response;
|
|
}
|
|
|
|
bool result = m_moneyDBService.addTransaction(transaction);
|
|
if (result)
|
|
{
|
|
UserInfo user = m_moneyDBService.FetchUserInfo(senderID);
|
|
if (user != null)
|
|
{
|
|
if (amount > 0 || (m_enableAmountZero && amount == 0))
|
|
{
|
|
string snd_message = "";
|
|
string rcv_message = "";
|
|
|
|
if (transaction.Type == (int)TransactionType.Gift)
|
|
{
|
|
snd_message = m_BalanceMessageSendGift;
|
|
rcv_message = m_BalanceMessageReceiveGift;
|
|
}
|
|
else if (transaction.Type == (int)TransactionType.LandSale)
|
|
{
|
|
snd_message = m_BalanceMessageLandSale;
|
|
rcv_message = m_BalanceMessageRcvLandSale;
|
|
}
|
|
else if (transaction.Type == (int)TransactionType.PayObject)
|
|
{
|
|
snd_message = m_BalanceMessageBuyObject;
|
|
rcv_message = m_BalanceMessageSellObject;
|
|
}
|
|
else if (transaction.Type == (int)TransactionType.ObjectPays)
|
|
{ // ObjectGiveMoney
|
|
rcv_message = m_BalanceMessageGetMoney;
|
|
}
|
|
|
|
responseData["success"] = NotifyTransfer(transactionUUID, snd_message, rcv_message, objectName);
|
|
}
|
|
else if (amount == 0)
|
|
{
|
|
responseData["success"] = true; // No messages for L$0 object. by Fumi.Iseki
|
|
}
|
|
return response;
|
|
}
|
|
}
|
|
else
|
|
{ // add transaction failed
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleTransaction: Add transaction for user {0} failed.", senderID);
|
|
}
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleTransaction: Exception occurred while adding transaction: " + e.ToString());
|
|
}
|
|
return response;
|
|
}
|
|
}
|
|
|
|
m_log.Error("[MONEY XMLRPC]: handleTransaction: Session authentication failure for sender " + senderID);
|
|
responseData["message"] = "Session check failure, please re-login later!";
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleForceTransaction(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
int amount = 0;
|
|
int transactionType = 0;
|
|
string senderID = string.Empty;
|
|
string receiverID = string.Empty;
|
|
string objectID = string.Empty;
|
|
string objectName = string.Empty;
|
|
string regionHandle = string.Empty;
|
|
string regionUUID = string.Empty;
|
|
string description = "Newly added on";
|
|
|
|
responseData["success"] = false;
|
|
UUID transactionUUID = UUID.Random();
|
|
|
|
//
|
|
if (!m_forceTransfer)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleForceTransaction: Not allowed force transfer of Money.");
|
|
m_log.Error("[MONEY XMLRPC]: handleForceTransaction: Set enableForceTransfer at [MoneyServer] to true in MoneyServer.ini");
|
|
responseData["message"] = "not allowed force transfer of Money!";
|
|
return response;
|
|
}
|
|
|
|
if (requestData.ContainsKey("senderID")) senderID = (string)requestData["senderID"];
|
|
if (requestData.ContainsKey("receiverID")) receiverID = (string)requestData["receiverID"];
|
|
if (requestData.ContainsKey("amount")) amount = Convert.ToInt32(requestData["amount"]);
|
|
if (requestData.ContainsKey("objectID")) objectID = (string)requestData["objectID"];
|
|
if (requestData.ContainsKey("objectName")) objectName = (string)requestData["objectName"];
|
|
if (requestData.ContainsKey("regionHandle")) regionHandle = (string)requestData["regionHandle"];
|
|
if (requestData.ContainsKey("regionUUID")) regionUUID = (string)requestData["regionUUID"];
|
|
if (requestData.ContainsKey("transactionType")) transactionType = Convert.ToInt32(requestData["transactionType"]);
|
|
if (requestData.ContainsKey("description")) description = (string)requestData["description"];
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleForceTransaction: Force transfering money from {0} to {1}, Amount = {2}", senderID, receiverID, amount);
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleForceTransaction: Object ID = {0}, Object Name = {1}", objectID, objectName);
|
|
|
|
int time = (int)((DateTime.UtcNow.Ticks - TicksToEpoch) / 10000000);
|
|
|
|
try
|
|
{
|
|
TransactionData transaction = new TransactionData();
|
|
transaction.TransUUID = transactionUUID;
|
|
transaction.Sender = senderID;
|
|
transaction.Receiver = receiverID;
|
|
transaction.Amount = amount;
|
|
transaction.ObjectUUID = objectID;
|
|
transaction.ObjectName = objectName;
|
|
transaction.RegionHandle = regionHandle;
|
|
transaction.RegionUUID = regionUUID;
|
|
transaction.Type = transactionType;
|
|
transaction.Time = time;
|
|
transaction.SecureCode = UUID.Random().ToString();
|
|
transaction.Status = (int)Status.PENDING_STATUS;
|
|
transaction.CommonName = GetSSLCommonName();
|
|
transaction.Description = description + " " + DateTime.UtcNow.ToString();
|
|
|
|
UserInfo rcvr = m_moneyDBService.FetchUserInfo(receiverID);
|
|
if (rcvr == null)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleForceTransaction: Force receive User is not yet in DB {0}", receiverID);
|
|
return response;
|
|
}
|
|
|
|
bool result = m_moneyDBService.addTransaction(transaction);
|
|
if (result)
|
|
{
|
|
UserInfo user = m_moneyDBService.FetchUserInfo(senderID);
|
|
if (user != null)
|
|
{
|
|
if (amount > 0 || (m_enableAmountZero && amount == 0))
|
|
{
|
|
string snd_message = "";
|
|
string rcv_message = "";
|
|
|
|
if (transaction.Type == (int)TransactionType.Gift)
|
|
{
|
|
snd_message = m_BalanceMessageSendGift;
|
|
rcv_message = m_BalanceMessageReceiveGift;
|
|
}
|
|
else if (transaction.Type == (int)TransactionType.LandSale)
|
|
{
|
|
snd_message = m_BalanceMessageLandSale;
|
|
snd_message = m_BalanceMessageRcvLandSale;
|
|
}
|
|
else if (transaction.Type == (int)TransactionType.PayObject)
|
|
{
|
|
snd_message = m_BalanceMessageBuyObject;
|
|
rcv_message = m_BalanceMessageSellObject;
|
|
}
|
|
else if (transaction.Type == (int)TransactionType.ObjectPays)
|
|
{ // ObjectGiveMoney
|
|
rcv_message = m_BalanceMessageGetMoney;
|
|
}
|
|
|
|
responseData["success"] = NotifyTransfer(transactionUUID, snd_message, rcv_message, objectName);
|
|
}
|
|
else if (amount == 0)
|
|
{
|
|
responseData["success"] = true; // No messages for L$0 object. by Fumi.Iseki
|
|
}
|
|
return response;
|
|
}
|
|
}
|
|
else
|
|
{ // add transaction failed
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleForceTransaction: Add force transaction for user {0} failed.", senderID);
|
|
}
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleForceTransaction: Exception occurred while adding force transaction: " + e.ToString());
|
|
}
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleScriptTransaction(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleScriptTransaction:");
|
|
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
int amount = 0;
|
|
int transactionType = 0;
|
|
string senderID = UUID.Zero.ToString();
|
|
string receiverID = UUID.Zero.ToString();
|
|
string clientIP = remoteClient.Address.ToString();
|
|
string secretCode = string.Empty;
|
|
string description = "Scripted Send Money from/to Avatar on";
|
|
|
|
responseData["success"] = false;
|
|
UUID transactionUUID = UUID.Random();
|
|
|
|
if (!m_scriptSendMoney || m_scriptAccessKey == "")
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleScriptTransaction: Not allowed send money to avatar!!");
|
|
m_log.Error("[MONEY XMLRPC]: handleScriptTransaction: Set enableScriptSendMoney and MoneyScriptAccessKey at [MoneyServer] in MoneyServer.ini");
|
|
responseData["message"] = "not allowed set money to avatar!";
|
|
return response;
|
|
}
|
|
|
|
if (requestData.ContainsKey("senderID")) senderID = (string)requestData["senderID"];
|
|
if (requestData.ContainsKey("receiverID")) receiverID = (string)requestData["receiverID"];
|
|
if (requestData.ContainsKey("amount")) amount = Convert.ToInt32(requestData["amount"]);
|
|
if (requestData.ContainsKey("transactionType")) transactionType = Convert.ToInt32(requestData["transactionType"]);
|
|
if (requestData.ContainsKey("description")) description = (string)requestData["description"];
|
|
if (requestData.ContainsKey("secretAccessCode")) secretCode = (string)requestData["secretAccessCode"];
|
|
|
|
MD5 md5 = MD5.Create();
|
|
byte[] code = md5.ComputeHash(ASCIIEncoding.Default.GetBytes(m_scriptAccessKey + "_" + clientIP));
|
|
string hash = BitConverter.ToString(code).ToLower().Replace("-", "");
|
|
code = md5.ComputeHash(ASCIIEncoding.Default.GetBytes(hash + "_" + m_scriptIPaddress));
|
|
hash = BitConverter.ToString(code).ToLower().Replace("-", "");
|
|
|
|
if (secretCode.ToLower() != hash)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleScriptTransaction: Not allowed send money to avatar!!");
|
|
m_log.Error("[MONEY XMLRPC]: handleScriptTransaction: Not match Script Access Key.");
|
|
responseData["message"] = "not allowed send money to avatar! not match Script Key";
|
|
return response;
|
|
}
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleScriptTransaction: Send money from {0} to {1}", senderID, receiverID);
|
|
int time = (int)((DateTime.UtcNow.Ticks - TicksToEpoch) / 10000000);
|
|
|
|
try
|
|
{
|
|
TransactionData transaction = new TransactionData();
|
|
transaction.TransUUID = transactionUUID;
|
|
transaction.Sender = senderID;
|
|
transaction.Receiver = receiverID;
|
|
transaction.Amount = amount;
|
|
transaction.ObjectUUID = UUID.Zero.ToString();
|
|
transaction.RegionHandle = "0";
|
|
transaction.Type = transactionType;
|
|
transaction.Time = time;
|
|
transaction.SecureCode = UUID.Random().ToString();
|
|
transaction.Status = (int)Status.PENDING_STATUS;
|
|
transaction.CommonName = GetSSLCommonName();
|
|
transaction.Description = description + " " + DateTime.UtcNow.ToString();
|
|
|
|
UserInfo senderInfo = null;
|
|
UserInfo receiverInfo = null;
|
|
if (transaction.Sender != UUID.Zero.ToString()) senderInfo = m_moneyDBService.FetchUserInfo(transaction.Sender);
|
|
if (transaction.Receiver != UUID.Zero.ToString()) receiverInfo = m_moneyDBService.FetchUserInfo(transaction.Receiver);
|
|
|
|
if (senderInfo == null && receiverInfo == null)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleScriptTransaction: Sender and Receiver are not yet in DB, or both of them are System: {0}, {1}",
|
|
transaction.Sender, transaction.Receiver);
|
|
return response;
|
|
}
|
|
|
|
bool result = m_moneyDBService.addTransaction(transaction);
|
|
if (result)
|
|
{
|
|
if (amount > 0 || (m_enableAmountZero && amount == 0))
|
|
{
|
|
if (m_moneyDBService.DoTransfer(transactionUUID))
|
|
{
|
|
transaction = m_moneyDBService.FetchTransaction(transactionUUID);
|
|
if (transaction != null && transaction.Status == (int)Status.SUCCESS_STATUS)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleScriptTransaction: ScriptTransaction money finished successfully, now update balance {0}",
|
|
transactionUUID.ToString());
|
|
string message = string.Empty;
|
|
if (senderInfo != null)
|
|
{
|
|
if (receiverInfo == null) message = string.Format(m_BalanceMessageSendMoney, amount, "SYSTEM", "");
|
|
else message = string.Format(m_BalanceMessageSendMoney, amount, receiverInfo.Avatar, "");
|
|
UpdateBalance(transaction.Sender, message);
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleScriptTransaction: Update balance of {0}. Message = {1}", transaction.Sender, message);
|
|
}
|
|
if (receiverInfo != null)
|
|
{
|
|
if (senderInfo == null) message = string.Format(m_BalanceMessageReceiveMoney, amount, "SYSTEM", "");
|
|
else message = string.Format(m_BalanceMessageReceiveMoney, amount, senderInfo.Avatar, "");
|
|
UpdateBalance(transaction.Receiver, message);
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleScriptTransaction: Update balance of {0}. Message = {1}", transaction.Receiver, message);
|
|
}
|
|
|
|
responseData["success"] = true;
|
|
}
|
|
}
|
|
}
|
|
else if (amount == 0)
|
|
{
|
|
responseData["success"] = true; // No messages for L$0 add
|
|
}
|
|
return response;
|
|
}
|
|
else
|
|
{ // add transaction failed
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleScriptTransaction: Add force transaction for user {0} failed.", transaction.Sender);
|
|
}
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleScriptTransaction: Exception occurred while adding money transaction: " + e.ToString());
|
|
}
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleAddBankerMoney(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
int amount = 0;
|
|
int transactionType = 0;
|
|
string senderID = UUID.Zero.ToString();
|
|
string bankerID = string.Empty;
|
|
string regionHandle = "0";
|
|
string regionUUID = UUID.Zero.ToString();
|
|
string description = "Add Money to Avatar on";
|
|
|
|
responseData["success"] = false;
|
|
UUID transactionUUID = UUID.Random();
|
|
|
|
if (requestData.ContainsKey("bankerID")) bankerID = (string)requestData["bankerID"];
|
|
if (requestData.ContainsKey("amount")) amount = Convert.ToInt32(requestData["amount"]);
|
|
if (requestData.ContainsKey("regionHandle")) regionHandle = (string)requestData["regionHandle"];
|
|
if (requestData.ContainsKey("regionUUID")) regionUUID = (string)requestData["regionUUID"];
|
|
if (requestData.ContainsKey("transactionType")) transactionType = Convert.ToInt32(requestData["transactionType"]);
|
|
if (requestData.ContainsKey("description")) description = (string)requestData["description"];
|
|
|
|
// Check Banker Avatar
|
|
if (m_bankerAvatar != UUID.Zero.ToString() && m_bankerAvatar != bankerID)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleAddBankerMoney: Not allowed add money to avatar!!");
|
|
m_log.Error("[MONEY XMLRPC]: handleAddBankerMoney: Set BankerAvatar at [MoneyServer] in MoneyServer.ini");
|
|
responseData["message"] = "not allowed add money to avatar!";
|
|
responseData["banker"] = false;
|
|
return response;
|
|
}
|
|
responseData["banker"] = true;
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleAddBankerMoney: Add money to avatar {0}", bankerID);
|
|
int time = (int)((DateTime.UtcNow.Ticks - TicksToEpoch) / 10000000);
|
|
|
|
try
|
|
{
|
|
TransactionData transaction = new TransactionData();
|
|
transaction.TransUUID = transactionUUID;
|
|
transaction.Sender = senderID;
|
|
transaction.Receiver = bankerID;
|
|
transaction.Amount = amount;
|
|
transaction.ObjectUUID = UUID.Zero.ToString();
|
|
transaction.RegionHandle = regionHandle;
|
|
transaction.RegionUUID = regionUUID;
|
|
transaction.Type = transactionType;
|
|
transaction.Time = time;
|
|
transaction.SecureCode = UUID.Random().ToString();
|
|
transaction.Status = (int)Status.PENDING_STATUS;
|
|
transaction.CommonName = GetSSLCommonName();
|
|
transaction.Description = description + " " + DateTime.UtcNow.ToString();
|
|
|
|
UserInfo rcvr = m_moneyDBService.FetchUserInfo(bankerID);
|
|
if (rcvr == null)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleAddBankerMoney: Avatar is not yet in DB {0}", bankerID);
|
|
return response;
|
|
}
|
|
|
|
bool result = m_moneyDBService.addTransaction(transaction);
|
|
if (result)
|
|
{
|
|
if (amount > 0 || (m_enableAmountZero && amount == 0))
|
|
{
|
|
if (m_moneyDBService.DoAddMoney(transactionUUID))
|
|
{
|
|
transaction = m_moneyDBService.FetchTransaction(transactionUUID);
|
|
if (transaction != null && transaction.Status == (int)Status.SUCCESS_STATUS)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleAddBankerMoney: Adding money finished successfully, now update balance: {0}",
|
|
transactionUUID.ToString());
|
|
string message = string.Format(m_BalanceMessageBuyMoney, amount, "SYSTEM", "");
|
|
UpdateBalance(transaction.Receiver, message);
|
|
responseData["success"] = true;
|
|
}
|
|
}
|
|
}
|
|
else if (amount == 0)
|
|
{
|
|
responseData["success"] = true; // No messages for L$0 add
|
|
}
|
|
return response;
|
|
}
|
|
else
|
|
{ // add transaction failed
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleAddBankerMoney: Add force transaction for user {0} failed.", senderID);
|
|
}
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleAddBankerMoney: Exception occurred while adding money transaction: " + e.ToString());
|
|
}
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handlePayMoneyCharge(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handlePayMoneyCharge now.");
|
|
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
int amount = 0;
|
|
int transactionType = 0;
|
|
string senderID = string.Empty;
|
|
string receiverID = UUID.Zero.ToString();
|
|
string senderSessionID = string.Empty;
|
|
string senderSecureSessionID = string.Empty;
|
|
string objectID = UUID.Zero.ToString();
|
|
string objectName = string.Empty;
|
|
string regionHandle = string.Empty;
|
|
string regionUUID = string.Empty;
|
|
string description = "Pay Charge on";
|
|
|
|
responseData["success"] = false;
|
|
UUID transactionUUID = UUID.Random();
|
|
|
|
// Parameter aus der Anfrage extrahieren
|
|
if (requestData.ContainsKey("senderID")) senderID = (string)requestData["senderID"];
|
|
if (requestData.ContainsKey("senderSessionID")) senderSessionID = (string)requestData["senderSessionID"];
|
|
if (requestData.ContainsKey("senderSecureSessionID")) senderSecureSessionID = (string)requestData["senderSecureSessionID"];
|
|
if (requestData.ContainsKey("amount")) amount = Convert.ToInt32(requestData["amount"]);
|
|
if (requestData.ContainsKey("regionHandle")) regionHandle = (string)requestData["regionHandle"];
|
|
if (requestData.ContainsKey("regionUUID")) regionUUID = (string)requestData["regionUUID"];
|
|
if (requestData.ContainsKey("transactionType")) transactionType = Convert.ToInt32(requestData["transactionType"]);
|
|
if (requestData.ContainsKey("description")) description = (string)requestData["description"];
|
|
if (requestData.ContainsKey("receiverID")) receiverID = (string)requestData["receiverID"];
|
|
if (requestData.ContainsKey("objectID")) objectID = (string)requestData["objectID"];
|
|
if (requestData.ContainsKey("objectName")) objectName = (string)requestData["objectName"];
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handlePayMoneyCharge: Transfering money from {0} to {1}, Amount = {2}", senderID, receiverID, amount);
|
|
|
|
// Sitzungsprüfung überspringen für SYSTEM oder Banker
|
|
if (senderID == m_bankerAvatar || senderID == "SYSTEM")
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handlePayMoneyCharge: Sender ist SYSTEM oder BankerAvatar. Sitzungsprüfung wird übersprungen.");
|
|
}
|
|
else if (m_sessionDic.ContainsKey(senderID) && m_secureSessionDic.ContainsKey(senderID))
|
|
{
|
|
if (m_sessionDic[senderID] != senderSessionID || m_secureSessionDic[senderID] != senderSecureSessionID)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handlePayMoneyCharge: Sitzungsprüfung für Sender fehlgeschlagen " + senderID);
|
|
responseData["message"] = "Session check failure, please re-login later!";
|
|
return response;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handlePayMoneyCharge: Sitzungsprüfung für Sender fehlgeschlagen " + senderID);
|
|
responseData["message"] = "Session check failure, please re-login later!";
|
|
return response;
|
|
}
|
|
|
|
int time = (int)((DateTime.UtcNow.Ticks - TicksToEpoch) / 10000000);
|
|
|
|
try
|
|
{
|
|
TransactionData transaction = new TransactionData
|
|
{
|
|
TransUUID = transactionUUID,
|
|
Sender = senderID,
|
|
Receiver = receiverID,
|
|
Amount = amount,
|
|
ObjectUUID = objectID,
|
|
ObjectName = objectName,
|
|
RegionHandle = regionHandle,
|
|
RegionUUID = regionUUID,
|
|
Type = transactionType,
|
|
Time = time,
|
|
SecureCode = UUID.Random().ToString(),
|
|
Status = (int)Status.PENDING_STATUS,
|
|
CommonName = GetSSLCommonName(),
|
|
Description = description + " " + DateTime.UtcNow.ToString()
|
|
};
|
|
|
|
bool result = m_moneyDBService.addTransaction(transaction);
|
|
if (result)
|
|
{
|
|
UserInfo user = m_moneyDBService.FetchUserInfo(senderID);
|
|
if (user != null)
|
|
{
|
|
if (amount == 0)
|
|
{
|
|
// Für L$0 keine Transferaktion, einfach Erfolg zurückgeben
|
|
responseData["success"] = true;
|
|
return response;
|
|
}
|
|
|
|
if (amount > 0 || (m_enableAmountZero && amount == 0))
|
|
{
|
|
if (!NotifyTransfer(transactionUUID, "", "", ""))
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handlePayMoneyCharge: Gutschrift fehlgeschlagen, versuche manuell Geld hinzuzufügen.");
|
|
|
|
Hashtable addMoneyParams = new Hashtable();
|
|
addMoneyParams["bankerID"] = "SYSTEM";
|
|
addMoneyParams["amount"] = amount;
|
|
addMoneyParams["regionHandle"] = regionHandle;
|
|
addMoneyParams["regionUUID"] = regionUUID;
|
|
addMoneyParams["transactionType"] = transactionType;
|
|
addMoneyParams["description"] = "Manuelle Gutschrift nach Fehlermeldung";
|
|
|
|
XmlRpcResponse addMoneyResponse = handleAddBankerMoney(
|
|
new XmlRpcRequest("AddBankerMoney", new object[] { addMoneyParams }),
|
|
remoteClient
|
|
);
|
|
|
|
Hashtable responseValue = addMoneyResponse.Value as Hashtable;
|
|
bool addMoneySuccess = addMoneyResponse != null
|
|
&& responseValue != null
|
|
&& responseValue.ContainsKey("success")
|
|
&& (bool)responseValue["success"];
|
|
|
|
responseData["success"] = addMoneySuccess;
|
|
|
|
if (!addMoneySuccess)
|
|
{
|
|
responseData["message"] = "Manuelles Hinzufügen des Geldes fehlgeschlagen.";
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
// Wenn NotifyTransfer erfolgreich war
|
|
responseData["success"] = true;
|
|
return response;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handlePayMoneyCharge: Zahlungstransaktion für Benutzer {0} fehlgeschlagen.", senderID);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handlePayMoneyCharge: Ausnahme bei der Zahlungstransaktion: " + e.ToString());
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleCancelTransfer(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string secureCode = string.Empty;
|
|
string transactionID = string.Empty;
|
|
UUID transactionUUID = UUID.Zero;
|
|
|
|
responseData["success"] = false;
|
|
|
|
if (requestData.ContainsKey("secureCode")) secureCode = (string)requestData["secureCode"];
|
|
if (requestData.ContainsKey("transactionID"))
|
|
{
|
|
transactionID = (string)requestData["transactionID"];
|
|
UUID.TryParse(transactionID, out transactionUUID);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(secureCode) || string.IsNullOrEmpty(transactionID))
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: handleCancelTransfer: secureCode and/or transactionID are empty.");
|
|
return response;
|
|
}
|
|
|
|
TransactionData transaction = m_moneyDBService.FetchTransaction(transactionUUID);
|
|
UserInfo user = m_moneyDBService.FetchUserInfo(transaction.Sender);
|
|
|
|
try
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleCancelTransfer: User {0} wanted to cancel the transaction.", user.Avatar);
|
|
if (m_moneyDBService.ValidateTransfer(secureCode, transactionUUID))
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleCancelTransfer: User {0} has canceled the transaction {1}", user.Avatar, transactionID);
|
|
m_moneyDBService.updateTransactionStatus(transactionUUID, (int)Status.FAILED_STATUS,
|
|
"User canceled the transaction on " + DateTime.UtcNow.ToString());
|
|
responseData["success"] = true;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleCancelTransfer: Exception occurred when transaction {0}: {1}", transactionID, e.ToString());
|
|
}
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleGetTransaction(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string clientID = string.Empty;
|
|
string sessionID = string.Empty;
|
|
string secureID = string.Empty;
|
|
string transactionID = string.Empty;
|
|
UUID transactionUUID = UUID.Zero;
|
|
|
|
responseData["success"] = false;
|
|
|
|
if (requestData.ContainsKey("clientUUID")) clientID = (string)requestData["clientUUID"];
|
|
if (requestData.ContainsKey("clientSessionID")) sessionID = (string)requestData["clientSessionID"];
|
|
if (requestData.ContainsKey("clientSecureSessionID")) secureID = (string)requestData["clientSecureSessionID"];
|
|
|
|
if (requestData.ContainsKey("transactionID"))
|
|
{
|
|
transactionID = (string)requestData["transactionID"];
|
|
UUID.TryParse(transactionID, out transactionUUID);
|
|
}
|
|
|
|
if (m_sessionDic.ContainsKey(clientID) && m_secureSessionDic.ContainsKey(clientID))
|
|
{
|
|
if (m_sessionDic[clientID] == sessionID && m_secureSessionDic[clientID] == secureID)
|
|
{
|
|
//
|
|
if (string.IsNullOrEmpty(transactionID))
|
|
{
|
|
responseData["description"] = "TransactionID is empty";
|
|
m_log.Error("[MONEY XMLRPC]: handleGetTransaction: TransactionID is empty.");
|
|
return response;
|
|
}
|
|
|
|
try
|
|
{
|
|
TransactionData transaction = m_moneyDBService.FetchTransaction(transactionUUID);
|
|
if (transaction != null)
|
|
{
|
|
responseData["success"] = true;
|
|
responseData["amount"] = transaction.Amount;
|
|
responseData["time"] = transaction.Time;
|
|
responseData["type"] = transaction.Type;
|
|
responseData["sender"] = transaction.Sender.ToString();
|
|
responseData["receiver"] = transaction.Receiver.ToString();
|
|
responseData["description"] = transaction.Description;
|
|
}
|
|
else
|
|
{
|
|
responseData["description"] = "Invalid Transaction UUID";
|
|
}
|
|
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleGetTransaction: {0}", e.ToString());
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleGetTransaction: Can't get transaction information for {0}", transactionUUID.ToString());
|
|
}
|
|
return response;
|
|
}
|
|
}
|
|
|
|
responseData["success"] = false;
|
|
responseData["description"] = "Session check failure, please re-login";
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleWebLogin(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string userID = string.Empty;
|
|
string webSessionID = string.Empty;
|
|
|
|
responseData["success"] = false;
|
|
|
|
if (requestData.ContainsKey("userID")) userID = (string)requestData["userID"];
|
|
if (requestData.ContainsKey("sessionID")) webSessionID = (string)requestData["sessionID"];
|
|
|
|
if (string.IsNullOrEmpty(userID) || string.IsNullOrEmpty(webSessionID))
|
|
{
|
|
responseData["errorMessage"] = "userID or sessionID can`t be empty, login failed!";
|
|
return response;
|
|
}
|
|
|
|
//Update the web session dictionary
|
|
lock (m_webSessionDic)
|
|
{
|
|
if (!m_webSessionDic.ContainsKey(userID))
|
|
{
|
|
m_webSessionDic.Add(userID, webSessionID);
|
|
}
|
|
else m_webSessionDic[userID] = webSessionID;
|
|
}
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleWebLogin: User {0} has logged in from web.", userID);
|
|
responseData["success"] = true;
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleWebLogout(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string userID = string.Empty;
|
|
string webSessionID = string.Empty;
|
|
|
|
responseData["success"] = false;
|
|
|
|
if (requestData.ContainsKey("userID")) userID = (string)requestData["userID"];
|
|
if (requestData.ContainsKey("sessionID")) webSessionID = (string)requestData["sessionID"];
|
|
|
|
if (string.IsNullOrEmpty(userID) || string.IsNullOrEmpty(webSessionID))
|
|
{
|
|
responseData["errorMessage"] = "userID or sessionID can`t be empty, log out failed!";
|
|
return response;
|
|
}
|
|
|
|
//Update the web session dictionary
|
|
lock (m_webSessionDic)
|
|
{
|
|
if (m_webSessionDic.ContainsKey(userID))
|
|
{
|
|
m_webSessionDic.Remove(userID);
|
|
}
|
|
}
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleWebLogout: User {0} has logged out from web.", userID);
|
|
responseData["success"] = true;
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleWebGetBalance(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string userID = string.Empty;
|
|
string webSessionID = string.Empty;
|
|
int balance = 0;
|
|
|
|
responseData["success"] = false;
|
|
|
|
if (requestData.ContainsKey("userID")) userID = (string)requestData["userID"];
|
|
if (requestData.ContainsKey("sessionID")) webSessionID = (string)requestData["sessionID"];
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleWebGetBalance: Getting balance for user {0}", userID);
|
|
|
|
//perform session check
|
|
if (m_webSessionDic.ContainsKey(userID))
|
|
{
|
|
if (m_webSessionDic[userID] == webSessionID)
|
|
{
|
|
try
|
|
{
|
|
balance = m_moneyDBService.getBalance(userID);
|
|
UserInfo user = m_moneyDBService.FetchUserInfo(userID);
|
|
if (user != null)
|
|
{
|
|
responseData["userName"] = user.Avatar;
|
|
}
|
|
else
|
|
{
|
|
responseData["userName"] = "unknown user";
|
|
}
|
|
// User not found
|
|
if (balance == -1)
|
|
{
|
|
responseData["errorMessage"] = "User not found";
|
|
responseData["balance"] = 0;
|
|
}
|
|
else if (balance >= 0)
|
|
{
|
|
responseData["success"] = true;
|
|
responseData["balance"] = balance;
|
|
}
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleWebGetBalance: Can't get balance for user {0}, Exception {1}", userID, e.ToString());
|
|
responseData["errorMessage"] = "Exception occurred when getting balance";
|
|
return response;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_log.Error("[MONEY XMLRPC]: handleWebLogout: Session authentication failed when getting balance for user " + userID);
|
|
responseData["errorMessage"] = "Session check failure, please re-login";
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleWebGetTransaction(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string userID = string.Empty;
|
|
string webSessionID = string.Empty;
|
|
int lastIndex = -1;
|
|
int startTime = 0;
|
|
int endTime = 0;
|
|
|
|
responseData["success"] = false;
|
|
|
|
if (requestData.ContainsKey("userID")) userID = (string)requestData["userID"];
|
|
if (requestData.ContainsKey("sessionID")) webSessionID = (string)requestData["sessionID"];
|
|
if (requestData.ContainsKey("startTime")) startTime = (int)requestData["startTime"];
|
|
if (requestData.ContainsKey("endTime")) endTime = (int)requestData["endTime"];
|
|
if (requestData.ContainsKey("lastIndex")) lastIndex = (int)requestData["lastIndex"];
|
|
|
|
if (m_webSessionDic.ContainsKey(userID))
|
|
{
|
|
if (m_webSessionDic[userID] == webSessionID)
|
|
{
|
|
try
|
|
{
|
|
int total = m_moneyDBService.getTransactionNum(userID, startTime, endTime);
|
|
TransactionData tran = null;
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleWebGetTransaction: Getting transation[{0}] for user {1}", lastIndex + 1, userID);
|
|
if (total > lastIndex + 2)
|
|
{
|
|
responseData["isEnd"] = false;
|
|
}
|
|
else
|
|
{
|
|
responseData["isEnd"] = true;
|
|
}
|
|
|
|
tran = m_moneyDBService.FetchTransaction(userID, startTime, endTime, lastIndex);
|
|
if (tran != null)
|
|
{
|
|
UserInfo senderInfo = m_moneyDBService.FetchUserInfo(tran.Sender);
|
|
UserInfo receiverInfo = m_moneyDBService.FetchUserInfo(tran.Receiver);
|
|
if (senderInfo != null && receiverInfo != null)
|
|
{
|
|
responseData["senderName"] = senderInfo.Avatar;
|
|
responseData["receiverName"] = receiverInfo.Avatar;
|
|
}
|
|
else
|
|
{
|
|
responseData["senderName"] = "unknown user";
|
|
responseData["receiverName"] = "unknown user";
|
|
}
|
|
responseData["success"] = true;
|
|
responseData["transactionIndex"] = lastIndex + 1;
|
|
responseData["transactionUUID"] = tran.TransUUID.ToString();
|
|
responseData["senderID"] = tran.Sender;
|
|
responseData["receiverID"] = tran.Receiver;
|
|
responseData["amount"] = tran.Amount;
|
|
responseData["type"] = tran.Type;
|
|
responseData["time"] = tran.Time;
|
|
responseData["status"] = tran.Status;
|
|
responseData["description"] = tran.Description;
|
|
}
|
|
else
|
|
{
|
|
responseData["errorMessage"] = string.Format("Unable to fetch transaction data with the index {0}", lastIndex + 1);
|
|
}
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleWebGetTransaction: Can't get transaction for user {0}, Exception {1}", userID, e.ToString());
|
|
responseData["errorMessage"] = "Exception occurred when getting transaction";
|
|
return response;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_log.Error("[MONEY XMLRPC]: handleWebGetTransaction: Session authentication failed when getting transaction for user " + userID);
|
|
responseData["errorMessage"] = "Session check failure, please re-login";
|
|
return response;
|
|
}
|
|
|
|
public XmlRpcResponse handleWebGetTransactionNum(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string userID = string.Empty;
|
|
string webSessionID = string.Empty;
|
|
int startTime = 0;
|
|
int endTime = 0;
|
|
|
|
responseData["success"] = false;
|
|
|
|
if (requestData.ContainsKey("userID")) userID = (string)requestData["userID"];
|
|
if (requestData.ContainsKey("sessionID")) webSessionID = (string)requestData["sessionID"];
|
|
if (requestData.ContainsKey("startTime")) startTime = (int)requestData["startTime"];
|
|
if (requestData.ContainsKey("endTime")) endTime = (int)requestData["endTime"];
|
|
|
|
if (m_webSessionDic.ContainsKey(userID))
|
|
{
|
|
if (m_webSessionDic[userID] == webSessionID)
|
|
{
|
|
int it = m_moneyDBService.getTransactionNum(userID, startTime, endTime);
|
|
if (it >= 0)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleWebGetTransactionNum: Get {0} transactions for user {1}", it, userID);
|
|
responseData["success"] = true;
|
|
responseData["number"] = it;
|
|
}
|
|
return response;
|
|
}
|
|
}
|
|
|
|
m_log.Error("[MONEY XMLRPC]: handleWebGetTransactionNum: Session authentication failed when getting transaction number for user " + userID);
|
|
responseData["errorMessage"] = "Session check failure, please re-login";
|
|
return response;
|
|
}
|
|
|
|
|
|
#endregion
|
|
// ################## helper ##################
|
|
#region helper
|
|
|
|
//Spezifische Handler OnMoneyTransferedHandler: Protokolliert Details zu einer Geldüberweisung.
|
|
public XmlRpcResponse OnMoneyTransferedHandler(XmlRpcRequest request, IPEndPoint client)
|
|
{
|
|
if (request == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: OnMoneyTransferedHandler: request is null.");
|
|
return new XmlRpcResponse();
|
|
}
|
|
|
|
if (client == null)
|
|
{
|
|
m_log.Error("[MONEY XMLRPC]: OnMoneyTransferedHandler: client is null.");
|
|
return new XmlRpcResponse();
|
|
}
|
|
|
|
try
|
|
{
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
string transactionID = (string)requestData["transactionID"];
|
|
UUID transactionUUID = UUID.Zero;
|
|
UUID.TryParse(transactionID, out transactionUUID);
|
|
|
|
TransactionData transaction = m_moneyDBService.FetchTransaction(transactionUUID);
|
|
UserInfo user = m_moneyDBService.FetchUserInfo(transaction.Sender);
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: OnMoneyTransferedHandler: Transaction {0} from user {1} to user {2} for {3} units",
|
|
transactionID, user.Avatar, transaction.Receiver, transaction.Amount);
|
|
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
responseData.Add("success", true);
|
|
response.Value = responseData;
|
|
return response;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: OnMoneyTransferedHandler: Exception occurred: {0}", ex.Message);
|
|
return new XmlRpcResponse();
|
|
}
|
|
}
|
|
|
|
public string GetSSLCommonName(XmlRpcRequest request)
|
|
{
|
|
if (request.Params.Count > 5)
|
|
{
|
|
m_sslCommonName = (string)request.Params[5];
|
|
}
|
|
else if (request.Params.Count == 5)
|
|
{
|
|
m_sslCommonName = (string)request.Params[4];
|
|
if (m_sslCommonName == "gridproxy") m_sslCommonName = "";
|
|
}
|
|
else
|
|
{
|
|
m_sslCommonName = "";
|
|
}
|
|
return m_sslCommonName;
|
|
}
|
|
|
|
/// <summary>Gets the name of the SSL common.</summary>
|
|
public string GetSSLCommonName()
|
|
{
|
|
return m_sslCommonName;
|
|
}
|
|
|
|
public bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, int amount, UUID txn, out string result)
|
|
{
|
|
result = String.Empty;
|
|
string description = String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID));
|
|
|
|
bool give_result = doMoneyTransfer(fromID, toID, amount, 2, description);
|
|
|
|
|
|
BalanceUpdate(fromID, toID, give_result, description);
|
|
|
|
return give_result;
|
|
}
|
|
|
|
private string resolveObjectName(UUID objectID)
|
|
{
|
|
SceneObjectPart part = findPrim(objectID);
|
|
if (part != null)
|
|
{
|
|
return part.Name;
|
|
}
|
|
return String.Empty;
|
|
}
|
|
|
|
private string resolveAgentName(UUID agentID)
|
|
{
|
|
// try avatar username surname
|
|
Scene scene = GetRandomScene();
|
|
UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, agentID);
|
|
if (account != null)
|
|
{
|
|
string avatarname = account.FirstName + " " + account.LastName;
|
|
return avatarname;
|
|
}
|
|
else
|
|
{
|
|
m_log.ErrorFormat(
|
|
"[MONEY]: Could not resolve user {0}",
|
|
agentID);
|
|
}
|
|
|
|
return String.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Utility function Gets a Random scene in the instance. For when which scene exactly you're doing something with doesn't matter
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Scene GetRandomScene()
|
|
{
|
|
lock (m_scenes)
|
|
{
|
|
foreach (Scene rs in m_scenes.Values)
|
|
return rs;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private SceneObjectPart findPrim(UUID objectID)
|
|
{
|
|
lock (m_scenes)
|
|
{
|
|
foreach (Scene s in m_scenes.Values)
|
|
{
|
|
SceneObjectPart part = s.GetSceneObjectPart(objectID);
|
|
if (part != null)
|
|
{
|
|
return part;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Transfer money
|
|
/// </summary>
|
|
/// <param name="Sender"></param>
|
|
/// <param name="Receiver"></param>
|
|
/// <param name="amount"></param>
|
|
/// <returns></returns>
|
|
private bool doMoneyTransfer(UUID Sender, UUID Receiver, int amount, int transactiontype, string description)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
private void BalanceUpdate(UUID senderID, UUID receiverID, bool transactionresult, string description)
|
|
{
|
|
IClientAPI sender = LocateClientObject(senderID);
|
|
IClientAPI receiver = LocateClientObject(receiverID);
|
|
|
|
if (senderID != receiverID)
|
|
{
|
|
if (sender != null)
|
|
{
|
|
sender.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(senderID), 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty);
|
|
}
|
|
|
|
if (receiver != null)
|
|
{
|
|
receiver.SendMoneyBalance(UUID.Random(), transactionresult, Utils.StringToBytes(description), GetFundsForAgentID(receiverID), 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sends the the stored money balance to the client
|
|
/// </summary>
|
|
/// <param name="client"></param>
|
|
/// <param name="agentID"></param>
|
|
/// <param name="SessionID"></param>
|
|
/// <param name="TransactionID"></param>
|
|
public void SendMoneyBalance(IClientAPI client, UUID agentID, UUID SessionID, UUID TransactionID)
|
|
{
|
|
if (client.AgentId == agentID && client.SessionId == SessionID)
|
|
{
|
|
int returnfunds = 0;
|
|
|
|
try
|
|
{
|
|
returnfunds = GetFundsForAgentID(agentID);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
client.SendAlertMessage(e.Message + " ");
|
|
}
|
|
|
|
client.SendMoneyBalance(TransactionID, true, Array.Empty<byte>(), returnfunds, 0, UUID.Zero, false, UUID.Zero, false, 0, String.Empty);
|
|
}
|
|
else
|
|
{
|
|
client.SendAlertMessage("Unable to send your money balance to you!");
|
|
}
|
|
}
|
|
|
|
private int GetFundsForAgentID(UUID AgentID)
|
|
{
|
|
int returnfunds = 0;
|
|
|
|
return returnfunds;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Locates a IClientAPI for the client specified
|
|
/// </summary>
|
|
/// <param name="AgentID"></param>
|
|
/// <returns></returns>
|
|
private IClientAPI LocateClientObject(UUID AgentID)
|
|
{
|
|
ScenePresence tPresence;
|
|
lock (m_scenes)
|
|
{
|
|
foreach (Scene _scene in m_scenes.Values)
|
|
{
|
|
tPresence = _scene.GetScenePresence(AgentID);
|
|
if (tPresence != null && !tPresence.IsDeleted && !tPresence.IsChildAgent)
|
|
return tPresence.ControllingClient;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public bool NotifyTransfer(UUID transactionUUID, string msg2sender, string msg2receiver, string objectName)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: NotifyTransfer: User has accepted the transaction, now continue with the transaction");
|
|
|
|
try
|
|
{
|
|
if (m_moneyDBService.DoTransfer(transactionUUID))
|
|
{
|
|
TransactionData transaction = m_moneyDBService.FetchTransaction(transactionUUID);
|
|
if (transaction != null && transaction.Status == (int)Status.SUCCESS_STATUS)
|
|
{
|
|
//m_log.InfoFormat("[MONEY XMLRPC]: NotifyTransfer: Transaction Type = {0}", transaction.Type);
|
|
//m_log.InfoFormat("[MONEY XMLRPC]: NotifyTransfer: Payment finished successfully, now update balance {0}", transactionUUID.ToString());
|
|
|
|
bool updateSender = true;
|
|
bool updateReceiv = true;
|
|
if (transaction.Sender == transaction.Receiver) updateSender = false;
|
|
if (transaction.Type == (int)TransactionType.UploadCharge) updateReceiv = false;
|
|
|
|
if (updateSender)
|
|
{
|
|
UserInfo receiverInfo = m_moneyDBService.FetchUserInfo(transaction.Receiver);
|
|
string receiverName = "unknown user";
|
|
if (receiverInfo != null) receiverName = receiverInfo.Avatar;
|
|
string snd_message = string.Format(msg2sender, transaction.Amount, receiverName, objectName);
|
|
UpdateBalance(transaction.Sender, snd_message);
|
|
}
|
|
if (updateReceiv)
|
|
{
|
|
UserInfo senderInfo = m_moneyDBService.FetchUserInfo(transaction.Sender);
|
|
string senderName = "unknown user";
|
|
if (senderInfo != null) senderName = senderInfo.Avatar;
|
|
string rcv_message = string.Format(msg2receiver, transaction.Amount, senderName, objectName);
|
|
UpdateBalance(transaction.Receiver, rcv_message);
|
|
}
|
|
|
|
// Notify to sender
|
|
if (transaction.Type == (int)TransactionType.PayObject)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: NotifyTransfer: Now notify opensim to give object to customer {0} ", transaction.Sender);
|
|
Hashtable requestTable = new Hashtable();
|
|
requestTable["clientUUID"] = transaction.Sender;
|
|
requestTable["receiverUUID"] = transaction.Receiver;
|
|
|
|
if (m_sessionDic.ContainsKey(transaction.Sender) && m_secureSessionDic.ContainsKey(transaction.Sender))
|
|
{
|
|
requestTable["clientSessionID"] = m_sessionDic[transaction.Sender];
|
|
requestTable["clientSecureSessionID"] = m_secureSessionDic[transaction.Sender];
|
|
}
|
|
else
|
|
{
|
|
requestTable["clientSessionID"] = UUID.Zero.ToString();
|
|
requestTable["clientSecureSessionID"] = UUID.Zero.ToString();
|
|
}
|
|
requestTable["transactionType"] = transaction.Type;
|
|
requestTable["amount"] = transaction.Amount;
|
|
requestTable["objectID"] = transaction.ObjectUUID;
|
|
requestTable["objectName"] = transaction.ObjectName;
|
|
requestTable["regionHandle"] = transaction.RegionHandle;
|
|
|
|
UserInfo user = m_moneyDBService.FetchUserInfo(transaction.Sender);
|
|
if (user != null)
|
|
{
|
|
Hashtable responseTable = genericCurrencyXMLRPCRequest(requestTable, "OnMoneyTransfered", user.SimIP);
|
|
|
|
if (responseTable != null && responseTable.ContainsKey("success"))
|
|
{
|
|
//User not online or failed to get object ?
|
|
if (!(bool)responseTable["success"])
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: NotifyTransfer: User {0} can't get the object, rolling back.", transaction.Sender);
|
|
if (RollBackTransaction(transaction))
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: NotifyTransfer: Transaction {0} failed but roll back succeeded.", transactionUUID.ToString());
|
|
}
|
|
else
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: NotifyTransfer: Transaction {0} failed and roll back failed as well.",
|
|
transactionUUID.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: NotifyTransfer: Transaction {0} finished successfully.", transactionUUID.ToString());
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: NotifyTransfer: Transaction {0} failed.", transactionUUID.ToString());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: NotifyTransfer: exception occurred when transaction {0}: {1}", transactionUUID.ToString(), e.ToString());
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public XmlRpcResponse handleGetBalance(XmlRpcRequest request, IPEndPoint remoteClient)
|
|
{
|
|
GetSSLCommonName(request);
|
|
|
|
Hashtable requestData = (Hashtable)request.Params[0];
|
|
XmlRpcResponse response = new XmlRpcResponse();
|
|
Hashtable responseData = new Hashtable();
|
|
response.Value = responseData;
|
|
|
|
string clientUUID = string.Empty;
|
|
string sessionID = string.Empty;
|
|
string secureID = string.Empty;
|
|
int balance;
|
|
|
|
responseData["success"] = false;
|
|
|
|
if (requestData.ContainsKey("clientUUID")) clientUUID = (string)requestData["clientUUID"];
|
|
if (requestData.ContainsKey("clientSessionID")) sessionID = (string)requestData["clientSessionID"];
|
|
if (requestData.ContainsKey("clientSecureSessionID")) secureID = (string)requestData["clientSecureSessionID"];
|
|
|
|
m_log.InfoFormat("[MONEY XMLRPC]: handleGetBalance: Getting balance for user {0}", clientUUID);
|
|
|
|
if (m_sessionDic.ContainsKey(clientUUID) && m_secureSessionDic.ContainsKey(clientUUID))
|
|
{
|
|
if (m_sessionDic[clientUUID] == sessionID && m_secureSessionDic[clientUUID] == secureID)
|
|
{
|
|
try
|
|
{
|
|
balance = m_moneyDBService.getBalance(clientUUID);
|
|
if (balance == -1) // User not found
|
|
{
|
|
responseData["description"] = "user not found";
|
|
responseData["clientBalance"] = 0;
|
|
}
|
|
else if (balance >= 0)
|
|
{
|
|
responseData["success"] = true;
|
|
responseData["clientBalance"] = balance;
|
|
}
|
|
|
|
return response;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: handleGetBalance: Can't get balance for user {0}, Exception {1}", clientUUID, e.ToString());
|
|
}
|
|
return response;
|
|
}
|
|
}
|
|
|
|
m_log.Error("[MONEY XMLRPC]: handleGetBalance: Session authentication failed when getting balance for user " + clientUUID);
|
|
responseData["description"] = "Session check failure, please re-login";
|
|
return response;
|
|
}
|
|
|
|
private Hashtable genericCurrencyXMLRPCRequest(Hashtable reqParams, string method, string uri)
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: genericCurrencyXMLRPCRequest: to {0}", uri);
|
|
|
|
if (reqParams.Count <= 0 || string.IsNullOrEmpty(method)) return null;
|
|
|
|
if (m_checkServerCert)
|
|
{
|
|
if (!uri.StartsWith("https://"))
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: genericCurrencyXMLRPCRequest: CheckServerCert is true, but protocol is not HTTPS. Please check INI file.");
|
|
//return null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!uri.StartsWith("https://") && !uri.StartsWith("http://"))
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: genericCurrencyXMLRPCRequest: Invalid Region Server URL: {0}", uri);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
ArrayList arrayParams = new ArrayList();
|
|
arrayParams.Add(reqParams);
|
|
XmlRpcResponse moneyServResp = null;
|
|
try
|
|
{
|
|
NSLXmlRpcRequest moneyModuleReq = new NSLXmlRpcRequest(method, arrayParams);
|
|
moneyServResp = moneyModuleReq.certSend(uri, m_certVerify, m_checkServerCert, MONEYMODULE_REQUEST_TIMEOUT);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: genericCurrencyXMLRPCRequest: Unable to connect to Region Server {0}", uri);
|
|
m_log.ErrorFormat("[MONEY XMLRPC]: genericCurrencyXMLRPCRequest: {0}", ex.ToString());
|
|
|
|
Hashtable ErrorHash = new Hashtable();
|
|
ErrorHash["success"] = false;
|
|
ErrorHash["errorMessage"] = "Failed to perform actions on OpenSim Server";
|
|
ErrorHash["errorURI"] = "";
|
|
return ErrorHash;
|
|
}
|
|
|
|
if (moneyServResp == null || moneyServResp.IsFault)
|
|
{
|
|
Hashtable ErrorHash = new Hashtable();
|
|
ErrorHash["success"] = false;
|
|
ErrorHash["errorMessage"] = "Failed to perform actions on OpenSim Server";
|
|
ErrorHash["errorURI"] = "";
|
|
return ErrorHash;
|
|
}
|
|
|
|
Hashtable moneyRespData = (Hashtable)moneyServResp.Value;
|
|
return moneyRespData;
|
|
}
|
|
|
|
private void UpdateBalance(string userID, string message)
|
|
{
|
|
string sessionID = string.Empty;
|
|
string secureID = string.Empty;
|
|
|
|
// Konfiguriere das maximale Guthaben (dieser Wert kann aus einer Konfigurationsdatei wie MoneyServer.ini geladen werden)
|
|
//int m_CurrencyMaximum = m_CurrencyMaximum;
|
|
|
|
if (m_sessionDic.ContainsKey(userID) && m_secureSessionDic.ContainsKey(userID))
|
|
{
|
|
sessionID = m_sessionDic[userID];
|
|
secureID = m_secureSessionDic[userID];
|
|
|
|
// Aktuelles Guthaben des Benutzers abrufen
|
|
int currentBalance = m_moneyDBService.getBalance(userID);
|
|
|
|
// Überprüfen, ob das Guthaben über dem Maximum liegt und ggf. abziehen
|
|
if (currentBalance > m_CurrencyMaximum)
|
|
{
|
|
int excessAmount = currentBalance - m_CurrencyMaximum;
|
|
|
|
// Guthaben auf das Maximum reduzieren
|
|
bool balanceUpdateSuccess = ReduceUserBalance(userID, excessAmount);
|
|
if (!balanceUpdateSuccess)
|
|
{
|
|
m_log.ErrorFormat("[UpdateBalance]: Error reducing user balance for user {0}", userID);
|
|
return;
|
|
}
|
|
|
|
currentBalance = m_CurrencyMaximum;
|
|
m_log.InfoFormat("[UpdateBalance]: Reduced balance for user {0} by {1} to enforce maximum limit of {2}", userID, excessAmount, m_CurrencyMaximum);
|
|
}
|
|
|
|
Hashtable requestTable = new Hashtable();
|
|
requestTable["clientUUID"] = userID;
|
|
requestTable["clientSessionID"] = sessionID;
|
|
requestTable["clientSecureSessionID"] = secureID;
|
|
requestTable["Balance"] = currentBalance;
|
|
if (message != "") requestTable["Message"] = message;
|
|
|
|
UserInfo user = m_moneyDBService.FetchUserInfo(userID);
|
|
if (user != null)
|
|
{
|
|
genericCurrencyXMLRPCRequest(requestTable, "UpdateBalance", user.SimIP);
|
|
m_log.InfoFormat("[MONEY XMLRPC]: UpdateBalance: Sent UpdateBalance Request to {0}", user.SimIP.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool ReduceUserBalance(string userID, int amount)
|
|
{
|
|
string sql = "UPDATE balances SET balance = balance - ?amount WHERE user = ?userID";
|
|
MySQLSuperManager dbm = GetLockedConnection();
|
|
|
|
try
|
|
{
|
|
using (MySqlCommand cmd = new MySqlCommand(sql, dbm.Manager.dbcon))
|
|
{
|
|
cmd.Parameters.AddWithValue("?amount", amount);
|
|
cmd.Parameters.AddWithValue("?userID", userID);
|
|
|
|
int rowsAffected = cmd.ExecuteNonQuery();
|
|
return rowsAffected > 0;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
m_log.ErrorFormat("[ReduceUserBalance]: Error reducing user balance: {0}", ex.Message);
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
dbm.Release();
|
|
}
|
|
}
|
|
|
|
|
|
protected bool RollBackTransaction(TransactionData transaction)
|
|
{
|
|
if (m_moneyDBService.withdrawMoney(transaction.TransUUID, transaction.Receiver, transaction.Amount))
|
|
{
|
|
if (m_moneyDBService.giveMoney(transaction.TransUUID, transaction.Sender, transaction.Amount))
|
|
{
|
|
m_log.InfoFormat("[MONEY XMLRPC]: RollBackTransaction: Transaction {0} is successfully.", transaction.TransUUID.ToString());
|
|
m_moneyDBService.updateTransactionStatus(transaction.TransUUID, (int)Status.FAILED_STATUS,
|
|
"The buyer failed to get the object, roll back the transaction");
|
|
UserInfo senderInfo = m_moneyDBService.FetchUserInfo(transaction.Sender);
|
|
UserInfo receiverInfo = m_moneyDBService.FetchUserInfo(transaction.Receiver);
|
|
string senderName = "unknown user";
|
|
string receiverName = "unknown user";
|
|
if (senderInfo != null) senderName = senderInfo.Avatar;
|
|
if (receiverInfo != null) receiverName = receiverInfo.Avatar;
|
|
|
|
string snd_message = string.Format(m_BalanceMessageRollBack, transaction.Amount, receiverName, transaction.ObjectName);
|
|
string rcv_message = string.Format(m_BalanceMessageRollBack, transaction.Amount, senderName, transaction.ObjectName);
|
|
|
|
if (transaction.Sender != transaction.Receiver) UpdateBalance(transaction.Sender, snd_message);
|
|
UpdateBalance(transaction.Receiver, rcv_message);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|
|
// ################## classes ##################
|
|
#region classes
|
|
|
|
public class CashbookEntry
|
|
{
|
|
public string Date { get; set; }
|
|
public string Description { get; set; }
|
|
public int? Income { get; set; }
|
|
public int? Expense { get; set; }
|
|
public int Balance { get; set; }
|
|
}
|
|
|
|
public class JsonStreamHandler : CustomSimpleStreamHandler
|
|
{
|
|
public JsonStreamHandler(string path, Action<IOSHttpRequest, IOSHttpResponse> processAction)
|
|
: base(path, processAction)
|
|
{
|
|
}
|
|
}
|
|
|
|
public class CurrencyQuoteRequest
|
|
{
|
|
public string AgentId { get; set; }
|
|
public int CurrencyBuy { get; set; }
|
|
public string Language { get; set; }
|
|
public string SecureSessionId { get; set; }
|
|
public string ViewerBuildVersion { get; set; }
|
|
public string ViewerChannel { get; set; }
|
|
public int ViewerMajorVersion { get; set; }
|
|
public int ViewerMinorVersion { get; set; }
|
|
public int ViewerPatchVersion { get; set; }
|
|
}
|
|
|
|
public class LandPurchaseRequest
|
|
{
|
|
public string AgentId { get; set; }
|
|
public int BillableArea { get; set; }
|
|
public int CurrencyBuy { get; set; }
|
|
public string Language { get; set; }
|
|
public string SecureSessionId { get; set; }
|
|
}
|
|
|
|
public class BuyCurrencyRequest
|
|
{
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="BuyCurrencyRequest"/> class.
|
|
/// </summary>
|
|
public BuyCurrencyRequest()
|
|
{
|
|
// Initialize any default values or properties here
|
|
}
|
|
public string AgentId { get; set; }
|
|
public int CurrencyBuy { get; set; }
|
|
public string Language { get; set; }
|
|
public string SecureSessionId { get; set; }
|
|
public string ViewerBuildVersion { get; set; }
|
|
public string ViewerChannel { get; set; }
|
|
public int ViewerMajorVersion { get; set; }
|
|
public int ViewerMinorVersion { get; set; }
|
|
public int ViewerPatchVersion { get; set; }
|
|
|
|
public decimal Amount { get; set; }
|
|
|
|
public string CurrencyType { get; set; }
|
|
|
|
public bool IsValid()
|
|
{
|
|
// Add validation logic here, e.g., check for null or empty values
|
|
return Amount > 0 && !string.IsNullOrEmpty(CurrencyType);
|
|
}
|
|
}
|
|
#endregion
|