mirror of
https://github.com/GuduleLapointe/opensim-helpers.git
synced 2026-08-14 08:52:11 +00:00
582 lines
14 KiB
PHP
582 lines
14 KiB
PHP
<?php
|
|
/**
|
|
* economy.php
|
|
*
|
|
* Provides functions required only by currency.php and landtool.php
|
|
*
|
|
* Requires an OpenSimulator Money Server
|
|
* [DTL/NSL Money Server for OpenSim](http://www.nsl.tuis.ac.jp/xoops/modules/xpwiki/?OpenSim%2FMoneyServer)
|
|
* or [Gloebit module](http://dev.gloebit.com/opensim/configuration-instructions/)
|
|
*
|
|
* @package magicoli/opensim-helpers
|
|
* @author Gudule Lapointe <gudule@speculoos.world>
|
|
* @link https://github.com/magicoli/opensim-helpers
|
|
* @license AGPLv3
|
|
*
|
|
* Includes portions of code from original DTLS/NLS Money Server, by:
|
|
* Melanie Thielker and Teravus Ovares (http://opensimulator.org/)
|
|
* Fumi.Iseki for CMS/LMS '09 5/31
|
|
**/
|
|
|
|
require_once 'functions.php';
|
|
|
|
if ( defined( 'CURRENCY_DB_HOST' ) ) {
|
|
$CurrencyDB = new OSPDO( 'mysql:host=' . CURRENCY_DB_HOST . ';dbname=' . CURRENCY_DB_NAME, CURRENCY_DB_USER, CURRENCY_DB_PASS );
|
|
} else {
|
|
$CurrencyDB = &$OpenSimDB;
|
|
}
|
|
|
|
function noserver_save_transaction( $sourceId, $destId, $amount, $type, $flags, $desc, $prminvent, $nxtowner, $ip ) {
|
|
global $CurrencyDB;
|
|
|
|
if ( ! is_numeric( $amount ) ) {
|
|
return;
|
|
}
|
|
if ( ! opensim_isuuid( $sourceId ) ) {
|
|
$sourceId = NULL_KEY;
|
|
}
|
|
if ( ! opensim_isuuid( $destId ) ) {
|
|
$destId = NULL_KEY;
|
|
}
|
|
|
|
$region = NULL_KEY;
|
|
$client = $sourceId;
|
|
if ( $client == NULL_KEY ) {
|
|
$client = $destId;
|
|
}
|
|
|
|
$avt = opensim_get_avatar_session( $client );
|
|
if ( $avt != null ) {
|
|
$region = $avt['regionID'];
|
|
}
|
|
|
|
$CurrencyDB->insert(
|
|
CURRENCY_TRANSACTION_TBL,
|
|
array(
|
|
'sourceId' => $sourceId,
|
|
'destId' => $destId,
|
|
'amount' => $amount,
|
|
'flags' => $flags,
|
|
'aggregatePermInventory' => $prminvent,
|
|
'aggregatePermNextOwner' => $nxtowner,
|
|
'description' => $desc,
|
|
'transactionType' => $type,
|
|
'timeOccurred' => time(),
|
|
'RegionGenerated' => $region,
|
|
'ipGenerated' => $ip,
|
|
)
|
|
);
|
|
}
|
|
|
|
function noserver_get_balance( $agentID ) {
|
|
global $CurrencyDB;
|
|
|
|
if ( ! opensim_isuuid( $agentID ) ) {
|
|
return -1;
|
|
}
|
|
|
|
$sent_sum = 0;
|
|
$received_sum = 0;
|
|
|
|
$credits = $CurrencyDB->prepareAndExecute(
|
|
'SELECT SUM(amount) FROM ' . CURRENCY_TRANSACTION_TBL . ' WHERE destId = :destId',
|
|
array( 'destId' => $agentID )
|
|
);
|
|
if ( $credits ) {
|
|
list($received_sum) = $credits->fetch();
|
|
}
|
|
|
|
$debits = $CurrencyDB->prepareAndExecute(
|
|
'SELECT SUM(amount) FROM ' . CURRENCY_TRANSACTION_TBL . ' WHERE sourceId = :sourceId',
|
|
array( 'sourceId' => $agentID )
|
|
);
|
|
if ( $debits ) {
|
|
list($sent_sum) = $debits->fetch();
|
|
}
|
|
|
|
$cash = (int) $received_sum - (int) $sent_sum;
|
|
return $cash;
|
|
}
|
|
|
|
function currency_save_transaction( $sourceId, $destId, $amount, $type, $flags, $description, &$deprecated = null ) {
|
|
global $CurrencyDB;
|
|
|
|
if ( ! is_numeric( $amount ) ) {
|
|
return;
|
|
}
|
|
if ( ! opensim_isuuid( $sourceId ) ) {
|
|
$sourceId = NULL_KEY;
|
|
}
|
|
if ( ! opensim_isuuid( $destId ) ) {
|
|
$destId = NULL_KEY;
|
|
}
|
|
|
|
$handle = 0;
|
|
$secure = NULL_KEY;
|
|
$client = $sourceId;
|
|
$UUID = make_random_guid();
|
|
$sourceID = $sourceId;
|
|
$destID = $destId;
|
|
if ( $client == NULL_KEY ) {
|
|
$client = $destId;
|
|
}
|
|
|
|
$avt = opensim_get_avatar_session( $client );
|
|
if ( $avt != null ) {
|
|
$region = $avt['regionID'];
|
|
$secure = $avt['secureID'];
|
|
|
|
$rgn = opensim_get_region_info( $region );
|
|
if ( $rgn != null ) {
|
|
$handle = $rgn['regionHandle'];
|
|
}
|
|
}
|
|
|
|
$CurrencyDB->insert(
|
|
CURRENCY_TRANSACTION_TBL,
|
|
array(
|
|
'UUID' => $UUID,
|
|
'sender' => $sourceID,
|
|
'receiver' => $destID,
|
|
'amount' => $amount,
|
|
'objectUUID' => NULL_KEY,
|
|
'regionHandle' => $handle,
|
|
'type' => $type,
|
|
'time' => time(),
|
|
'secure' => $secure,
|
|
'status' => $flags,
|
|
'description' => $description,
|
|
)
|
|
);
|
|
}
|
|
|
|
function currency_set_currency_balance( $agentID, $amount, &$deprecated = null ) {
|
|
if ( ! opensim_isuuid( $agentID ) or ! is_numeric( $amount ) ) {
|
|
return false;
|
|
}
|
|
|
|
global $CurrencyDB;
|
|
$balances_table = CURRENCY_MONEY_TBL;
|
|
|
|
$CurrencyDB->query( "LOCK TABLES $balances_table" );
|
|
$currentbalance = $CurrencyDB->prepareAndExecute(
|
|
"SELECT balance FROM $balances_table WHERE user = :user",
|
|
array(
|
|
'user' => $agentID,
|
|
)
|
|
);
|
|
if ( $currentbalance ) {
|
|
list($cash) = $currentbalance->fetch();
|
|
$balance = (int) $cash + (int) $amount;
|
|
$result = $CurrencyDB->prepareAndExecute(
|
|
"UPDATE $balances_table SET balance = :balance WHERE user = :user",
|
|
array(
|
|
'balance' => $balance,
|
|
'user' => $agentID,
|
|
)
|
|
);
|
|
} else {
|
|
$result = false;
|
|
}
|
|
$CurrencyDB->query( "UNLOCK TABLES $balances_table" );
|
|
return $result;
|
|
}
|
|
|
|
function currency_update_simulator_balance( $agentID, $amount = -1, $secureID = null ) {
|
|
if ( ! opensim_isuuid( $agentID ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( $amount < 0 ) {
|
|
$amount = currency_get_balance( $agentID, $secureID );
|
|
if ( $amount < 0 ) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// XML RPC to Region Server
|
|
if ( ! opensim_isuuid( $secureID, true ) ) {
|
|
return false;
|
|
}
|
|
|
|
$agentServer = opensim_get_server_info( $agentID );
|
|
if ( ! $agentServer ) {
|
|
return false;
|
|
}
|
|
$serverip = $agentServer['serverIP'];
|
|
$httpport = $agentServer['serverHttpPort'];
|
|
$serveruri = $agentServer['serverURI'];
|
|
|
|
$avatarSession = opensim_get_avatar_session( $agentID );
|
|
if ( ! $avatarSession ) {
|
|
return false;
|
|
}
|
|
$sessionID = $avatarSession['sessionID'];
|
|
if ( $secureID == null ) {
|
|
$secureID = $avatarSession['secureID'];
|
|
}
|
|
|
|
$request = xmlrpc_encode_request(
|
|
'UpdateBalance',
|
|
array(
|
|
array(
|
|
'clientUUID' => $agentID,
|
|
'clientSessionID' => $sessionID,
|
|
'clientSecureSessionID' => $secureID,
|
|
'Balance' => $amount,
|
|
),
|
|
)
|
|
);
|
|
$response = currency_xmlrpc_call( $serverip, $httpport, $serveruri, $request );
|
|
|
|
return $response;
|
|
}
|
|
|
|
function currency_move_money( $agentID, $destID, $amount, $type, $flags, $desc, $prminvent = 0, $nxtowner = 0, $ip = '' ) {
|
|
if ( ! CURRENCY_USE_MONEYSERVER ) {
|
|
noserver_save_transaction( $agentID, $destID, $amount, $type, $flags, $desc, $prminvent, $nxtowner, $ip );
|
|
return true;
|
|
}
|
|
|
|
// Direct DB access for security
|
|
// $url = preg_split("/[:\/]/", USER_SERVER_URI);
|
|
// $userip = $url[3];
|
|
currency_save_transaction( $agentID, $destID, $amount, $type, $flags, $desc );
|
|
|
|
// TODO: Shouldn't we execute both balance updates only if all of the four
|
|
// conditions are met and none of them if any of the checks fails?
|
|
if ( opensim_isuuid( $agentID ) and $agentID != NULL_KEY ) {
|
|
currency_set_currency_balance( $agentID, -$amount );
|
|
}
|
|
if ( opensim_isuuid( $destID ) and $destID != NULL_KEY ) {
|
|
currency_set_currency_balance( $destID, $amount );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function currency_add_money( $agentID, $amount, $secureID = null ) {
|
|
if ( ! opensim_isuuid( $agentID ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! CURRENCY_USE_MONEYSERVER ) {
|
|
noserver_save_transaction( null, $agentID, $amount, 5010, 0, 'Add Money', 0, 0, '' );
|
|
$response = array( 'success' => true );
|
|
return $response;
|
|
}
|
|
|
|
//
|
|
// XML RPC to Region Server
|
|
//
|
|
if ( ! opensim_isuuid( $secureID, true ) ) {
|
|
return false;
|
|
}
|
|
|
|
$agentServer = opensim_get_server_info( $agentID );
|
|
$serverip = $agentServer['serverIP'];
|
|
$httpport = $agentServer['serverHttpPort'];
|
|
$serveruri = $agentServer['serverURI'];
|
|
if ( $serverip == '' ) {
|
|
return false;
|
|
}
|
|
|
|
$avatarSession = opensim_get_avatar_session( $agentID );
|
|
$sessionID = $avatarSession['sessionID'];
|
|
// if ($sessionID=="") return false;
|
|
if ( $secureID == null ) {
|
|
$secureID = $avatarSession['secureID'];
|
|
}
|
|
|
|
$request = xmlrpc_encode_request(
|
|
'AddBankerMoney',
|
|
array(
|
|
array(
|
|
'clientUUID' => $agentID,
|
|
'clientSessionID' => $sessionID,
|
|
'clientSecureSessionID' => $secureID,
|
|
'amount' => $amount,
|
|
),
|
|
)
|
|
);
|
|
$response = currency_xmlrpc_call( $serverip, $httpport, $serveruri, $request );
|
|
|
|
return $response;
|
|
}
|
|
|
|
//
|
|
// Send the money to avatar for bonus
|
|
// by Milo
|
|
//
|
|
function currency_send_money( $agentID, $amount, $secretCode = null ) {
|
|
if ( ! opensim_isuuid( $agentID ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! CURRENCY_USE_MONEYSERVER ) {
|
|
noserver_save_transaction( null, $agentID, $amount, 5003, 0, 'Send Money', 0, 0, '' );
|
|
$response = array( 'success' => true );
|
|
return $response;
|
|
}
|
|
|
|
//
|
|
// XML RPC to Region Server
|
|
//
|
|
$agentServer = opensim_get_server_info( $agentID );
|
|
$serverip = $agentServer['serverIP'];
|
|
$httpport = $agentServer['serverHttpPort'];
|
|
$serveruri = $agentServer['serverURI'];
|
|
if ( $serverip == '' ) {
|
|
return false;
|
|
}
|
|
$serverip = gethostbyname( $serverip );
|
|
|
|
if ( $secretCode != null ) {
|
|
$secretCode = md5( $secretCode . '_' . $serverip );
|
|
} else {
|
|
$secretCode = currency_get_confirm_value( $serverip );
|
|
}
|
|
|
|
$request = xmlrpc_encode_request(
|
|
'SendMoneyBalance',
|
|
array(
|
|
array(
|
|
'clientUUID' => $agentID,
|
|
'secretAccessCode' => $secretCode,
|
|
'amount' => $amount,
|
|
),
|
|
)
|
|
);
|
|
$response = currency_xmlrpc_call( $serverip, $httpport, $serveruri, $request );
|
|
|
|
return $response;
|
|
}
|
|
|
|
function currency_get_balance( $agentID, $secureID = null ) {
|
|
$cash = -1;
|
|
if ( ! opensim_isuuid( $agentID ) ) {
|
|
return (int) $cash;
|
|
}
|
|
|
|
if ( ! CURRENCY_USE_MONEYSERVER ) {
|
|
$cash = noserver_get_balance( $agentID );
|
|
return (int) $cash;
|
|
}
|
|
|
|
if ( ! opensim_isuuid( $secureID, true ) ) {
|
|
return (int) $cash;
|
|
}
|
|
|
|
$agentServer = opensim_get_server_info( $agentID );
|
|
$serverip = $agentServer['serverIP'];
|
|
$httpport = $agentServer['serverHttpPort'];
|
|
$serveruri = $agentServer['serverURI'];
|
|
if ( $serverip == '' ) {
|
|
return (int) $cash;
|
|
}
|
|
|
|
$avatarSession = opensim_get_avatar_session( $agentID );
|
|
$sessionID = $avatarSession['sessionID'];
|
|
if ( $sessionID == '' ) {
|
|
return (int) $cash;
|
|
}
|
|
if ( $secureID == null ) {
|
|
$secureID = $avatarSession['secureID'];
|
|
}
|
|
|
|
$request = xmlrpc_encode_request(
|
|
'GetBalance',
|
|
array(
|
|
array(
|
|
'clientUUID' => $agentID,
|
|
'clientSessionID' => $sessionID,
|
|
'clientSecureSessionID' => $secureID,
|
|
),
|
|
)
|
|
);
|
|
$response = currency_xmlrpc_call( $serverip, $httpport, $serveruri, $request );
|
|
|
|
if ( $response ) {
|
|
$cash = $response['balance'];
|
|
}
|
|
return (int) $cash;
|
|
}
|
|
|
|
function currency_get_confirm_value( $ipAddress ) {
|
|
// TODO:
|
|
// Option to force key to be something else than default
|
|
$key = empty( CURRENCY_SCRIPT_KEY ) ? '1234567883789' : CURRENCY_SCRIPT_KEY;
|
|
$confirmvalue = md5( $key . '_' . $ipAddress );
|
|
|
|
return $confirmvalue;
|
|
}
|
|
|
|
function currency_process_transaction( $avatarID, $cost, $ipAddress ) {
|
|
// Do external processing here! (credit card, paypal, any money system)
|
|
// Return False if it fails!
|
|
// Remember, $amount is stored without decimal places, however it's assumed
|
|
// that the transaction amount is in Cents and has two decimal places
|
|
// 5 dollars will be 500
|
|
// 15 dollars will be 1500
|
|
|
|
// if ($avatarID==CURRENCY_BANKER) return true;
|
|
// return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
function currency_virtual_to_real( $amount ) {
|
|
$cost = (int) ( CURRENCY_RATE / CURRENCY_RATE_PER * 100 * $amount );
|
|
|
|
return $cost;
|
|
}
|
|
|
|
|
|
// XML RPC
|
|
function currency_xmlrpc_call( $host, $port, $uri, $request ) {
|
|
$url = '';
|
|
if ( $uri != '' ) {
|
|
$dec = explode( ':', $uri );
|
|
if ( ! strncasecmp( $dec[0], 'http', 4 ) ) {
|
|
$url = "$dec[0]:$dec[1]";
|
|
}
|
|
}
|
|
if ( $url == '' ) {
|
|
$url = "http://$host";
|
|
}
|
|
$url = "$url:$port/";
|
|
|
|
// TODO: use file_get_contents() instead of over complicate curl procedure
|
|
$header[] = 'Content-type: text/xml';
|
|
$header[] = 'Content-length: ' . strlen( $request );
|
|
|
|
$ch = curl_init();
|
|
curl_setopt( $ch, CURLOPT_URL, $url );
|
|
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
|
|
curl_setopt( $ch, CURLOPT_TIMEOUT, 3 );
|
|
curl_setopt( $ch, CURLOPT_HTTPHEADER, $header );
|
|
curl_setopt( $ch, CURLOPT_POSTFIELDS, $request );
|
|
|
|
$data = curl_exec( $ch );
|
|
if ( ! curl_errno( $ch ) ) {
|
|
curl_close( $ch );
|
|
}
|
|
|
|
$ret = false;
|
|
if ( $data ) {
|
|
$ret = xmlrpc_decode( $data );
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
/**
|
|
* Following functions are not specific to money and could be useful in other
|
|
* helpers. However, they are not: they are currently only used in currency
|
|
* scripts, so I leave them here, hence the opensim_ prefix.
|
|
*/
|
|
function opensim_get_avatar_session( $agentID, &$deprecated = null ) {
|
|
global $OpenSimDB;
|
|
if ( ! opensim_isuuid( $agentID ) ) {
|
|
return null;
|
|
}
|
|
|
|
$result = $OpenSimDB->query( "SELECT RegionID,SessionID,SecureSessionID FROM Presence WHERE UserID='$agentID'" );
|
|
if ( $result ) {
|
|
list($RegionID, $SessionID, $SecureSessionID) = $result->fetch();
|
|
} else {
|
|
return array();
|
|
}
|
|
|
|
$av_session['regionID'] = $RegionID;
|
|
$av_session['sessionID'] = $SessionID;
|
|
$av_session['secureID'] = $SecureSessionID;
|
|
|
|
return $av_session;
|
|
}
|
|
|
|
function opensim_set_current_region( $agentID, $regionid, &$deprecated = null ) {
|
|
global $OpenSimDB;
|
|
|
|
if ( ! opensim_isuuid( $agentID ) or ! opensim_isuuid( $regionid ) ) {
|
|
return false;
|
|
}
|
|
|
|
$sql = "UPDATE Presence SET RegionID='$regionid' WHERE UserID='$agentID'";
|
|
$result = $OpenSimDB->query( $sql );
|
|
if ( ! $result ) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function opensim_get_server_info( $userid, &$deprecated = null ) {
|
|
global $OpenSimDB;
|
|
if ( ! opensim_isuuid( $userid ) ) {
|
|
return array();
|
|
}
|
|
|
|
$result = $OpenSimDB->query(
|
|
"SELECT serverIP,serverHttpPort,serverURI,regionSecret
|
|
FROM GridUser INNER JOIN regions ON regions.uuid=GridUser.LastRegionID
|
|
WHERE GridUser.UserID='$userid'"
|
|
);
|
|
if ( $result ) {
|
|
list($serverip, $httpport, $serveruri, $secret) = $result->fetch();
|
|
} else {
|
|
return array();
|
|
}
|
|
|
|
$serverinfo['serverIP'] = $serverip;
|
|
$serverinfo['serverHttpPort'] = $httpport;
|
|
$serverinfo['serverURI'] = $serveruri;
|
|
$serverinfo['regionSecret'] = $secret;
|
|
return $serverinfo;
|
|
}
|
|
|
|
function opensim_check_secure_session( $agentID, $regionid, $secure, &$deprecated = null ) {
|
|
global $OpenSimDB;
|
|
if ( ! opensim_isuuid( $agentID ) or ! opensim_isuuid( $secure ) ) {
|
|
return false;
|
|
}
|
|
|
|
$sql = "SELECT UserID FROM Presence WHERE UserID='$agentID' AND SecureSessionID='$secure'";
|
|
if ( opensim_isuuid( $regionid ) ) {
|
|
$sql = $sql . " AND RegionID='$regionid'";
|
|
}
|
|
|
|
$result = $OpenSimDB->query( $sql );
|
|
if ( ! $result ) {
|
|
return false;
|
|
}
|
|
|
|
list($UUID) = $result->fetch();
|
|
if ( $UUID != $agentID ) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function opensim_check_region_secret( $regionID, $secret, &$deprecated = null ) {
|
|
global $OpenSimDB;
|
|
if ( ! opensim_isuuid( $regionID ) ) {
|
|
return false;
|
|
}
|
|
|
|
$result = $OpenSimDB->prepareAndExecute(
|
|
'SELECT UUID FROM regions WHERE UUID=:uuid AND regionSecret=:regionSecret',
|
|
array(
|
|
'uuid' => $regionID,
|
|
'regionSecret' => $secret,
|
|
)
|
|
);
|
|
if ( $result ) {
|
|
list($UUID) = $result->fetch();
|
|
if ( $UUID == $regionID ) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|