Initial commit

This commit is contained in:
Adil El Farissi
2024-07-02 14:27:34 +00:00
commit 81882b6ef0
49 changed files with 13804 additions and 0 deletions
+2
View File
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Adil El Farissi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+22
View File
@@ -0,0 +1,22 @@
MIT License
Copyright (c) [Fumi.Iseki and NSL](http://www.nsl.tuis.ac.jp)
Modified by Adil El Farissi for BTCPay Server (2024)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+182
View File
@@ -0,0 +1,182 @@
#Opensimulator Money Server With BTCPay Integration.
###Outline:
This is a modified version of DTL/NSL Secure Money Server by [Fumi.Iseki and NSL](http://www.nsl.tuis.ac.jp) re-worked to interact with [BTCPay Server](https://github.com/btcpayserver/btcpayserver) as cryptocurrencies payment gateway and processor in a self-sovereign context, where you have 100% of the control and you are behind your own system without any fees or Third-parties... Freedom.
###Change Log:
+ Upgraded to dotnet 8 (Cross-platforms, Compatible OpenSim >= 0.9.3).
+ Add support for standalones instances.
+ Add BTCPay related MySQL tables and their respective handlers.
+ Add TLS/SSL support to the region module server.
+ Replaced HttpWebRequest by HttpClient.
+ Add BTCPay related XMLRPC handlers and respective methods in the region module.
+ Add BTCPay related functions in the PHP side to fetch the current rates, request BTCPay invoices and pull payments for withdrawals.
+ Add web interfaces for the currency purchases and withdrawals.
+ Add some security checks and verifications.
+ Removed all unnecessary PHP files for this BTCPay Server integration.
+ Many fixes and optimizations...
###Requirements:
+ A correctly installed and synced BTCPay instance with a correctly set store and wallet. Those can be self-hosted or installed on a VPS... or you can use a third-party host without installations (not recommanded!). more infos here:
https://docs.btcpayserver.org/Deployment/
+ A PHP server under https (important! don't use without TLS/SSL). Due to the removal of the xmlrpc-encode/decode and the json_encode/decode functions in PHP8 without a replacement, the max compatible PHP version is the last PHP7. The PHP part do not work with PHP8.
+ Opensimulator >= v0.9.3 (SSL/TLSed recommanded).
###Viewers Compatibility:
This version is compatible with [Firestorm](http://firestormviewer.org/) Viewer that allows the display of the crypto amounts in the Buy Currency and lands windows... The currency and lands purchases using the viewer windows may not work in the others!
As solution, i added a web interface for the currency purchases and withdrawals to what you can point your end-user. Is also possible to sell/buy back the local currency using LSL scripts (scripts not included!)...
+ For the currency buy:
https://your-domain-or-ip.here/helper_scripts/helper/currency-buy.php
+ For the withdrawals:
https://your-domain-or-ip.here/helper_scripts/helper/withdrawals.php
###Installation
The installation depend on your operating system and if a compilation is needed but in general is the same for all OS.
0. You need an SSL/TLS valid or self-signed Pkcs12 certificate (.pfx or .p12 extension). Please don't use this software if the server/module/php are not under https! this trilogy exchange some sensive data and is all what a malicious person need to harm! not only in the money level!!!
1. Copy the content of the "ready-bin" folder to "opensim-0.9.3/bin" in linux or "opensim-0.9.3\bin" in windows
2. Upload or copy the "helper_scripts" folder to your PHP7 web server. You can change the folder name if you want... the "helper" folder must be accessible eg; https://your-domain-or-ip.here/helper_scripts/helper/
###Compiling
place the "btcpay-opensim-currency" in the OpenSimulator source root folder.
+ In Windows, run or double click
# opensim-0.9.3-source\btcpay-opensim-currency\runprebuild.bat
This will create the solution and produce a compile.bat files... run or double click
# opensim-0.9.3-source\btcpay-opensim-currency\compile.bat
A successful compilation will add a "bin" folder inside "btcpay-opensim-currency" with the target sub-folder "net8.0" where you will find the Money Server executable and the module DLLs...
# opensim-0.9.3-source\btcpay-opensim-currency\bin\net8.0\
+ In Linux&Co, is the same as Windows but the file extension is .sh
# cd opensim-0.9.3-source
# cd btcpay-opensim-currency
# ./runprebuild.sh
# ./compile.sh
###Setting
1. Money Server
Open "opensim-0.9.3/bin/MoneyServer.ini" or "opensim-0.9.3\bin\MoneyServer.ini" with a text editor or IDE.
- Set the OpenSim MySQL hostname, database, username and password in the [MySql] section (must be the same as [DatabaseService] in your StandaloneCommun or GridCommun .ini).
- If you use a Banker Avatar, please set UUID of Banker Avatar to "BankerAvatar" in MoneyServer.ini.
When 00000000-0000-0000-0000-000000000000 is specified as UUID, all avatars can get money from system.
- If you want to normally use llGiveMoney() function even when payer doesn't login to OpenSim, you must set "true" to "enableForceTransfer".
- If you want to send money to another avatar by PHP script, you must set "true" to "enableScriptSendMoney" And please set "MoneyScriptAccessKey" and "MoneyScriptIPaddress". "MoneyScriptAccessKey" is Secret key of Helper Script. Specify same key in include/config.php and OpenSim.ini. "MoneyScriptIPaddress" is IP address of server that Helper Script execute at. Not specify 127.0.0.1.
- If you want to change Update Balance Messages (blue dialog), pleaase enable and rewrite "BalanceMessage..." valiables.
2. Region Server
Open "opensim-0.9.3/bin/OpenSim.ini" or "opensim-0.9.3\bin\OpenSim.ini" with a text editor or IDE and scroll down to the [Economy] section. Open "opensim-config\OpenSim.ini.sample" copy/paste and modify what is needed. eg:
[Economy]
; Set the economy module name.
EconomyModule = DTLNSLMoneyModule
; Do you want to allow 0 currency transactions?
SellEnabled = true
; Set your PHP web server URL pointing to the "helper" folder with "/" at the end.
Economy = "https://your-domain-or-ip.here/helper_scripts/helper/
; Set the Money Server URL.
CurrencyServer = "https://your-domain-or-ip.here:8008"
; Verify the server certificate? keep false... (buggy! may not work)
CheckServerCert = false
; Set the module certificate and password.
ClientCertFilename = "SineWaveCert.pfx"
ClientCertPassword = "123"
; Set the things prices...
PriceUpload = 10
PriceGroupCreate = 100
; Mesh upload factors
MeshModelUploadCostFactor = 2.5
MeshModelUploadTextureCostFactor = 1.0
MeshModelMinCostFactor = 2.0
; Set the minimum amount to buy currency from the system.
MinimumAmount = 250
; Set the same secret key as MoneyScriptAccessKey in include/config.php and MoneyServer.ini
MoneyAccessKey = "123456789"
; Avatar Class for HG Avatar
; {ForeignAvatar, HGAvatar, GuestAvatar, LocalAvatar} HGAvatar
; HG Avatar is assumed as a specified avatar class. Default is HGAvatar
; Processing for each avatar class is dependent on Money Server settings.
HGAvatarAs = "HGAvatar"
Notes: Do not use 127.0.0.1 or localhost for CurrencyServer's address. This address is used for identification of user on Money Server.
3. PHP Helper Scripts
Open "/helper_scripts/include/config.php", read the guides "comments" and follow the instructions to get/set what is needed for the BTCPay integration.
Note: Please do your best to protect the "include" folder and the config.php file with strict permissions and htaccess if supported.
###Execution
1. Standalones:
+ In windows, run or double click MoneyServer.exe before OpenSim.exe.
+ In linux&Co:
# cd opensim-0.9.3
# cd bin
# dotnet MoneyServer.dll
# dotnet OpenSim.dll
2. Grids
+ In windows, run or double click Robust.exe, next MoneyServer.exe before OpenSim.exe.
+ In linux&Co:
# cd opensim-0.9.3
# cd bin
# dotnet Robust.dll
# dotnet MoneyServer.dll
# dotnet OpenSim.dll
When done and all started without problems, use Firestorm to test a currency purchase from the viewer. You can also use the web interfaces to test.
+ For the currency buy:
https://your-domain-or-ip.here/helper_scripts/helper/currency-buy.php
+ For the withdrawals:
https://your-domain-or-ip.here/helper_scripts/helper/withdrawals.php
###Web Interfaces.
The currency purchases web interface can take 2 parameters that auto-fill the form:
+ account: Avatar UUID.
+ amount: The amount of local currency to buy.
So, you can point the user to this page using llLoadURL...
https://your-domain-or-ip.here/helper_scripts/helper/currency-buy.php?account=UUID&amount=1234
The withdrawal web interface can take 1 parameter:
+ account : Avatar UUID.
https://your-domain-or-ip.here/helper_scripts/helper/withdrawals.php?account=UUID
###Attention.
This is unofficial software. Please do not inquire to OpenSim development team or DTL Currency Processing development team or NSL team about this.
###Exemption from responsibility.
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Use at your own risks!
###Thanks where due.
+ This is a modified version of DTL/NSL Secure Money Server by [Fumi.Iseki and NSL](http://www.nsl.tuis.ac.jp)
+ Special thanks to [Fumi.Iseki and NSL Team](http://www.nsl.tuis.ac.jp).
+ Special thanks to BTCPay Server Team.
+ Special thanks to [OpenSimulator Team](http://opensimulator.org/).
Thank you very much!!!
+22
View File
@@ -0,0 +1,22 @@
MIT License
Copyright (c) [Fumi.Iseki and NSL](http://www.nsl.tuis.ac.jp)
Modified by Adil El Farissi for BTCPay Server (2024)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,55 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenMetaverse;
namespace OpenSim.Data.MySQL.MySQLMoneyDataWrapper
{
public interface IMoneyManager
{
int GetBalance(string userID);
bool WithdrawMoney(UUID transactionID,string senderID, int amount);
bool GiveMoney(UUID transactionID,string receiverID, int amount);
bool AddTransaction(TransactionData transaction);
bool UpdateTransactionStatus(UUID transactionID, int status,string description);
TransactionData FetchTransaction(UUID transactionID);
TransactionData[] FetchTransaction(string userID, int startTime, int endTime, uint index,uint retNum);
int GetTransactionNum(string userID, int startTime, int endTime);
bool AddUser(string userID, int balance, int status, int type);
bool SetTransExpired(int deadTime);
bool ValidateTransfer(string secureCode, UUID transactionID);
bool AddUserInfo(UserInfo user);
UserInfo FetchUserInfo(string userID);
bool UpdateUserInfo(UserInfo user);
bool AddUserPresence(UserPresence user);
UserPresence fetchUserPresence(string userID);
bool UpdateUserPresence(UserPresence user);
}
}
@@ -0,0 +1,52 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*
* 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 OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Threading;
namespace OpenSim.Data.MySQL.MySQLMoneyDataWrapper
{
// This bit of code is from OpenSim.Data.MySQLSuperManager
public class MySQLSuperManager
{
public bool Locked;
private readonly Mutex m_lock = new Mutex(false);
public MySQLMoneyManager Manager;
public string Running;
public void GetLock()
{
Locked = true;
m_lock.WaitOne();
}
public void Release()
{
m_lock.ReleaseMutex();
Locked = false;
}
}
}
@@ -0,0 +1,263 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using OpenMetaverse;
namespace OpenSim.Data.MySQL.MySQLMoneyDataWrapper
{
public class TransactionData
{
UUID m_uuid;
string m_sender = string.Empty;
string m_receiver = string.Empty;
int m_amount;
int m_senderBalance;
int m_receiverBalance;
int m_type;
int m_time;
int m_status;
string m_objectID = UUID.Zero.ToString();
// string m_objectID = "00000000-0000-0000-0000-000000000000";
string m_objectName = string.Empty;
string m_regionHandle = string.Empty;
string m_regionUUID = string.Empty;
string m_secureCode = string.Empty;
string m_commonName = string.Empty;
string m_description = string.Empty;
/*
public TransactionData(string uuid, string sender, string receiver,
int amount, int time, int status, string description)
{
this.m_uuid = uuid;
this.m_sender = sender;
this.m_receiver = receiver;
this.m_amount = amount;
}
*/
public UUID TransUUID
{
get { return m_uuid; }
set { m_uuid = value; }
}
public string Sender
{
get { return m_sender; }
set { m_sender = value; }
}
public string Receiver
{
get { return m_receiver; }
set { m_receiver = value; }
}
public int Amount
{
get { return m_amount; }
set { m_amount = value; }
}
public int SenderBalance
{
get { return m_senderBalance; }
set { m_senderBalance = value; }
}
public int ReceiverBalance
{
get { return m_receiverBalance; }
set { m_receiverBalance = value; }
}
public int Type
{
get { return m_type; }
set { m_type = value; }
}
public int Time
{
get { return m_time; }
set { m_time = value; }
}
public int Status
{
get { return m_status; }
set { m_status = value; }
}
public string Description
{
get { return m_description; }
set { m_description = value; }
}
public string ObjectUUID
{
get { return m_objectID; }
set { m_objectID = value; }
}
public string ObjectName
{
get { return m_objectName; }
set { m_objectName = value; }
}
public string RegionHandle
{
get { return m_regionHandle; }
set { m_regionHandle = value; }
}
public string RegionUUID
{
get { return m_regionUUID; }
set { m_regionUUID = value; }
}
public string SecureCode
{
get { return m_secureCode; }
set { m_secureCode = value; }
}
public string CommonName
{
get { return m_commonName; }
set { m_commonName = value; }
}
}
public enum Status
{
SUCCESS_STATUS = 0,
PENDING_STATUS = 1,
FAILED_STATUS = 2,
ERROR_STATUS = 9
}
public enum AvatarType
{
LOCAL_AVATAR = 0,
HG_AVATAR = 1,
NPC_AVATAR = 2,
GUEST_AVATAR = 3,
FOREIGN_AVATAR = 8,
UNKNOWN_AVATAR = 9
}
public class UserInfo
{
string m_userID = string.Empty;
string m_simIP = string.Empty;
string m_avatarName = string.Empty;
string m_passwordHash = string.Empty;
int m_avatarType = (int)AvatarType.LOCAL_AVATAR;
int m_avatarClass = (int)AvatarType.LOCAL_AVATAR;
string m_serverURL = string.Empty;
public string UserID
{
get { return m_userID; }
set { m_userID = value; }
}
public string SimIP
{
get { return m_simIP; }
set { m_simIP = value; }
}
public string Avatar
{
get { return m_avatarName; }
set { m_avatarName = value; }
}
public string PswHash
{
get { return m_passwordHash; }
set { m_passwordHash = value; }
}
public int Type
{
get { return m_avatarType; }
set { m_avatarType = value; }
}
public int Class
{
get { return m_avatarClass; }
set { m_avatarClass = value; }
}
public string ServerURL
{
get { return m_serverURL; }
set { m_serverURL = value; }
}
}
public class UserPresence
{
string m_UserID = string.Empty;
string m_SessionID = string.Empty;
string m_SecureSessionID = string.Empty;
string m_LastSeen = string.Empty;
public string UserID
{
get { return m_UserID; }
set { m_UserID = value; }
}
public string SessionID
{
get { return m_SessionID; }
set { m_SessionID = value; }
}
public string SecureSessionID
{
get { return m_SecureSessionID; }
set { m_SecureSessionID = value; }
}
public string LastSeen
{
get { return m_LastSeen; }
set { m_LastSeen = value; }
}
}
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/, http://www.nsl.tuis.ac.jp/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//using System.Linq;
using OpenMetaverse;
using OpenSim.Data.MySQL.MySQLMoneyDataWrapper;
namespace OpenSim.Grid.MoneyServer
{
public interface IMoneyDBService
{
int GetBalance(string userID);
bool WithdrawMoney(UUID transactionID, string senderID, int amount);
bool GiveMoney(UUID transactionID, string receiverID, int amount);
bool AddTransaction(TransactionData transaction);
bool AddUser(string userID, int balance, int status, int type);
bool UpdateTransactionStatus(UUID transactionID, int status, string description);
bool SetTransExpired(int deadTime);
bool ValidateTransfer(string secureCode, UUID transactionID);
TransactionData FetchTransaction(UUID transactionID);
TransactionData FetchTransaction(string userID, int startTime, int endTime, int lastIndex);
int GetTransactionNum(string userID, int startTime, int endTime);
bool DoTransfer(UUID transactionUUID);
bool DoAddMoney(UUID transactionUUID); // Added by Fumi.Iseki
bool TryAddUserInfo(UserInfo user, UserPresence data);
UserInfo FetchUserInfo(string userID);
UserPresence FetchUserPresence(string userID);
bool RemoveUserPresence(string userID);
}
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using OpenSim.Framework.Servers.HttpServer;
using Nini.Config;
namespace OpenSim.Grid.MoneyServer
{
public interface IMoneyServiceCore
{
BaseHttpServer GetHttpServer();
Dictionary<string, string> GetSessionDic();
Dictionary<string, string> GetSecureSessionDic();
Dictionary<string, string> GetWebSessionDic();
IConfig GetServerConfig();
IConfig GetCertConfig();
bool IsCheckClientCert();
}
}
@@ -0,0 +1,643 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/, http://www.nsl.tuis.ac.jp/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using OpenSim.Data.MySQL.MySQLMoneyDataWrapper;
using OpenSim.Modules.Currency;
using log4net;
using System.Reflection;
using OpenMetaverse;
namespace OpenSim.Grid.MoneyServer
{
class MoneyDBService: IMoneyDBService
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_connect;
//private MySQLMoneyManager m_moneyManager;
private long TicksToEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
// DB manager pool
protected Dictionary<int, MySQLSuperManager> m_dbconnections = new Dictionary<int, MySQLSuperManager>(); // Lock付
private int m_maxConnections;
public int m_lastConnect = 0;
public MoneyDBService(string connect)
{
m_connect = connect;
Initialise(m_connect,10);
}
public MoneyDBService()
{
}
public void Initialise(string connectionString, int maxDBConnections)
{
m_connect = connectionString;
m_maxConnections = maxDBConnections;
if (connectionString != string.Empty) {
//m_moneyManager = new MySQLMoneyManager(connectionString);
//m_log.Info("Creating " + m_maxConnections + " DB connections...");
for (int i=0; i<m_maxConnections; i++) {
//m_log.Info("Connecting to DB... [" + i + "]");
MySQLSuperManager msm = new MySQLSuperManager();
msm.Manager = new MySQLMoneyManager(connectionString);
m_dbconnections.Add(i, msm);
}
}
else {
m_log.Error("[MONEY DB]: Connection string is null, initialise database failed");
throw new Exception("Failed to initialise MySql database");
}
}
public void Reconnect()
{
for (int i=0; i<m_maxConnections; i++) {
MySQLSuperManager msm = m_dbconnections[i];
msm.Manager.Reconnect();
}
}
private MySQLSuperManager GetLockedConnection()
{
int lockedCons = 0;
while (true) {
m_lastConnect++;
// Overflow protection
if (m_lastConnect==int.MaxValue) m_lastConnect = 0;
MySQLSuperManager msm = m_dbconnections[m_lastConnect%m_maxConnections];
if (!msm.Locked) {
msm.GetLock();
return msm;
}
lockedCons++;
if (lockedCons>m_maxConnections) {
lockedCons = 0;
System.Threading.Thread.Sleep(1000); // Wait some time before searching them again.
m_log.Debug("WARNING: All threads are in use. Probable cause: Something didnt release a mutex properly, or high volume of requests inbound.");
}
}
}
public int GetBalance(string userID)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.GetBalance(userID);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.GetBalance(userID);
}
catch(Exception e) {
m_log.Error(e.ToString());
return 0;
}
finally {
dbm.Release();
}
}
public bool WithdrawMoney(UUID transactionID, string senderID, int amount)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.WithdrawMoney(transactionID, senderID, amount);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.WithdrawMoney(transactionID, senderID, amount);
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public bool GiveMoney(UUID transactionID, string receiverID, int amount)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.GiveMoney(transactionID, receiverID, amount);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.GiveMoney(transactionID, receiverID, amount);
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public bool setTotalSale(TransactionData transaction)
{
if (transaction.Receiver==transaction.Sender) return false;
if (transaction.Sender==UUID.Zero.ToString()) return false;
MySQLSuperManager dbm = GetLockedConnection();
int time = (int)((DateTime.UtcNow.Ticks - TicksToEpoch) / 10000000);
try {
return dbm.Manager.SetTotalSale(transaction.Receiver, transaction.ObjectUUID, transaction.Type, 1, transaction.Amount, time);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.SetTotalSale(transaction.Receiver, transaction.ObjectUUID, transaction.Type, 1, transaction.Amount, time);
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public bool AddTransaction(TransactionData transaction)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.AddTransaction(transaction);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.AddTransaction(transaction);
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public bool AddUser(string userID, int balance, int status, int type)
{
TransactionData transaction = new TransactionData();
transaction.TransUUID = UUID.Random();
transaction.Sender = UUID.Zero.ToString();
transaction.Receiver = userID;
transaction.Amount = balance;
transaction.ObjectUUID = UUID.Zero.ToString();
transaction.ObjectName = string.Empty;
transaction.RegionHandle = string.Empty;
transaction.Type = (int)TransactionType.BirthGift;
transaction.Time = (int)((DateTime.UtcNow.Ticks - TicksToEpoch) / 10000000);;
transaction.Status = (int)Status.PENDING_STATUS;
transaction.SecureCode = UUID.Random().ToString();
transaction.CommonName = string.Empty;
transaction.Description = "addUser " + DateTime.UtcNow.ToString();
bool ret = AddTransaction(transaction);
if (!ret) return false;
//
MySQLSuperManager dbm = GetLockedConnection();
try {
ret = dbm.Manager.AddUser(userID, 0, status, type); // make Balance Table
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
ret = dbm.Manager.AddUser(userID, 0, status, type); // make Balance Table
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
//
if (ret) ret = GiveMoney(transaction.TransUUID, userID, balance);
return ret;
}
public bool UpdateTransactionStatus(UUID transactionID, int status, string description)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.UpdateTransactionStatus(transactionID, status, description);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.UpdateTransactionStatus(transactionID, status, description);
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public bool SetTransExpired(int deadTime)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.SetTransExpired(deadTime);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.SetTransExpired(deadTime);
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public bool ValidateTransfer(string secureCode, UUID transactionID)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.ValidateTransfer(secureCode, transactionID);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.ValidateTransfer(secureCode, transactionID);
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public TransactionData FetchTransaction(UUID transactionID)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.FetchTransaction(transactionID);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.FetchTransaction(transactionID);
}
catch (Exception e) {
m_log.Error(e.ToString());
return null;
}
finally {
dbm.Release();
}
}
public TransactionData FetchTransaction(string userID, int startTime, int endTime, int lastIndex)
{
MySQLSuperManager dbm = GetLockedConnection();
TransactionData[] arrTransaction;
uint index = 0;
if (lastIndex>=0) index = Convert.ToUInt32(lastIndex) + 1;
try {
arrTransaction = dbm.Manager.FetchTransaction(userID, startTime, endTime, index, 1);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
arrTransaction = dbm.Manager.FetchTransaction(userID, startTime, endTime, index, 1);
}
catch (Exception e) {
m_log.Error(e.ToString());
return null;
}
finally {
dbm.Release();
}
//
if (arrTransaction.Length > 0) {
return arrTransaction[0];
}
else {
return null;
}
}
public bool DoTransfer(UUID transactionUUID)
{
bool do_trans = false;
TransactionData transaction = new TransactionData();
transaction = FetchTransaction(transactionUUID);
if (transaction != null && transaction.Status == (int)Status.PENDING_STATUS) {
int balance = GetBalance(transaction.Sender);
//check the amount
if (transaction.Amount >= 0 && balance >= transaction.Amount) {
if (WithdrawMoney(transactionUUID, transaction.Sender, transaction.Amount)) {
//If receiver not found, add it to DB.
if (GetBalance(transaction.Receiver) == -1) {
m_log.ErrorFormat("[MONEY DB]: DoTransfer: Receiver not found in balances DB. {0}", transaction.Receiver);
return false;
}
if (GiveMoney(transactionUUID, transaction.Receiver, transaction.Amount)) {
do_trans = true;
}
else { // give money to receiver failed. 返金処理
m_log.ErrorFormat("[MONEY DB]: Give money to receiver {0} failed", transaction.Receiver);
//Return money to sender
if (GiveMoney(transactionUUID, transaction.Sender, transaction.Amount)) {
m_log.ErrorFormat("[MONEY DB]: give money to receiver {0} failed but return it to sender {1} successfully",
transaction.Receiver, transaction.Sender);
UpdateTransactionStatus(transactionUUID, (int)Status.FAILED_STATUS, "give money to receiver failed but return it to sender successfully");
}
else {
m_log.ErrorFormat("[MONEY DB]: FATAL ERROR: Money withdrawn from sender: {0}, but failed to be given to receiver {1}",
transaction.Sender, transaction.Receiver);
UpdateTransactionStatus(transactionUUID, (int)Status.ERROR_STATUS, "give money to receiver failed, and return it to sender unsuccessfully!!!");
}
}
}
else { // withdraw money failed
m_log.ErrorFormat("[MONEY DB]: Withdraw money from sender {0} failed", transaction.Sender);
}
}
else { // not enough balance to finish the transaction
m_log.ErrorFormat("[MONEY DB]: Not enough balance for user: {0} to apply the transaction.", transaction.Sender);
}
}
else { // Can not fetch the transaction or it has expired
m_log.ErrorFormat("[MONEY DB]: The transaction:{0} has expired", transactionUUID.ToString());
}
//
if (do_trans) {
setTotalSale(transaction);
}
return do_trans;
}
// by Fumi.Iseki
public bool DoAddMoney(UUID transactionUUID)
{
TransactionData transaction = new TransactionData();
transaction = FetchTransaction(transactionUUID);
if (transaction!=null && transaction.Status==(int)Status.PENDING_STATUS) {
//If receiver not found, add it to DB.
if (GetBalance(transaction.Receiver)==-1) {
m_log.ErrorFormat("[MONEY DB]: DoAddMoney: Receiver not found in balances DB. {0}", transaction.Receiver);
return false;
}
//
if (GiveMoney(transactionUUID, transaction.Receiver, transaction.Amount)) {
setTotalSale(transaction);
return true;
}
else { // give money to receiver failed.
m_log.ErrorFormat("[MONEY DB]: Add money to receiver {0} failed", transaction.Receiver);
UpdateTransactionStatus(transactionUUID, (int)Status.FAILED_STATUS, "add money to receiver failed");
}
}
else { // Can not fetch the transaction or it has expired
m_log.ErrorFormat("[MONEY DB]: The transaction:{0} has expired", transactionUUID.ToString());
}
return false;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// userinfo
//
public bool TryAddUserInfo(UserInfo user, UserPresence userPresence)
{
MySQLSuperManager dbm = GetLockedConnection();
UserInfo userInfo = null;
UserPresence presence = null;
try {
userInfo = dbm.Manager.FetchUserInfo(user.UserID);
presence = dbm.Manager.fetchUserPresence(userPresence.UserID.ToString());
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
userInfo = dbm.Manager.FetchUserInfo(user.UserID);
presence = dbm.Manager.fetchUserPresence(userPresence.UserID.ToString());
}
catch (Exception e) {
m_log.Error(e.ToString());
dbm.Release();
return false;
}
try {
if (userInfo!=null && presence != null) {
//m_log.InfoFormat("[MONEY DB]: Found user \"{0}\", now update information", user.Avatar);
if (dbm.Manager.UpdateUserInfo(user) && dbm.Manager.UpdateUserPresence(userPresence)) return true;
}
else if (userInfo != null && presence == null) {
//m_log.InfoFormat("[MONEY DB]: Unable to find user \"{0}\", add it to DB successfully", user.Avatar);
return dbm.Manager.AddUserPresence(userPresence);
}
else if (userInfo == null && presence == null){
if(dbm.Manager.AddUserInfo(user) && dbm.Manager.AddUserPresence(userPresence)){
return true;
}
}
m_log.InfoFormat("[MONEY DB]: WARNNING: TryAddUserInfo: Unable to TryAddUserInfo.");
return false;
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public UserInfo FetchUserInfo(string userID)
{
UserInfo userInfo = null;
MySQLSuperManager dbm = GetLockedConnection();
try {
userInfo = dbm.Manager.FetchUserInfo(userID);
return userInfo;
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
userInfo = dbm.Manager.FetchUserInfo(userID);
return userInfo;
}
catch (Exception e) {
m_log.Error(e.ToString());
return null;
}
finally {
dbm.Release();
}
}
public UserPresence FetchUserPresence(string userID)
{
UserPresence userPresence = null;
MySQLSuperManager dbm = GetLockedConnection();
try {
userPresence = dbm.Manager.fetchUserPresence(userID);
return userPresence;
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
userPresence = dbm.Manager.fetchUserPresence(userID);
return userPresence;
}
catch (Exception e) {
m_log.Error(e.ToString());
return null;
}
finally {
dbm.Release();
}
}
public bool RemoveUserPresence(string userID)
{
bool bRet = false;
MySQLSuperManager dbm = GetLockedConnection();
try {
bRet = dbm.Manager.RemoveUserPresence(userID);
return bRet;
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
bRet = dbm.Manager.RemoveUserPresence(userID);
return bRet;
}
catch (Exception e) {
m_log.Error(e.ToString());
return false;
}
finally {
dbm.Release();
}
}
public int GetTransactionNum(string userID, int startTime, int endTime)
{
MySQLSuperManager dbm = GetLockedConnection();
try {
return dbm.Manager.GetTransactionNum(userID,startTime,endTime);
}
catch (MySql.Data.MySqlClient.MySqlException)
{
dbm.Manager.Reconnect();
return dbm.Manager.GetTransactionNum(userID,startTime,endTime);
}
catch (Exception e) {
m_log.Error(e.ToString());
return -1;
}
finally {
dbm.Release();
}
}
}
}
@@ -0,0 +1,319 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/, http://www.nsl.tuis.ac.jp/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Collections.Generic;
using System.Net.Security;
using System.Reflection;
using System.Timers;
using Nini.Config;
using log4net;
using OpenSim.Framework;
using OpenSim.Framework.Console;
using OpenSim.Framework.Servers;
using OpenSim.Framework.Servers.HttpServer;
using NSL.Certificate.Tools;
namespace OpenSim.Grid.MoneyServer
{
class MoneyServerBase : BaseOpenSimServer, IMoneyServiceCore
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string connectionString = string.Empty;
private uint m_moneyServerPort = 8008; // 8008 is default server port
private string m_certFilename = "";
private string m_certPassword = "";
private string m_cacertFilename = "";
private string m_clcrlFilename = "";
private bool m_checkClientCert = false;
private int DEAD_TIME = 120;
private int MAX_DB_CONNECTION = 10;
private MoneyXmlRpcModule m_moneyXmlRpcModule;
private MoneyDBService m_moneyDBService;
private NSLCertificateVerify m_certVerify = new NSLCertificateVerify(); // クライアント認証用
private Dictionary<string, string> m_sessionDic = new Dictionary<string, string>();
private Dictionary<string, string> m_secureSessionDic = new Dictionary<string, string>();
private Dictionary<string, string> m_webSessionDic = new Dictionary<string, string>();
IConfig m_server_config;
IConfig m_cert_config;
public MoneyServerBase()
{
m_console = new LocalConsole("Money ");
MainConsole.Instance = m_console;
}
public void Work()
{
//m_console.Notice("Enter help for a list of commands\n");
//The timer checks the transactions table every 60 seconds
Timer checkTimer = new Timer();
checkTimer.Interval = 60*1000;
checkTimer.Enabled = true;
checkTimer.Elapsed += new ElapsedEventHandler(CheckTransaction);
checkTimer.Start();
while (true) {
m_console.Prompt();
}
}
/// <summary>
/// Check the transactions table, set expired transaction state to failed
/// </summary>
private void CheckTransaction(object sender, ElapsedEventArgs e)
{
long ticksToEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
int unixEpochTime =(int) ((DateTime.UtcNow.Ticks - ticksToEpoch )/10000000);
int deadTime = unixEpochTime - DEAD_TIME;
m_moneyDBService.SetTransExpired(deadTime);
}
protected override void StartupSpecific()
{
m_log.Info("[MONEY SERVER]: Setup HTTP Server process");
ReadIniConfig();
try {
if (m_certFilename!="") {
m_httpServer = new BaseHttpServer(m_moneyServerPort, true, m_certFilename, m_certPassword);
if (m_checkClientCert) {
Type typeBaseHttpServer = typeof(BaseHttpServer); // BaseHttpServer.cs にパッチがあたっていない場合のため
PropertyInfo pinfo = typeBaseHttpServer.GetProperty("CertificateValidationCallback");
if (pinfo!=null) {
//m_httpServer.CertificateValidationCallback = (RemoteCertificateValidationCallback)m_certVerify.ValidateClientCertificate;
pinfo.SetValue(m_httpServer, (RemoteCertificateValidationCallback)m_certVerify.ValidateClientCertificate, null);
m_log.Info ("[MONEY SERVER]: Set RemoteCertificateValidationCallback");
}
else {
m_log.Error("[MONEY SERVER]: StartupSpecific: CheckClientCert is true. But this MoneyServer does not support CheckClientCert!!");
}
}
}
else {
m_httpServer = new BaseHttpServer(m_moneyServerPort);
}
SetupMoneyServices();
m_httpServer.Start();
base.StartupSpecific(); // OpenSim/Framework/Servers/BaseOpenSimServer.cs
}
catch (Exception e) {
m_log.ErrorFormat("[MONEY SERVER]: StartupSpecific: Fail to start HTTPS process");
m_log.ErrorFormat("[MONEY SERVER]: StartupSpecific: Please Check Certificate File or Password. Exit");
m_log.ErrorFormat("[MONEY SERVER]: StartupSpecific: {0}", e);
Environment.Exit(1);
}
//TODO : Add some console commands here
}
protected void ReadIniConfig()
{
MoneyServerConfigSource moneyConfig = new MoneyServerConfigSource();
Config = moneyConfig.m_config; // for base.StartupSpecific()
try {
// [Startup]
IConfig st_config = moneyConfig.m_config.Configs["Startup"];
string PIDFile = st_config.GetString("PIDFile", "");
if (PIDFile!="") Create_PIDFile(PIDFile);
// [MySql]
IConfig db_config = moneyConfig.m_config.Configs["MySql"];
string sqlserver = db_config.GetString("hostname", "localhost");
string database = db_config.GetString("database", "OpenSim");
string username = db_config.GetString("username", "root");
string password = db_config.GetString("password", "password");
string pooling = db_config.GetString("pooling", "false");
string port = db_config.GetString("port", "3306");
MAX_DB_CONNECTION = db_config.GetInt ("MaxConnection", MAX_DB_CONNECTION);
connectionString = "Server=" + sqlserver + ";Port=" + port + ";Database=" + database + ";User ID=" +
username + ";Password=" + password + ";Pooling=" + pooling + ";";
// [MoneyServer]
m_server_config = moneyConfig.m_config.Configs["MoneyServer"];
DEAD_TIME = m_server_config.GetInt("ExpiredTime", DEAD_TIME);
m_moneyServerPort = (uint)m_server_config.GetInt("ServerPort", (int)m_moneyServerPort);
//
// [Certificate]
m_cert_config = moneyConfig.m_config.Configs["Certificate"];
if (m_cert_config==null) {
m_log.Info("[MONEY SERVER]: [Certificate] section is not found. Using [MoneyServer] section instead");
m_cert_config = m_server_config;
}
// HTTPS Server Cert (Server Mode)
// サーバ証明書
m_certFilename = m_cert_config.GetString("ServerCertFilename", m_certFilename);
m_certPassword = m_cert_config.GetString("ServerCertPassword", m_certPassword);
if (m_certFilename!="") {
m_log.Info("[MONEY SERVER]: ReadIniConfig: Execute HTTPS comunication. Cert file is " + m_certFilename);
}
// クライアント認証
m_checkClientCert = m_cert_config.GetBoolean("CheckClientCert", m_checkClientCert);
m_cacertFilename = m_cert_config.GetString("CACertFilename", m_cacertFilename);
m_clcrlFilename = m_cert_config.GetString("ClientCrlFilename", m_clcrlFilename);
//
if (m_checkClientCert && m_cacertFilename!="") {
m_certVerify.SetPrivateCA(m_cacertFilename);
m_log.Info("[MONEY SERVER]: ReadIniConfig: Execute Authentication of Clients. CA file is " + m_cacertFilename);
}
else {
m_checkClientCert = false;
}
if (m_checkClientCert) {
if (m_clcrlFilename!="") {
m_certVerify.SetPrivateCRL(m_clcrlFilename);
m_log.Info("[MONEY SERVER]: ReadIniConfig: Execute Authentication of Clients. CRL file is " + m_clcrlFilename);
}
}
}
catch (Exception) {
m_log.Error("[MONEY SERVER]: ReadIniConfig: Fail to setup configure. Please check MoneyServer.ini. Exit");
Environment.Exit(1);
}
}
// added by skidz
protected void Create_PIDFile(string path)
{
try {
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
FileStream fs = File.Create(path);
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
Byte[] buf = enc.GetBytes(pidstring);
fs.Write(buf, 0, buf.Length);
fs.Close();
m_pidFile = path;
}
catch (Exception) {
}
}
protected virtual void SetupMoneyServices()
{
m_log.Info("[MONEY SERVER]: Connecting to Money Storage Server");
m_moneyDBService = new MoneyDBService();
m_moneyDBService.Initialise(connectionString, MAX_DB_CONNECTION);
m_moneyXmlRpcModule = new MoneyXmlRpcModule();
// m_moneyXmlRpcModule.Initialise(m_version, m_server_config, m_cert_config, m_moneyDBService, this);
m_moneyXmlRpcModule.Initialise(m_version, m_moneyDBService, this);
m_moneyXmlRpcModule.PostInitialise();
}
//
public bool IsCheckClientCert()
{
return m_checkClientCert;
}
public IConfig GetServerConfig()
{
return m_server_config;
}
public IConfig GetCertConfig()
{
return m_cert_config;
}
public BaseHttpServer GetHttpServer()
{
return m_httpServer;
}
public Dictionary<string, string> GetSessionDic()
{
return m_sessionDic;
}
public Dictionary<string, string> GetSecureSessionDic()
{
return m_secureSessionDic;
}
public Dictionary<string, string> GetWebSessionDic()
{
return m_webSessionDic;
}
}
//
class MoneyServerConfigSource
{
public IniConfigSource m_config;
public MoneyServerConfigSource()
{
string configPath = Path.Combine(Directory.GetCurrentDirectory(), "MoneyServer.ini");
if (File.Exists(configPath)) {
m_config = new IniConfigSource(configPath);
}
else {
//TODO: create default configuration.
//m_config = DefaultConfig();
}
}
public void Save(string path)
{
m_config.Save(path);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,43 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using log4net.Config;
namespace OpenSim.Grid.MoneyServer
{
class Program
{
public static void Main(string[] args)
{
XmlConfigurator.Configure(new System.IO.FileInfo("MoneyServer.exe.config"));
MoneyServerBase app = new MoneyServerBase();
app.Startup();
app.Work();
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,202 @@
/*
* Copyright (c) Contributors, http://www.nsl.tuis.ac.jp
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*/
using System;
using System.Net;
using System.Net.Security;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using log4net;
namespace NSL.Certificate.Tools
{
public class NSLCertificateVerify
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private X509Chain m_chain = null;
private X509Certificate2 m_cacert = null;
private Mono.Security.X509.X509Crl m_clientcrl = null;
public NSLCertificateVerify()
{
m_chain = null;
m_cacert = null;
m_clientcrl = null;
}
public NSLCertificateVerify(string certfile)
{
SetPrivateCA(certfile);
}
public NSLCertificateVerify(string certfile, string crlfile)
{
SetPrivateCA (certfile);
SetPrivateCRL(crlfile);
}
public void SetPrivateCA(string certfile)
{
try {
m_cacert = new X509Certificate2(certfile);
}
catch (Exception ex)
{
m_cacert = null;
m_log.ErrorFormat("[SET PRIVATE CA]: CA File reading error [{0}]. {1}", certfile, ex);
}
if (m_cacert!=null) {
m_chain = new X509Chain();
m_chain.ChainPolicy.ExtraStore.Add(m_cacert);
m_chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
m_chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
}
}
public void SetPrivateCRL(string crlfile)
{
try {
m_clientcrl = Mono.Security.X509.X509Crl.CreateFromFile(crlfile);
}
catch (Exception ex)
{
m_clientcrl = null;
m_log.ErrorFormat("[SET PRIVATE CRL]: CRL File reading error [{0}]. {1}", crlfile, ex);
}
}
public bool CheckPrivateChain(X509Certificate2 cert)
{
if (m_chain==null || m_cacert==null) {
return false;
}
bool ret = m_chain.Build((X509Certificate2)cert);
if (ret) {
return true;
}
for (int i=0; i<m_chain.ChainStatus.Length; i++) {
if (m_chain.ChainStatus[i].Status==X509ChainStatusFlags.UntrustedRoot) return true;
}
return false;
}
/*
SslPolicyErrors:
RemoteCertificateNotAvailable = 1, // 証明書が利用できません.
RemoteCertificateNameMismatch = 2, // 証明書名が不一致です.
RemoteCertificateChainErrors = 4, // ChainStatus が空でない配列を返しました.
*/
//
//
//
public bool ValidateServerCertificate(object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
//m_log.InfoFormat("[NSL SERVER CERT VERIFY]: ValidateServerCertificate: Policy is ({0})", sslPolicyErrors);
if (obj is HttpWebRequest) {
//
HttpWebRequest Request = (HttpWebRequest)obj;
string noVerify = Request.Headers.Get("NoVerifyCert");
if (noVerify!=null && noVerify.ToLower()=="true") {
return true;
}
}
X509Certificate2 certificate2 = new X509Certificate2(certificate);
string simplename = certificate2.GetNameInfo(X509NameType.SimpleName, false);
//m_log.InfoFormat("[NSL SERVER CERT VERIFY]: ValidateServerCertificate: Simple Name is \"{0}\"", simplename);
/*
// RemoteCertificateNotAvailableはエラーとする.
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable)==SslPolicyErrors.RemoteCertificateNotAvailable) {
m_log.InfoFormat("[NSL SERVER CERT VERIFY]: ValidateServerCertificate: Policy Error! {0}", sslPolicyErrors);
return false;
}
*/
// None, ChainErrors 以外は全てエラーとする.
if (sslPolicyErrors!=SslPolicyErrors.None && sslPolicyErrors!=SslPolicyErrors.RemoteCertificateChainErrors) {
m_log.InfoFormat("[NSL SERVER CERT VERIFY]: ValidateServerCertificate: Policy Error! {0}", sslPolicyErrors);
return false;
}
bool valid = CheckPrivateChain(certificate2);
if (valid) {
m_log.InfoFormat("[NSL SERVER CERT VERIFY]: Valid Server Certification for \"{0}\"", simplename);
}
else {
m_log.InfoFormat("[NSL SERVER CERT VERIFY]: Failed to Verify Server Certification for \"{0}\"", simplename);
}
return valid;
}
// obj is SslStream
public bool ValidateClientCertificate(object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
//m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: ValidateClientCertificate: Policy is ({0})", sslPolicyErrors);
X509Certificate2 certificate2 = new X509Certificate2(certificate);
string simplename = certificate2.GetNameInfo(X509NameType.SimpleName, false);
//m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: ValidateClientCertificate: Simple Name is \"{0}\"", simplename);
/*
// RemoteCertificateNotAvailableはエラーとする.
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable)==SslPolicyErrors.RemoteCertificateNotAvailable) {
m_log.InfoFormat("[NSL CVLIENT CERT VERIFY]: ValidateClientCertificate: Policy Error! {0}", sslPolicyErrors);
return false;
}
*/
// None, ChainErrors 以外は全てエラーとする.
if (sslPolicyErrors!=SslPolicyErrors.None && sslPolicyErrors!=SslPolicyErrors.RemoteCertificateChainErrors) {
m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: ValidateClientCertificate: Policy Error! {0}", sslPolicyErrors);
return false;
}
// check CRL
if (m_clientcrl!=null) {
Mono.Security.X509.X509Certificate monocert = new Mono.Security.X509.X509Certificate(certificate.GetRawCertData());
Mono.Security.X509.X509Crl.X509CrlEntry entry = m_clientcrl.GetCrlEntry(monocert);
if (entry!=null) {
m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Common Name \"{0}\" was revoked at {1}", simplename, entry.RevocationDate.ToString());
return false;
}
}
bool valid = CheckPrivateChain(certificate2);
if (valid) {
m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Valid Client Certification for \"{0}\"", simplename);
}
else {
m_log.InfoFormat("[NSL CLIENT CERT VERIFY]: Failed to Verify Client Certification for \"{0}\"", simplename);
}
return valid;
}
}
public class NSLCertificatePolicy
{
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem)
{
if (certificateProblem == 0 || //正常
certificateProblem == -2146762487 || //信頼されてない?
certificateProblem == -2146762495 || //期限切れ
certificateProblem == -2146762481) { //名前不正?
return true;
}
else {
return false;
}
}
}
}
@@ -0,0 +1,68 @@
/*
* Copyright (c) Contributors, http://www.nsl.tuis.ac.jp
* Modified by Adil El Farissi for BTCPay Server Integration 11-2023.
*/
using System;
using System.Collections;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using log4net;
using Nwc.XmlRpc;
using System.Net.Http;
namespace NSL.Network.XmlRpc
{
public class NSLXmlRpcRequest : XmlRpcRequest
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public NSLXmlRpcRequest(){}
public Hashtable SendXMLRPCRequest(Hashtable reqParams, string method, string url, X509Certificate2 myClientCert, bool checkServerCert, int timeout)
{
m_log.Debug($"[MONEY XML-RPC]: Sending request '{method}' to {url}");
HttpClient client = null;
HttpClientHandler ch = new();
if( myClientCert != null) ch.ClientCertificates.Add(myClientCert);
if(!checkServerCert) ch.ServerCertificateCustomValidationCallback += (sender, myClientCert, chain, sslPolicyErrors) => true;
client = new HttpClient(ch, false)
{
Timeout = TimeSpan.FromMilliseconds(timeout)
};
client.DefaultRequestHeaders.Add("UserAgent", "NSLXmlRpcRequest");
if (!checkServerCert) client.DefaultRequestHeaders.Add("NoVerifyCert", "true");
try
{
ArrayList sendParams = new(){ reqParams };
XmlRpcRequest Req = new(method, sendParams);
XmlRpcResponse Resp = Req.Send(url, client);
if (Resp.IsFault)
{
m_log.Debug($"[MONEY XML-RPC]: XML-RPC request '{method}' to {url} FAILED: FaultCode={Resp.FaultCode}, {Resp.FaultString}");
client?.Dispose();
return null;
}
Hashtable RespData = (Hashtable)Resp.Value;
return RespData;
}
catch (Exception e)
{
m_log.Debug($"[MONEY XML-RPC]: XML-RPC Exception '{e.Message}'");
client?.Dispose();
return null;
}
finally
{
client?.Dispose();
}
}
}
}
+46
View File
@@ -0,0 +1,46 @@
###Change Log:
+ Upgraded to dotnet 8 (Cross-platforms, Compatible OpenSim >= 0.9.3).
+ Add support for OpenSim's standalones instances.
+ Add BTCPay related MySQL tables and their respective handlers.
+ Add TLS/SSL support to the region module server.
+ Replaced HttpWebRequest by HttpClient.
+ Add BTCPay related XMLRPC handlers and respective methods in the region module.
+ Add some security checks and verifications.
+ Many fixes and optimizations...
###Requirements:
+ Opensimulator source code >= v0.9.3.
+ [dotnet 8.0 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)
###Compiling
1. Compile OpenSim.
2. Place the "btcpay-opensim-currency" in the OpenSimulator source root folder.
+ In Windows, run or double click:
# opensim-0.9.3-source\btcpay-opensim-currency\runprebuild.bat
This will create the solution and produce a compile.bat files... run or double click:
# opensim-0.9.3-source\btcpay-opensim-currency\compile.bat
A successful compilation will add a "bin" folder inside "btcpay-opensim-currency" with the target sub-folder "net8.0" where you will find the Money Server executable and the module DLLs...
# opensim-0.9.3-source\btcpay-opensim-currency\bin\net8.0\
+ In Linux&Co, is the same as Windows but the file extension is .sh
# cd opensim-0.9.3-source
# cd btcpay-opensim-currency
# ./runprebuild.sh
# ./compile.sh
###Attention.
This is unofficial software. Please do not inquire to OpenSim development team or DTL Currency Processing development team or NSL team about this software.
###Exemption from responsibility.
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Use at your own risks!
###Thanks where due.
+ This is a modified version of DTL/NSL Secure Money Server by [Fumi.Iseki and NSL](http://www.nsl.tuis.ac.jp)
+ Special thanks to [Fumi.Iseki and NSL Team](http://www.nsl.tuis.ac.jp).
+ Special thanks to BTCPay Server Team.
+ Special thanks to [OpenSimulator Team](http://opensimulator.org/).
Thank you very much!!!
+143
View File
@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8" ?>
<Prebuild xmlns="http://dnpb.sourceforge.net/schemas/prebuild-1.10.xsd" version="1.10">
<Solution name="OpenSim.Currency" activeConfig="Release" path="./" version="0.5.0-$Rev$">
<Configuration name="Debug">
<Options>
<CompilerDefines>TRACE;DEBUG</CompilerDefines>
<OptimizeCode>false</OptimizeCode>
<CheckUnderflowOverflow>false</CheckUnderflowOverflow>
<AllowUnsafe>false</AllowUnsafe>
<WarningLevel>4</WarningLevel>
<WarningsAsErrors>false</WarningsAsErrors>
<SuppressWarnings>SYSLIB0014</SuppressWarnings>
<OutputPath>bin</OutputPath>
<DebugInformation>true</DebugInformation>
<IncrementalBuild>true</IncrementalBuild>
<NoStdLib>false</NoStdLib>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<CompilerDefines>TRACE</CompilerDefines>
<OptimizeCode>true</OptimizeCode>
<CheckUnderflowOverflow>false</CheckUnderflowOverflow>
<AllowUnsafe>false</AllowUnsafe>
<WarningLevel>4</WarningLevel>
<WarningsAsErrors>false</WarningsAsErrors>
<SuppressWarnings>SYSLIB0014</SuppressWarnings>
<OutputPath>bin</OutputPath>
<DebugInformation>false</DebugInformation>
<IncrementalBuild>true</IncrementalBuild>
<NoStdLib>false</NoStdLib>
</Options>
</Configuration>
<Project frameworkVersion="v8_0" name="OpenSim.Data.MySQL.MySQLMoneyDataWrapper" path="OpenSim.Data.MySQL.MySQLMoneyDataWrapper" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../bin/</ReferencePath>
<Reference name="Nini.dll" path="../../bin/"/>
<Reference name="log4net.dll" path="../../bin/"/>
<Reference name="XMLRPC.dll" path="../../bin/"/>
<Reference name="MySql.Data" path="../../bin/"/>
<Reference name="Mono.Addins.dll" path="../../bin/"/>
<Reference name="OpenMetaverseTypes.dll" path="../../bin/"/>
<Reference name="OpenMetaverse.dll" path="../../bin/"/>
<Reference name="OpenSim.Region.Framework" path="../../bin/"/>
<Reference name="OpenSim.Framework" path="../../bin/"/>
<Reference name="OpenSim.Framework.Console" path="../../bin/"/>
<Reference name="OpenSim.Framework.Servers" path="../../bin/"/>
<Reference name="OpenSim.Framework.Servers.HttpServer" path="../../bin/"/>
<Reference name="OpenSim.Services.Interfaces" path="../../bin/"/>
<Reference name="OpenSim.Server.Base" path="../../bin/"/>
<Reference name="OpenSim.Data" path="../../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project frameworkVersion="v8_0" name="OpenSim.Modules.Currency" path="OpenSim.Modules.Currency" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../bin/</ReferencePath>
<Reference name="Mono.Security.dll" path="../../bin/"/>
<Reference name="Nini.dll" path="../../bin/"/>
<Reference name="log4net.dll" path="../../bin/"/>
<Reference name="XMLRPC.dll" path="../../bin/"/>
<Reference name="Mono.Addins.dll" path="../../bin/"/>
<Reference name="Mono.Security.dll" path="../../bin/"/>
<Reference name="OpenMetaverseTypes.dll" path="../../bin/"/>
<Reference name="OpenMetaverse.dll" path="../../bin/"/>
<Reference name="OpenSim.Region.Framework" path="../../bin/"/>
<Reference name="OpenSim.Framework" path="../../bin/"/>
<Reference name="OpenSim.Framework.Console" path="../../bin/"/>
<Reference name="OpenSim.Framework.Servers" path="../../bin/"/>
<Reference name="OpenSim.Framework.Servers.HttpServer" path="../../bin/"/>
<Reference name="OpenSim.Services.Interfaces" path="../../bin/"/>
<Reference name="OpenSim.Server.Base" path="../../bin/"/>
<Reference name="OpenSim.Data" path="../../bin/"/>
<Reference name="OpenSim.Data.MySQL.MySQLMoneyDataWrapper" path="../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
<Project frameworkVersion="v8_0" name="MoneyServer" path="OpenSim.Grid.MoneyServer" type="Exe">
<Configuration name="Debug">
<Options>
<OutputPath>../bin/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../bin/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../bin/</ReferencePath>
<Reference name="Mono.Security.dll" path="../../bin/"/>
<Reference name="Nini.dll" path="../../bin/"/>
<Reference name="log4net.dll" path="../../bin/"/>
<Reference name="XMLRPC.dll" path="../../bin/"/>
<Reference name="MySql.Data" path="../../bin/"/>
<Reference name="Mono.Addins.dll" path="../../bin/"/>
<Reference name="OpenMetaverseTypes.dll" path="../../bin/"/>
<Reference name="OpenMetaverse.dll" path="../../bin/"/>
<Reference name="OpenSim.Region.Framework" path="../../bin/"/>
<Reference name="OpenSim.Framework" path="../../bin/"/>
<Reference name="OpenSim.Framework.Console" path="../../bin/"/>
<Reference name="OpenSim.Framework.Servers" path="../../bin/"/>
<Reference name="OpenSim.Framework.Servers.HttpServer" path="../../bin/"/>
<Reference name="OpenSim.Services.Interfaces" path="../../bin/"/>
<Reference name="OpenSim.Server.Base" path="../../bin/"/>
<Reference name="OpenSim.Data" path="../../bin/"/>
<Reference name="OpenSim.Data.MySQL.MySQLMoneyDataWrapper" path="../bin/"/>
<Reference name="OpenSim.Modules.Currency" path="../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>
</Project>
</Solution>
</Prebuild>
+67
View File
@@ -0,0 +1,67 @@
@echo OFF
dotnet ..\bin\prebuild.dll /target vs2022 /targetframework net8_0
setlocal ENABLEEXTENSIONS
set VALUE_NAME=MSBuildToolsPath
if "%PROCESSOR_ARCHITECTURE%"=="x86" set PROGRAMS=%ProgramFiles%
if defined ProgramFiles(x86) set PROGRAMS=%ProgramFiles(x86)%
rem Try to find VS2019, VS2022
for %%e in (Enterprise Professional Community) do (
if exist "%PROGRAMS64%\Microsoft Visual Studio\2022\%%e\MSBuild\Current\Bin\MSBuild.exe" (
set ValueValue="%PROGRAMS64%\Microsoft Visual Studio\2022\%%e\MSBuild\Current\Bin\MSBuild"
goto :found
)
if exist "%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild.exe" (
set ValueValue="%PROGRAMS%\Microsoft Visual Studio\2019\%%e\MSBuild\Current\Bin\MSBuild"
goto :found
)
)
rem try find vs2017
for %%e in (Enterprise Professional Community) do (
if exist "%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild.exe" (
set ValueValue="%PROGRAMS%\Microsoft Visual Studio\2017\%%e\MSBuild\15.0\Bin\MSBuild"
goto :found
)
)
rem We have to use grep or find to locate the correct line, because reg query spits
rem out 4 lines before Windows 7 but 2 lines after Windows 7.
rem We use grep if it's on the path; otherwise we use the built-in find command
rem from Windows. (We must use grep on Cygwin because it overrides the "find" command.)
for %%X in (grep.exe) do (set FOUNDGREP=%%~$PATH:X)
if defined FOUNDGREP (
set FINDCMD=grep
) else (
set FINDCMD=find
)
rem try vs2015
FOR /F "usebackq tokens=1-3" %%A IN (`REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v %VALUE_NAME% 2^>nul ^| %FINDCMD% "%VALUE_NAME%"`) DO (
set ValueValue=%%C\msbuild
goto :found
)
@echo msbuild for at least VS2015 not found, please install a (Community) edition of VS2017 or VS2015
@echo Not creating compile.bat
if exist "compile.bat" (
del compile.bat
)
goto :done
:found
@echo Found msbuild at %ValueValue%
@echo Creating compile.bat
rem To compile in debug mode
@echo dotnet build --configuration Release OpenSim.Currency.sln > compile.bat
rem To compile in release mode comment line (add rem to start) above and uncomment next (remove rem)
rem @echo %ValueValue% /P:Config=Release OpenSim.Currency.sln > compile.bat
:done
pause
+5
View File
@@ -0,0 +1,5 @@
#!/bin/sh
dotnet ../bin/prebuild.dll /target vs2022 /targetframework net8_0 /excludedir = "obj | bin" /file prebuild.xml
echo "dotnet build -c Release OpenSim.Currency.sln" > compile.sh
chmod +x compile.sh
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<appSettings>
</appSettings>
<log4net>
<appender name="Console" type="OpenSim.Framework.Console.OpenSimAppender, OpenSim.Framework.Console">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{HH:mm:ss} - %message%newline" />
</layout>
</appender>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="MoneyServer.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level - %logger %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
+136
View File
@@ -0,0 +1,136 @@
[Startup]
;
; Place to create a PID file
; PIDFile = "/tmp/money.pid"
[MySql]
;
;Connection parameters of MySQL
hostname = localhost
database = opensim
username = db_user
password = db_password
pooling = false
port = 3306
;
; Max DB connections kept by money server.
MaxConnection = 10
[MoneyServer]
; Port No. of this Server
ServerPort = 8008
;
; If the user is not found in database,he/she will be created with the default balance.
DefaultBalance = 0
;
; Is amount==0 transaction enable? Default is false.
;EnableAmountZero = false
;
; If "00000000-0000-0000-0000-000000000000" is specified, all avatars can get money from system.
; If "" is specified, nobody can get money.
BankerAvatar = ""
;
; If you want to use llGiveMoney() function normally even when payer doesn't login to OpenSim,
; please set true to this valiable
EnableForceTransfer = true
;
; Send/Move money to/from avatar by Money Script
EnableScriptSendMoney = true
;; Specify same secret key in include/config.php or WI(XoopenSim/Modlos)
MoneyScriptAccessKey = "123456789"
;; Not use 127.0.0.1. This is used to generate Script key
MoneyScriptIPaddress = "192.168.1.109"
;
; for HG/Guest Avatar. Foreign Avatar is always false
;EnableHGAvatar = false
;EnableGuestAvatar = false
;HGAvatarDefaultBalance = 0
;GuestAvatarDefaultBalance = 0
;
; Message that displayed in blue dialog, when balance is updated.
; If "" is specified, blue dialog is not displayed.
; You can use {0} and {1} in message string.
; {0} means amount and {1} means avatar name or object owner name.
;; for send gift to other avatar
BalanceMessageSendGift = "Sent {0} B$ Gift to {1}."
;; for receieve gift from other avatar
BalanceMessageReceiveGift = "Received {0} B$ Gift from {1}."
;; for upload and group creation charge
;BalanceMessagePayCharge = ""
;; for buy the object
BalanceMessageBuyObject = "Bought the Object {2} from {1} for {0} B$."
;; for sell the object
BalanceMessageSellObject = "{1} bought the Object {2} for {0} B$."
;; for buy the land
BalanceMessageLandSale = "Paid {0} B$ for land purchase."
;; for get the money of the sold land
;BalanceMessageScvLandSale = ""
;; for get the money from object by llGiveMoney()
BalanceMessageGetMoney = "Got {0} B$ from {1}."
;; for buy the money from system
BalanceMessageBuyMoney = "Bought {0} B$ from {1}."
;; when roll back ocuurred
BalanceMessageRollBack = "RollBack the Transaction: {0} B$ from/to {1}."
;; for sender of sending the money
BalanceMessageSendMoney = "Paid {0} B$ to {1}."
;; for receive the money
BalanceMessageReceiveMoney = "Received {0} B$ from {1}."
[Certificate]
;
; Certification Configuration
;
; CA Cert to check Client/Server Cert (unused)
;CACertFilename = "cacert.crt"
;
; HTTPS Server Cert (Server Mode)
ServerCertFilename = "SineWaveCert.pfx"
ServerCertPassword = "123"
;ServerCertFilename = "server_cert.p12"
;ServerCertPassword = ""
; Client Authentication from Region Server
;; check Region Server
CheckClientCert = false
;ClientCrlFilename = "clcrl.crt"
;
; XML RPC to Region Server (Client Mode)
;; check Region Server
CheckServerCert = false
;ClientCertFilename = "client_cert.p12"
;;ClientCertPassword = ""
ClientCertFilename = "SineWaveCert.pfx"
ClientCertPassword = "123"
+40
View File
@@ -0,0 +1,40 @@
[Economy]
; Set the economy module name.
EconomyModule = DTLNSLMoneyModule
; Do you want to allow 0 currency transactions?
SellEnabled = true
; Set your PHP web server URL pointing to the "helper" folder with "/" at the end.
Economy = "https://your-domain-or-ip.here/helper_scripts/helper/
; Set the Money Server URL. Do not use 127.0.0.1 or localhost for CurrencyServer's address. This address is used for identification of user on Money Server.
CurrencyServer = "https://your-domain-or-ip.here:8008"
; Verify the server certificate? keep false... (buggy! may not work)
CheckServerCert = false
; Set the module certificate and password.
ClientCertFilename = "SineWaveCert.pfx"
ClientCertPassword = "123"
; Set the things prices...
PriceUpload = 10
PriceGroupCreate = 100
; Mesh upload factors
MeshModelUploadCostFactor = 2.5
MeshModelUploadTextureCostFactor = 1.0
MeshModelMinCostFactor = 2.0
; Set the minimum amount to buy currency from the system.
MinimumAmount = 250
; Set the same secret key as MoneyScriptAccessKey in include/config.php and MoneyServer.ini
MoneyAccessKey = "123456789"
; Avatar Class for HG Avatar
; {ForeignAvatar, HGAvatar, GuestAvatar, LocalAvatar} HGAvatar
; HG Avatar is assumed as a specified avatar class. Default is HGAvatar
; Processing for each avatar class is dependent on Money Server settings.
HGAvatarAs = "HGAvatar"
Binary file not shown.
Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^(include/*|helper/helpers.php) - [F]
</IfModule>
+241
View File
@@ -0,0 +1,241 @@
<?php
#
# Add by Adil El Farissi for the BTCPay integration.
#
# 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.
#
if (!defined('ENV_READ_CONFIG')) require_once(realpath(dirname(__FILE__).'/../include/config.php'));
require_once(realpath(ENV_HELPER_PATH.'/helpers.php'));
$isDisabled = getCurrencyStatus();
$cryptoSymbol = getSupportedCrypto();
$fiatSymbol = getSupportedFiat();
$localCurrencySymbol = getLocalCurrencySymbol();
$localCurrencyMinimum = getMinimumAmount();
$localCurrencyBuyPrice = getBuyPrice();
$pullPaymentLink = getPullPaymentLink();
?>
<!DOCTYPE HTML>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<style>
body{background-color:#161B22;font-family:arial;}
h2, h3{text-shadow: 2px 2px 2px #000;}
#page{min-height: auto;margin:10px auto; width:500px;background-color:#0D1117;padding:10px 20px;color:#fff;border: 1px solid #010;border-radius:2px;}
#content{height:auto;min-height:490px;}
#support{position:relative;display:block;background-color:#020;color:#fff;padding:10px;border: 1px solid #010;border-radius:10px;}
hr, a{text-decoration:none;color:#51B13E;}
.support-img{font-size:18px;}
.warning-box{text-align:center;margin-bottom:20px;margin-top:50px;}
.warning-img{font-size:150px;margin-top:10px;}
.warning{font-size:22px;color:#f00;text-shadow:2px 2px 1px #000;margin-bottom:10px;}
.success{font-size:22px;color:#0f0;text-shadow:2px 2px 1px #000;margin-bottom:10px;}
.sub-warning, .sub-success{font-size:14px;color:#ff0;text-shadow:1px 1px 1px #000;margin-bottom:30px;}
.inputs{margin:5px auto;display:block;}
.inputs input{margin:5px auto; display:inline-block;font-size:24px;width:210px;text-align:center;}
.inputs .button, .button{font-size: 16px;color:#fff;border:none;border-radius: 5px;text-shadow:0px 0px 2px #000;font-weight:bold;padding:10px;text-align:center;cursor:pointer;}
.label{text-align:left;color:#8B949E;}
tr{display:block;width:490px;}
hr{color: #51B13E;}
li{margin-bottom:10px;}
.btn-red {background-color: #f56954 !important;background: -moz-linear-gradient(bottom, #f00 0%, #370101 100%);background: -webkit-gradient(linear, bottom, top, color-stop(0%,#f00), color-stop(100%,#370101));background: -webkit-linear-gradient(bottom, #f00 0%,#370101 100%); background: -o-linear-gradient(bottom, #f00 0%,#370101 100%);background: -ms-linear-gradient(bottom, #f00 0%,#370101 100%);background: linear-gradient(to bottom, #f00 0%,#370101 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f00', endColorstr='#370101',GradientType=1 );}
.btn-green {background: #003300;background: -moz-linear-gradient(bottom, #003300 0%, #00AE00 100%);background: -webkit-gradient(linear, bottom, top, color-stop(0%,#003300), color-stop(100%,#00AE00));background: -webkit-linear-gradient(bottom, #003300 0%,#00AE00 100%);background: -o-linear-gradient(bottom, #003300 0%,#00AE00 100%);background: -ms-linear-gradient(bottom, #003300 0%,#00AE00 100%);background: linear-gradient(to top, #003300 0%,#00AE00 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#003300', endColorstr='#00AE00',GradientType=1 );}
.btn-red:hover, .btn-green:hover{background-color: #f39c12 !important;background: -moz-linear-gradient(bottom, #f39c12 0%, #875504 100%);background: -webkit-gradient(linear, bottom, top, color-stop(0%,#f39c12), color-stop(100%,#875504)); background: -webkit-linear-gradient(bottom, #f39c12 0%,#875504 100%);background: -o-linear-gradient(bottom, #f39c12 0%,#875504 100%);background: -ms-linear-gradient(bottom, #f39c12 0%,#875504 100%);background: linear-gradient(to bottom, #f39c12 0%,#875504 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f39c12', endColorstr='#875504',GradientType=1 );}
</style>
<title>BTCPay Currency Proccessor</title>
</head>
<body>
<div id="page">
<div id="content">
<h2 style="margin:5px 0;">Buy <?= $localCurrencySymbol ?> With <?= $cryptoSymbol ?></h2>
<hr>
<?php
if(getenv('REQUEST_METHOD') == 'GET') {
if ($isDisabled){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">'. $cryptoSymbol .' withdrawals are disabled<br> by the administration !</span><br>
<span class="sub-warning">Please try again in some minutes...<br>Thanks for your patience.</span>
</div>';
return;
}else
{
$account = isset($_GET["account"]) ? $_GET["account"] : "";
$amount = isset($_GET["amount"]) ? $_GET["amount"] : $localCurrencyMinimum;
$price = convert_to_real($amount, false);
if($price == null){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">BTCPay Server is not available!</span><br>
<span class="sub-warning">Please try again in some minutes...<br>Thanks for your patience.</span><br>
</div>';
return;
}else{
echo
'<span>Exchange Rates: 1 '. $localCurrencySymbol .' = '. $localCurrencyBuyPrice .' '.$fiatSymbol .'</span>
<div class="inputs">
<form method="post">
<table>
<tr>
<td >
<span class="label">Set the '. $localCurrencySymbol .' amount to buy:</span><br>
<input id="inputBalance" type="number" name="amount" placeholder="'. $localCurrencyMinimum .'" min="'. $localCurrencyMinimum.'" oninput="setTimeout(()=>{ if(this.value < '. $localCurrencyMinimum .') this.value = '. $localCurrencyMinimum .'; document.getElementById(\'inputFiat\').value = parseFloat(this.value *'. $localCurrencyBuyPrice.').toFixed(2)+\' '. $fiatSymbol.'\';}, 2000);" value='.$amount.'>
</td>
<td><span style="font-size:40px"> 💱 </span></td>
<td>
<span class="label">Average price:</span><br>
<input id="inputFiat" type="text" name="fiat" value="'.$price["fiatAmount"].' '. $fiatSymbol .'" readOnly>
</td>
</tr>
<tr>
<td>
<span class="label">Set the destination avatar\'s key:</span><br>
<input id="key" type="text" name="aviKey" placeholder="Your avatar UUID..." value="'. $account .'" style="width:490px;height:30px;" oninput="this.value = this.value.trim();">
</td>
</tr>
<tr>
<td>
<span><b>Step By Step Guide:</b></span>
<ul style="margin-top: 10px;">
<li>Set the amount to purchase, the destination avatar UUID key and click [ Buy Now ].</li>
<li>Process your '. $cryptoSymbol .' payment using the provided payment infos in the BTCPay invoice.</li>
<li>The destination avatar will recive the purchased '. $localCurrencySymbol .' amount after the usual peers confirmations.</li>
</ul>
</td>
</tr>
<tr>
<td style="float:right;">
<input class="button btn-green" type="submit" name="buy" value="Buy Now" style="margin-top:17px;">
</td>
</tr>
</table>
</form>
</div>';
}
}
}
if(getenv('REQUEST_METHOD') == 'POST') {
if(!array_key_exists('aviKey', $_POST) || !isUUID($_POST['aviKey'])){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Missing or wrong avatar UUID key!</span><br>
<span class="sub-warning">You can get your UUID from your avatar\'s "Profile".<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
else{
$account = $_POST['aviKey'];
$aviName = opensim_get_avatar_name($account)["fullname"];
if(array_key_exists('amount', $_POST)
&& $_POST['amount'] >= $localCurrencyMinimum){
$price = convert_to_real($_POST['amount'], false);
if($price == null){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">BTCPay Server is not available!</span><br>
<span class="sub-warning">Please try again in some minutes...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}else{
if ($account != null && $_POST['amount'] != null ){
$pendingInvoice = hasPendingInvoice($account);
if($pendingInvoice != null){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">You have a pending invoice!</span><br>
<span class="sub-warning">Please, open the invoice page to process your payment:<br><a href="'. BTCPAY_SERVER_URL .'/i/'. $pendingInvoice .'">'. BTCPAY_SERVER_URL .'/i/'. $pendingInvoice .'</a><br> or wait the expiration of the pending invoice to be able to buy '. LOCAL_CURRENCY_SYMBOL.'.<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}else{
$ret = requestInvoice($account, null, $_POST['amount'], true);
if(!array_key_exists('errorMessage', $ret)){
/*echo
'<div class="warning-box">
<span class="warning-img">✔️</span><br>
<span class="success">Withdrawal Successfully Requested!</span><br>
<span class="sub-warning">Please open your tracking page to get more infos...<br><b>URL: <a class="" href="'. $ret["checkoutLink"].'" >'. $ret["checkoutLink"].'</b></span><br>
<input class="button" value="Go To Page" style="margin-top:30px;width:100px;background-color:darkgreen;"></a>
</div>';*/
header("Location: ".$ret['checkoutLink']);
exit();
}else{
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Invoice request failed!</span><br>
<span class="sub-warning">'.$ret["errorMessage"].'<br> Please, wait the transaction approuval...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}
}else{
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Missing invoice parameters!</span><br>
<span class="sub-warning">Please go back and try again...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}
}else{
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Missing or wrong '.$localCurrencySymbol.' amount!</span><br>
<span class="sub-warning">The amount in '.$localCurrencySymbol.' must be over the minimum '. $localCurrencyMinimum.' '.$localCurrencySymbol.'.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}
}
?>
<div id="support"><span>Need help?</span>&nbsp;&nbsp;<a href="#" target="_blank"><span class="support-img">👨‍🔧</span> InWorld</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" target="_blank"><span class="support-img">🌐</span> Website</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" target="_blank"><span class="support-img">✉️</span> E-Mail</a></div>
</div>
</div>
</body>
+403
View File
@@ -0,0 +1,403 @@
<?php
#
# Copyright (c)Melanie Thielker and Teravus Ovares (http://opensimulator.org/)
#
# 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.
#
########################################################################
# This file enables buying currency in the client.
#
# For this to work, the all clients using currency need to add
#
# -helperURI <WebpathToThisDirectory>
#
# to the commandline parameters when starting the client!
#
# Example:
# client.exe -loginuri http://foo.com:8002/ -helperuri http://foo.com/
#
# Don't forget to change the currency conversion value in the wi_economy_money
# table!
#
# This requires PHP curl, XMLRPC, and MySQL extensions.
#
# If placed in the opensimwiredux web directory, it will share the db module
#
########################################################################
#
# Modified by Fumi.Iseki for XoopenSim/Modlos
# Modified by Adil El Farissi for the BTCPay integration.
#
if (!defined('ENV_READ_CONFIG')) require_once(realpath(dirname(__FILE__).'/../include/config.php'));
require_once(realpath(ENV_HELPER_PATH.'/helpers.php'));
#
# The XMLRPC server object
#
$xmlrpc_server = xmlrpc_server_create();
#
# Viewer retrieves currency buy quote
#
xmlrpc_server_register_method($xmlrpc_server, "getCurrencyQuote", "get_currency_quote");
function get_currency_quote($method_name, $params, $app_data)
{
$req = $params[0];
$agentid = $req['agentId'];
$secureid = $req['secureSessionId'];
$amount = $req['currencyBuy'];
$ipAddress = $_SERVER['REMOTE_ADDR'];
if (DISABLE_CURRENCY_PURCHASE) {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\nThe currency purchases are disabled by the administration for maintenance.\nPlease try again in some minutes... Thanks for your patience."));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
if ($amount < LOCAL_CURRENCY_MIN_AMOUNT) {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\nThe minimum amount to purchase is ". LOCAL_CURRENCY_MIN_AMOUNT ." ". LOCAL_CURRENCY_SYMBOL));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
$ret = opensim_check_secure_session($agentid, null, $secureid);
if ($ret) {
$confirmvalue = get_confirm_value($ipAddress);
$cost = convert_to_real($amount, false);
if($cost != null){
if(strpos($_SERVER["HTTP_USER_AGENT"],"Firestorm-Release") > -1){
$currency = array('estimatedLocalCost'=> $cost['fiatAmount'] ." ". BTCPAY_FIAT. " ~ ". $cost['cryptoAmount'] ." ". BTCPAY_PAYMENT_CRYPTOCURRENCY, 'currencyBuy'=> $amount);
}else{
$currency = array('estimatedCost'=> $cost['fiatAmount'], 'currencyBuy'=> $amount);
}
$response_xml = xmlrpc_encode(array('success' => True,
'currency' => $currency,
'confirm' => $confirmvalue));
}
else{
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\nFailed to get the rates from the data source... Please, wait a minute and try again.\n"));
}
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "Unable to Authenticate\n\nClick URL for more info.",
'errorURI' => "".SYSURL.""));
}
header("Content-type: text/xml");
echo $response_xml;
return "";
}
#
# Viewer buys currency
#
xmlrpc_server_register_method($xmlrpc_server, "buyCurrency", "buy_currency");
function buy_currency($method_name, $params, $app_data)
{
$req = $params[0];
$agentid = $req['agentId'];
$secureid = $req['secureSessionId'];
$amount = $req['currencyBuy'];
$confim = $req['confirm'];
$ipAddress = $_SERVER['REMOTE_ADDR'];
if (DISABLE_CURRENCY_PURCHASE) {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\n\nThe currency purchases are disabled by the administration for maintenance.\nPlease try again in some minutes... Thanks for your patience."));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
if ($confim!=get_confirm_value($ipAddress)) {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\n\nMissmatch Confirm Value!",
'errorURI' => "".SYSURL.""));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
$checkSecure = opensim_check_secure_session($agentid, null, $secureid);
if (!$checkSecure) {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\n\nMissmatch Secure Session ID!!",
'errorURI' => "".SYSURL.""));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
if ($amount < LOCAL_CURRENCY_MIN_AMOUNT) {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\n\nThe minimum amount to purchase is". LOCAL_CURRENCY_MIN_AMOUNT ." ". LOCAL_CURRENCY_SYMBOL));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
$invoiceData = null;
$pendingInvoice = hasPendingInvoice($agentid);
if($pendingInvoice != null){
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\n\nYou have an invoice in wait of your payment!. Please, open the invoice page to process your payment:\n". BTCPAY_SERVER_URL ."/i/". $pendingInvoice ."\n or wait the expiration of the pending invoice to be able to buy ". LOCAL_CURRENCY_SYMBOL,
'errorURI' => "". BTCPAY_SERVER_URL ."/i/". $pendingInvoice .""));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
else{
$invoiceData = requestInvoice($agentid, $secureid, $amount, false);
}
if ($invoiceData != null) {
if(array_key_exists('errorMessage', $invoiceData)){
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "BTCPay error: ". $invoiceData["errorMessage"]));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
if( array_key_exists('storeId', $invoiceData)
&& $invoiceData["storeId"] == BTCPAY_STORE_ID
&& $invoiceData["id"] != null
&& $invoiceData["metadata"]["posData"]["localAmount"] == $amount
&& $invoiceData["metadata"]["posData"]["avatartId"] == $agentid
&& $invoiceData["metadata"]["posData"]["txType"] == "5010"
){
$message = "Thank you for purchasing ". $amount ." ". LOCAL_CURRENCY_SYMBOL .".\nYour invoice ID is:\n". $invoiceData['id'] ."\nPlease, open the invoice page to process your payment...\n" ;
loadBTCPayURL($agentid, BTCPAY_SERVER_URL ."/i/". $invoiceData["id"], $message, "BTCPay Invoice", $secureid);
$response_xml = xmlrpc_encode(array('success' => True));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
else{
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\nUnable to process the transaction. The invoice request failed!"
));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\nUnable to process the transaction. The gateway denied your charge"
));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
header("Content-type: text/xml");
echo $response_xml;
return "";
}
#
# Region requests account balance
#
xmlrpc_server_register_method($xmlrpc_server, "simulatorUserBalanceRequest", "balance_request");
function balance_request($method_name, $params, $app_data)
{
$req = $params[0];
$agentid = $req['agentId'];
$secureid = $req['secureSessionId'];
$balance = get_balance($agentid, $secureid);
if ($balance>=0) {
$response_xml = xmlrpc_encode(array('success' => True,
'agentId' => $agentid,
'funds' => $balance));
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "Could not authenticate your avatar. Money operations may be unavailable",
'errorURI' => " "));
}
header("Content-type: text/xml");
echo $response_xml;
return "";
}
#
# Region initiates money transfer (Direct DB Operation for security)
#
xmlrpc_server_register_method($xmlrpc_server, "regionMoveMoney", "region_move_money");
function region_move_money($method_name, $params, $app_data)
{
$req = $params[0];
$agentid = $req['agentId'];
$destid = $req['destId'];
$secureid = $req['secureSessionId'];
$regionid = $req['regionId'];
$secret = $req['secret'];
$currencySecret = $req['currencySecret'];
$cash = $req['cash'];
$aggregatePermInventory = $req['aggregatePermInventory'];
$aggregatePermNextOwner = $req['aggregatePermNextOwner'];
$flags = $req['flags'];
$transactiontype = $req['transactionType'];
$description = $req['description'];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$ret = opensim_check_region_secret($regionid, $secret);
if ($ret) {
$ret = opensim_check_secure_session($agentid, $regionid, $secureid);
if ($ret) {
$balance = get_balance($agentid, $secureid);
if ($balance >= $cash) {
move_money($agentid, $destid, $cash, $transactiontype, $flags, $description,
$aggregatePermInventory, $aggregatePermNextOwner, $ipAddress);
$sbalance = get_balance($agentid, $secureid);
$dbalance = get_balance($destid);
$response_xml = xmlrpc_encode(array('success' => True,
'agentId' => $agentid,
'funds' => $balance,
'funds2' => $balance,
'currencySecret'=> " "));
update_simulator_balance($agentid, $sbalance, $secureid);
update_simulator_balance($destid, $dbalance);
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "You do not have sufficient funds for this purchase",
'errorURI' => " "));
}
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "Unable to authenticate avatar. Money operations may be unavailable",
'errorURI' => " "));
}
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "This region is not authorized to manage your money.",
'errorURI' => " "));
}
header("Content-type: text/xml");
echo $response_xml;
return "";
}
#
# Region claims user
#
xmlrpc_server_register_method($xmlrpc_server, "simulatorClaimUserRequest", "claimUser_func");
function claimUser_func($method_name, $params, $app_data)
{
$req = $params[0];
$agentid = $req['agentId'];
$secureid = $req['secureSessionId'];
$regionid = $req['regionId'];
$secret = $req['secret'];
$ret = opensim_check_region_secret($regionid, $secret);
if ($ret) {
$ret = opensim_check_secure_session($agentid, null, $secureid);
if ($ret) {
$ret = opensim_set_current_region($agentid, $regionid);
if ($ret) {
$balance = get_balance($agentid, $secureid);
$response_xml = xmlrpc_encode(array('success' => True,
'agentId' => $agentid,
'funds' => $balance,
'currencySecret'=> " "));
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "Error occurred, when DB was updated.",
'errorURI' => " "));
}
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "Unable to authenticate avatar. Money operations may be unavailable.",
'errorURI' => " "));
}
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "This region is not authorized to manage your money.",
'errorURI' => " "));
}
header("Content-type: text/xml");
echo $response_xml;
return "";
}
#
# Process the request
#
if (!isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = file_get_contents('php://input');
$request_xml = $HTTP_RAW_POST_DATA;
//error_log('currency.php: '.$request_xml);
xmlrpc_server_call_method($xmlrpc_server, $request_xml, '');
xmlrpc_server_destroy($xmlrpc_server);
+744
View File
@@ -0,0 +1,744 @@
<?php
#
# Copyright (c)Melanie Thielker and Teravus Ovares (http://opensimulator.org/)
#
# 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.
#
# Modified by Adil El Farissi for the BTCPay integration.
if (!defined('ENV_READ_CONFIG')) require_once(realpath(dirname(__FILE__).'/../include/config.php'));
require_once(realpath(ENV_HELPER_PATH.'/../include/opensim.mysql.php'));
if (!isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = file_get_contents('php://input');
#$request_xml = $HTTP_RAW_POST_DATA;
#error_log('helper.php: '.$request_xml);
###################### No user serviceable parts below #####################
#
# Helper routines
#
# This function convert in real time the local currency amount to fiat and crypto
# amounts using BTCPay as rates provider.
# You can setup the rates source in your BTCPay Store Settings > Rates.
function convert_to_real($amount, $isWithdrawal)
{
if($amount == 0) return 0;
$fiatAmount = $isWithdrawal
? bcmul(LOCAL_CURRENCY_WITHDRAWAL_PRICE, $amount, 2)
: bcmul(LOCAL_CURRENCY_PRICE, $amount, 2);
$url = BTCPAY_SERVER_URL .'/api/rates?storeId='. BTCPAY_STORE_ID .'&currencyPairs='. BTCPAY_PAYMENT_CRYPTOCURRENCY .'_'. BTCPAY_FIAT;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if (DISABLE_SSL_VERIFICATION){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
$rateJson = curl_exec($ch);
curl_close($ch);
$rateData = null;
$cost = null;
$rateData = json_decode($rateJson, true);
if($rateData && $rateData[0]['rate'] != null && !array_key_exists('error',$rateData)){
$rate = $rateData[0]['rate'];
$cryptoAmount = bcdiv($fiatAmount, $rate, 8);
$cost = array(
'fiatAmount' => $fiatAmount,
'cryptoAmount' => $cryptoAmount,
'rate' => $rate);
}
else{
$cost = null;
}
return $cost;
}
/*
下記関数は現在のところ,アバターがログインしていないと使用できない
function user_alert($agentID, $message, $secureID=null)
function update_simulator_balance($agentID, $amount=-1, $secureID=null)
function add_money($agentID, $amount, $secureID=null)
function get_balance($agentID, $secureID=null)
function move_money($srcID, $dstID, $amount, $type, $desc, $prminvent=0, $nxtowner=0, $ip='')
*/
//
// アバターがログインしていないと使用できない
//
function user_alert($agentID, $message, $secureID=null)
{
if (!USE_CURRENCY_SERVER) return false;
if (!isGUID($agentID)) return false;
if (!isGUID($secureID, true)) return false;
// XML RPC to Region Server
$results = opensim_get_userinfo($agentID);
$url = parse_url($results['simip']);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($results['simip'], $port);
if ($server['host']=='') return false;
$results = opensim_get_avatar_session($agentID); // use Presence Table
if (!$results) return false;
$sessionID = $results['sessionID'];
if ($secureID==null) $secureID = $results['secureID'];
$req = array('clientUUID'=>$agentID, 'clientSessionID'=>$sessionID, 'clientSecureSessionID'=>$secureID, 'Description'=>$message);
$params = array($req);
$request = xmlrpc_encode_request('UserAlert', $params);
$response = do_call($server['url'], $server['port'], $request);
if ($response!=null and array_key_exists('success', $response)) return $response['success'];
return false;
}
function loadBTCPayURL($agentID, $invoiceUrl, $message, $type, $secureID=null)
{
if (!USE_CURRENCY_SERVER) return false;
if (!isGUID($agentID)) return false;
if (!isGUID($secureID, true)) return false;
// XML RPC to Region Server
$results = opensim_get_userinfo($agentID);
$url = parse_url($results['simip']);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($results['simip'], $port);
if ($server['host']=='') return false;
$results = opensim_get_avatar_session($agentID); // use Presence Table
if (!$results) return false;
$sessionID = $results['sessionID'];
if ($secureID==null) $secureID = $results['secureID'];
$req = array('clientUUID'=>$agentID, 'clientSessionID'=>$sessionID, 'clientSecureSessionID'=>$secureID, 'Description'=>$message, 'Url'=>$invoiceUrl, 'Type'=> $type);
$params = array($req);
$request = xmlrpc_encode_request('LoadBTCPayURL', $params);
$response = do_call($server['url'], $server['port'], $request);
if ($response!=null and array_key_exists('success', $response)) return $response['success'];
return false;
}
function sendWithdrawalLinkRequest($agentID, $hash)
{
if (!USE_CURRENCY_SERVER) return false;
if (!isGUID($agentID)) return false;
// XML RPC to Region Server
$results = opensim_get_userinfo($agentID);
$url = parse_url($results['simip']);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($results['simip'], $port);
if ($server['host']=='') return false;
$results = opensim_get_avatar_session($agentID); // use Presence Table
if (!$results) return false;
$sessionID = $results['sessionID'];
$secureID = $results['secureID'];
$req = array('clientUUID'=>$agentID, 'clientSessionID'=>$sessionID, 'clientSecureSessionID'=>$secureID, 'Hash'=>$hash);
$params = array($req);
$request = xmlrpc_encode_request('LoadWithdrawalLink', $params);
$response = do_call($server['url'], $server['port'], $request);
if ($response!=null && array_key_exists('success', $response)) return $response['success'];
return false;
}
//
// アバターがログインしていないと使用できない
//
function update_simulator_balance($agentID, $amount=-1, $secureID=null)
{
if (!USE_CURRENCY_SERVER) return false;
if (!isGUID($agentID)) return false;
if (!isGUID($secureID, true)) return false;
if ($amount<0) {
$amount = get_balance($agentID, $secureID);
if ($amount<0) return false;
}
// XML RPC to Region Server
$results = opensim_get_userinfo($agentID);
$url = parse_url($results['simip']);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($results['simip'], $port);
if ($server['host']=='') return false;
$results = opensim_get_avatar_session($agentID);
if (!$results) return false;
$sessionID = $results['sessionID'];
if ($secureID == null) $secureID = $results['secureID'];
$req = array('clientUUID'=>$agentID, 'clientSessionID'=>$sessionID, 'clientSecureSessionID'=>$secureID, 'Balance'=>$amount);
$params = array($req);
$request = xmlrpc_encode_request('UpdateBalance', $params);
$response = do_call($server['url'], $server['port'], $request);
if ($response!=null and array_key_exists('success', $response)) return $response['success'];
return false;
}
//
// アバターがログインしていないと使用できない
//
function add_money($agentID, $amount, $secureID=null)
{
if (!USE_CURRENCY_SERVER) return false;
if (!isGUID($agentID)) return false;
if (!isGUID($secureID, true)) return false;
// XML RPC to Region Server
$results = opensim_get_userinfo($agentID);
$url = parse_url($results['simip']);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($results['simip'], $port);
if ($server['host']=='') return false;
$results = opensim_get_avatar_session($agentID);
$sessionID = $results['sessionID'];
if ($secureID==null) $secureID = $results['secureID'];
$req = array('clientUUID'=>$agentID, 'clientSessionID'=>$sessionID, 'clientSecureSessionID'=>$secureID, 'amount'=>$amount);
$params = array($req);
$request = xmlrpc_encode_request('AddBankerMoney', $params);
$response = do_call($server['url'], $server['port'], $request);
if ($response!=null and array_key_exists('success', $response)) return $response['success'];
return false;
}
//
// アバターがログインしていないと使用できない
//
function get_balance($agentID, $secureID=null)
{
$cash = -1;
if (!USE_CURRENCY_SERVER) return (integer)$cash;
if (!isGUID($agentID)) return (integer)$cash;
if (!isGUID($secureID, true)) return (integer)$cash;
// XML RPC to Region Server
$results = opensim_get_userinfo($agentID);
$url = parse_url($results['simip']);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($results['simip'], $port);
if ($server['host']=='') return (integer)$cash;
$results = opensim_get_avatar_session($agentID);
$sessionID = $results['sessionID'];
if ($sessionID=='') return (integer)$cash;
if ($secureID==null) $secureID = $results['secureID'];
$req = array('clientUUID'=>$agentID, 'clientSessionID'=>$sessionID, 'clientSecureSessionID'=>$secureID);
$params = array($req);
$request = xmlrpc_encode_request('GetBalance', $params);
$response = do_call($server['url'], $server['port'], $request);
if ($response!=null and array_key_exists('balance', $response)) $cash = $response['balance'];
return (integer)$cash;
}
//
// Send the money to avatar for bonus by Milo
//
// XMLRPC による正式な手順による送金
// アバターが一度もログインしていない場合は,送金できない.
//
// $type: トランザクションのタイプ.デフォルトは 5003:ReferBonus
// $serverURI: 処理を行うリージョンサーバの URI (オフライン時対応)
// $secretCode: MoneyServer.ini に書かれた MoneyScriptAccessKey の値.
//
function send_money($agentID, $amount, $type=5003, $serverURI=null, $secretCode=null, $description)
{
if (!USE_CURRENCY_SERVER) return false;
if (!isGUID($agentID)) return false;
// XML RPC to Region Server
$server['url'] = null;
if ($serverURI!=null) {
$url = parse_url($serverURI);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($serverURI, $port);
}
if ($server['url']==null) {
$results = opensim_get_userinfo($agentID);
$url = parse_url($results['simip']);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($results['simip'], $port);
}
if ($server['url']==null) return false;
if ($secretCode!=null) {
$secretCode = md5($secretCode.'_'.$server['host']);
}
else {
$secretCode = get_confirm_value($server['host']);
}
$req = array('agentUUID'=>$agentID, 'secretAccessCode'=>$secretCode, 'amount'=>$amount, 'transactionType'=>$type, 'description'=>$description);
$params = array($req);
$request = xmlrpc_encode_request('SendMoney', $params);
$response = do_call($server['url'], $server['port'], $request);
if ($response!=null and array_key_exists('success', $response)) return $response['success'];
return false;
}
//
// Send the money to avatar for bonus by Milo
//
// XMLRPC による正式な手順による送金
// アバターが一度もログインしていない場合は,送金できない.
//
// $serverURI: 処理を行うリージョンサーバの URI (オフライン時対応)
// $secretCode: MoneyServer.ini に書かれた MoneyScriptAccessKey の値.
//
function move_money($fromID, $toID, $amount, $serverURI=null, $secretCode=null)
{
if (!USE_CURRENCY_SERVER) return false;
if (!isGUID($fromID)) return false;
if (!isGUID($toID)) return false;
// XML RPC to Region Server
$server['url'] = null;
if ($serverURI!=null) {
$url = parse_url($serverURI);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($serverURI, $port);
}
if ($server['url']==null) {
$results = opensim_get_userinfo($fromID);
$url = parse_url($results['simip']);
$port = $url['scheme'] == "https" ? 7001 : 7000;
$server = make_url($results['simip'], $port);
}
if ($server['url']==null) return false;
if ($secretCode!=null) {
$secretCode = md5($secretCode.'_'.$server['host']);
}
else {
$secretCode = get_confirm_value($server['host']);
}
$req = array('fromUUID'=>$fromID, 'toUUID'=>$toID, 'secretAccessCode'=>$secretCode, 'amount'=>$amount);
$params = array($req);
$request = xmlrpc_encode_request('MoveMoney', $params);
$response = do_call($server['url'], $server['port'], $request);
if ($response!=null and array_key_exists('success', $response)) return $response['success'];
return false;
}
function getSecureId($agentID){
$presenceData = opensim_get_avatar_session($agentID);
return $presenceData["secureID"];
}
function getSessionId($agentID){
$presenceData = opensim_get_avatar_session($agentID);
return $presenceData["sessionID"];
}
function hasPendingInvoice($agentID){
return has_pending_btcpay_invoice($agentID);
}
function updateInvoice($agentID, $invoiceID, $invoiceStatus){
return update_btcpay_invoice_status($agentID, $invoiceID, $invoiceStatus);
}
function removeInvoice($agentID, $invoiceID){
return remove_btcpay_invoice($agentID, $invoiceID);
}
function getPullPaymentData($pullPaymentID, $payoutID){
return get_btcpay_pull_payment_data($pullPaymentID, $payoutID);
}
function hasPendingPayout($agentID){
return has_pending_btcpay_pull_payment($agentID);
}
function updatePullPayment($agentID, $pullPaymentID, $payoutID, $pullPaymentStatus){
return update_btcpay_payout_status($agentID, $pullPaymentID, $payoutID, $pullPaymentStatus);
}
function removePullPayment($agentID, $pullPaymentID, $payoutID){
return remove_btcpay_pull_payment($agentID, $pullPaymentID, $payoutID);
}
// XML RPC
function do_call($uri, $port, $request)
{
$server = make_url($uri, $port);
$header[] = 'Content-type: text/xml';
$header[] = 'Content-length: '.strlen($request);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $server['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);
if (DISABLE_SSL_VERIFICATION){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
$data = curl_exec($ch);
if (!curl_errno($ch)) curl_close($ch);
$ret = false;
if ($data) $ret = xmlrpc_decode($data);
// for Debug
/*
ob_start();
print_r($ret);
$rt = ob_get_contents();
ob_end_clean();
error_log('[do_call] responce = '.$rt);
*/
return $ret;
}
/* Request the invoice from your BTCPay store. more infos here:
https://docs.btcpayserver.org/API/Greenfield/v1/#operation/Invoices_CreateInvoice
*/
function requestInvoice($agentid, $secureid, $amount, $isWebPurchase)
{
$header = array('Accept: application/json', 'Content-Type: application/json', 'Authorization: token '. BTCPAY_API_KEY);
$checkout = array(
"defaultPaymentMethod" => BTCPAY_PAYMENT_CRYPTOCURRENCY
);
$posData = array(
"avatarName" => opensim_get_avatar_name($agentid)["fullname"],
"avatartId" => $agentid,
"localAmount" => $amount,
"txType" => "5010",
"isWebPurchase" => $isWebPurchase
);
$metaData = array(
"itemDesc" => $amount ." ". LOCAL_CURRENCY_SYMBOL ." Purchase.",
"posData" => $posData
);
$additionalSearchTerms = array(
opensim_get_avatar_name($agentid)["fullname"],
$agentid
);
$cost = convert_to_real($amount, false);
if($cost == null) return null;
$invoice = array(
"currency" => BTCPAY_FIAT,
"amount" => BTCPAY_FIAT == BTCPAY_PAYMENT_CRYPTOCURRENCY ? $cost['cryptoAmount'] : $cost['fiatAmount'],
"metadata" => $metaData,
"checkout" => $checkout,
"additionalSearchTerms" => $additionalSearchTerms
);
$request = json_encode($invoice);
$url = BTCPAY_SERVER_URL ."/api/v1/stores/". BTCPAY_STORE_ID ."/invoices";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
if (DISABLE_SSL_VERIFICATION){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
$data = curl_exec($ch);
curl_close($ch);
$ret = null;
$ret = json_decode($data, true);
if ($data && array_key_exists('id', $ret)) {
$notification = "BTCPay Notification:\nInvoice successfully created.\nID: ". $ret["id"] ."\nand in wait of your payment at:\n\n". $ret["checkoutLink"];
if(!$isWebPurchase){
user_alert($ret["metadata"]["posData"]["avatartId"], $notification, $secureid);
}
add_new_btcpay_invoice($ret["metadata"]["posData"]["avatartId"], $ret["id"], "new", $amount);
return $ret;
}
else if($data && array_key_exists('message', $ret)){
$error = json_decode($data, true);
$ret = array(
"errorMessage" => "BTCPay Notification:\n". $error["message"]
);
}
return $ret;
}
function requestWithrawal($agentid, $secureid, $amount, $destination)
{
$header = array('Accept: application/json', 'Content-Type: application/json', 'Authorization: token '. BTCPAY_API_KEY);
$cost = convert_to_real($amount, true);
if($cost == null) return null;
$pullPayment = array(
"name" => BTCPAY_PAYMENT_CRYPTOCURRENCY ." Withdrawal To ". opensim_get_avatar_name($agentid)["fullname"],
"description" => "✔️ Your withdrawal request was successfully done.<br>Note: Withdrawals are not automatic and require a human intervention. This may take some minutes up to some business days. Thank you for your patience.\n",
"currency" => BTCPAY_FIAT,
"amount" => BTCPAY_FIAT == BTCPAY_PAYMENT_CRYPTOCURRENCY ? $cost['cryptoAmount'] : $cost['fiatAmount'],
"paymentMethods" => array(BTCPAY_PAYMENT_CRYPTOCURRENCY),
"autoApproveClaims" => false,
"expiresAt" => time() + 172800
);
$claim = array(
"destination" => $destination,
"amount" => $cost['fiatAmount'],
"paymentMethod" => BTCPAY_PAYMENT_CRYPTOCURRENCY,
"metadata" => array(
"avatarName" => opensim_get_avatar_name($agentid)["fullname"],
"avatartId" => $agentid,
"localAmount" => $amount,
"rate" => $cost["rate"],
"txType" => "5013"
)
);
$request = json_encode($pullPayment);
$url = BTCPAY_SERVER_URL ."/api/v1/stores/". BTCPAY_STORE_ID ."/pull-payments";
$ppch = curl_init();
curl_setopt($ppch, CURLOPT_URL, $url);
curl_setopt($ppch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ppch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ppch, CURLOPT_TIMEOUT, 3);
curl_setopt($ppch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ppch, CURLOPT_POSTFIELDS, $request);
if (DISABLE_SSL_VERIFICATION){
curl_setopt($ppch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ppch, CURLOPT_SSL_VERIFYHOST, 0);
}
$pullPaymentData = curl_exec($ppch);
curl_close($ppch);
$ppRet = null;
$ppRet = json_decode($pullPaymentData, true);
if ($pullPaymentData && array_key_exists('id', $ppRet)) {
$request = json_encode($claim);
$url = BTCPAY_SERVER_URL ."/api/v1/pull-payments/". $ppRet['id'] ."/payouts";
$clch = curl_init();
curl_setopt($clch, CURLOPT_URL, $url);
curl_setopt($clch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($clch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($clch, CURLOPT_TIMEOUT, 3);
curl_setopt($clch, CURLOPT_HTTPHEADER, $header);
curl_setopt($clch, CURLOPT_POSTFIELDS, $request);
if (DISABLE_SSL_VERIFICATION){
curl_setopt($clch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($clch, CURLOPT_SSL_VERIFYHOST, 0);
}
$claimData = curl_exec($clch);
curl_close($clch);
$clRet = null;
$clRet = json_decode($claimData, true);
if($claimData && array_key_exists('pullPaymentId', $clRet) && array_key_exists('id', $clRet) && $clRet['pullPaymentId'] == $ppRet['id']){
add_new_btcpay_pull_payment($agentid, $clRet['pullPaymentId'], $clRet['id'], "new", $cost['fiatAmount'], $amount);
$message = "Thank you for using our services!\nWithdrawal request successfully created.\nID: ". $clRet["pullPaymentId"] ."\nand in wait of the administration approval and payment.\nPlease, open this page to get your withdrawal status...\n";
loadBTCPayURL($agentid, BTCPAY_SERVER_URL ."/pull-payments/". $clRet["pullPaymentId"], $message, "BTCPay Withrawal",$secureid);
return array(
"success" => true,
"id" => $clRet["pullPaymentId"],
"link" => BTCPAY_SERVER_URL ."/pull-payments/". $clRet["pullPaymentId"]
);
}
else if($claimData && array_key_exists('message', $clRet)){
$error = json_decode($claimData, true);
$notification = "BTCPay Notification:\nClaim request failed!\n". $error['message'];
//user_alert($agentid, $notification, $secureid);
archivePullPayment($ppRet['id']);
return $ret = array(
"success" => false,
"errorMessage" => $error["message"]
);
}
}
else if($pullPaymentData && array_key_exists('message', $ppRet)){
$error = json_decode($pullPaymentData, true);
$notification = "BTCPay Notification:\nWithrawal request failed!\n". $error['message'];
user_alert($agentid, $notification, $secureid);
return $ret = array(
"success" => false,
"errorMessage" => $error["message"]
);
}
}
function archivePullPayment($pullPaymentID){
$header = array('Accept: application/json', 'Content-Type: application/json', 'Authorization: token '. BTCPAY_API_KEY);
$url = BTCPAY_SERVER_URL ."/api/v1/stores/". BTCPAY_STORE_ID ."/pull-payments/". $pullPaymentID;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
if (DISABLE_SSL_VERIFICATION){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
curl_exec($ch);
curl_close($ch);
return;
}
function getwithdrawalStatus(){return DISABLE_CURRENCY_WITHDRAWAL;}
function getCurrencyStatus(){return DISABLE_CURRENCY_PURCHASE;}
function getSupportedCrypto(){return BTCPAY_PAYMENT_CRYPTOCURRENCY;}
function getSupportedFiat(){return BTCPAY_FIAT;}
function getLocalCurrencySymbol(){return LOCAL_CURRENCY_SYMBOL;}
function getMinimumAmount(){return LOCAL_CURRENCY_MIN_AMOUNT;}
function getBuyPrice(){return LOCAL_CURRENCY_PRICE;}
function getWithdrawalPrice(){return LOCAL_CURRENCY_WITHDRAWAL_PRICE;}
function getPullPaymentLink(){return BTCPAY_SERVER_URL .'/pull-payments/';}
function getBankster(){return LOCAL_CURRENCY_BANKSTER;}
function getWebhookId(){return BTCPAY_WEBHOOK_ID;}
function getStoreId(){return BTCPAY_STORE_ID;}
function getLinkHash($account,$ip){
return hash("sha256", $account."_".CURRENCY_SCRIPT_KEY."_".$ip);
}
function getHash($account,$avatarSecureId,$avatarSession,$ip){
return hash("sha256", $account."_".$avatarSecureId."_".$avatarSession."_".CURRENCY_SCRIPT_KEY."_".$ip);
}
function getHashMac($data){
return hash_hmac('sha256', utf8_encode($data), utf8_encode(BTCPAY_WEBHOOK_SECRET));
}
function isUUID($uuid){
if ($uuid==null) return false;
if (!preg_match('/^[0-9A-Fa-f]{8,8}-[0-9A-Fa-f]{4,4}-[0-9A-Fa-f]{4,4}-[0-9A-Fa-f]{4,4}-[0-9A-Fa-f]{12,12}$/', $uuid)) return false;
return true;
}
function get_confirm_value($ipAddress)
{
$key = CURRENCY_SCRIPT_KEY;
if ($key=='') $key = '123456789';
$confirmvalue = md5($key.'_'.$ipAddress);
//hash("sha256",$key.'_'.$ipAddress);
return $confirmvalue;
}
function make_url($serverURI, $portnum=0)
{
$url = '';
$host = 'localhost';
$port = 80;
$protocol = 'http';
if ($serverURI!=null) {
$uri = parse_url($serverURI);
if ($uri["scheme"] != null) {
$protocol = $uri["scheme"];
$host = $uri["host"];
if ($uri["port"] != null) {
$port = $uri["port"];
}
else {
if ($portnum!=0) {
$port = $portnum;
}
else {
if ($uri["scheme"]=='http') $port = 80;
else if ($uri["scheme"]=='https') $port = 443;
}
}
}
if ($uri["scheme"] == null && $port==443) {
$url = 'https://'.$host.':'.$port.'/';
$protocol = 'https';
}
else if ($uri["scheme"] == null && $port==80) {
$url = 'http://'.$host.'/';
$protocol = 'http';
}
else {
$url = $protocol.'://'.$host.':'.$port.'/';
}
}
$server['url'] = $url;
$server['host'] = $host;
$server['port'] = $port;
$server['porotocol'] = $protocol;
return $server;
}
+1
View File
@@ -0,0 +1 @@
<script>history.go(-1);</script>
+162
View File
@@ -0,0 +1,162 @@
<?php
#
# Copyright (c)Melanie Thielker and Teravus Ovares (http://opensimulator.org/)
#
# 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.
#
//////////////////////////////////////////////////////////////////////////////
//
// Modified by Fumi.Iseki for CMS/LMS '09 5/31
// Modified by Adil El Farissi for the BTCPay integration.
//
if (!defined('ENV_READ_CONFIG')) require_once(realpath(dirname(__FILE__).'/../include/config.php'));
require_once(realpath(ENV_HELPER_PATH.'/helpers.php'));
###################### No user serviceable parts below #####################
#
# The XMLRPC server object
#
$xmlrpc_server = xmlrpc_server_create();
#
# Land purchase sections
#
# Functions are called by the viewer directly.
#
#
# Land buying functions
#
xmlrpc_server_register_method($xmlrpc_server, "preflightBuyLandPrep", "buy_land_prep");
function buy_land_prep($method_name, $params, $app_data)
{
$req = $params[0];
$agentid = $req['agentId'];
$secureid = $req['secureSessionId'];
$amount = $req['currencyBuy'];
$billableArea = $req['billableArea'];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$ret = opensim_check_secure_session($agentid, null, $secureid);
if($ret) {
$confirmvalue = get_confirm_value($ipAddress);
$membership_levels = array('levels' => array('id' => "00000000-0000-0000-0000-000000000000", 'description' => "some level"));
$landUse = array('upgrade' => False, 'action' => "".SYSURL."");
$cost = convert_to_real($amount, false);
if($cost != null){
$currency = array('estimatedLocalCost'=> $cost['fiatAmount'] ." ". BTCPAY_FIAT. " ~ ". $cost['cryptoAmount'] ." ". BTCPAY_PAYMENT_CRYPTOCURRENCY);
}
else{
$currency = array('estimatedLocalCost' => bcmul($amount, LOCAL_CURRENCY_PRICE, 2) ." ". BTCPAY_FIAT. " \n Rates Unavailable");
}
$membership = array('upgrade' => False, 'action' => "".SYSURL."", 'levels' => $membership_levels);
$response_xml = xmlrpc_encode(array('success' => True,
'currency' => $currency,
'membership'=> $membership,
'landUse' => $landUse,
'confirm' => $confirmvalue));
}
else {
$response_xml = xmlrpc_encode(array( 'success' => False,
'errorMessage' => "Unable to Authenticate\n\nClick URL for more info.",
'errorURI' => "".SYSURL.""));
}
header("Content-type: text/xml");
echo $response_xml;
return "";
}
#
# Perform the buy (所持金が足りないとき)
#
xmlrpc_server_register_method($xmlrpc_server, "buyLandPrep", "buy_land");
function buy_land($method_name, $params, $app_data)
{
$req = $params[0];
$agentid = $req['agentId'];
$secureid = $req['secureSessionId'];
$amount = $req['currencyBuy'];
$cost = $req['estimatedLocalCost'];
$billableArea = $req['billableArea'];
$confim = $req['confirm'];
$ipAddress = $_SERVER['REMOTE_ADDR'];
//
if ($confim!=get_confirm_value($ipAddress)) {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\n\nMissmatch Confirm Value!!",
'errorURI' => "".SYSURL.""));
header("Content-type: text/xml");
echo $response_xml;
return "";
}
$ret = opensim_check_secure_session($agentid, null, $secureid);
if ($ret) {
if ($amount <= get_balance($agentid)) {
//land_move_money($agentid, null, $amount, 5002, 0, "Land Purchase", 0, 0, $ipAddress);
update_simulator_balance($agentid, -1, $secureid);
$response_xml = xmlrpc_encode(array('success' => True));
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage'=> "\n\nYou do not have sufficient funds for this purchase. Please click [BUY ". LOCAL_CURRENCY_SYMBOL ."] in the top menu to reload your balance."));
}
}
else {
$response_xml = xmlrpc_encode(array('success' => False,
'errorMessage' => "\n\nUnable to Authenticate\n\nClick URL for more info.",
'errorURI' => "".SYSURL.""));
}
header("Content-type: text/xml");
echo $response_xml;
return "";
}
#
# Process XMLRPC request
#
if (!isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = file_get_contents('php://input');
$request_xml = $HTTP_RAW_POST_DATA;
//error_log("landtool.php: ".$request_xml);
xmlrpc_server_call_method($xmlrpc_server, $request_xml, '');
xmlrpc_server_destroy($xmlrpc_server);
+145
View File
@@ -0,0 +1,145 @@
<?php
#
# Add by Adil El Farissi for the BTCPay integration.
#
# 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.
#
if (!defined('ENV_READ_CONFIG')) require_once(realpath(dirname(__FILE__).'/../include/config.php'));
require_once(realpath(ENV_HELPER_PATH.'/helpers.php'));
if (getenv('REQUEST_METHOD') == 'POST') {
$notification_data = file_get_contents("php://input");
if ($_SERVER["HTTP_BTCPAY_SIG"] && explode("/", $_SERVER["HTTP_USER_AGENT"])[0] == "BTCPayServer"){
$reqHash = str_replace("sha256=", "", $_SERVER["HTTP_BTCPAY_SIG"]);
$localHash = getHashMac($notification_data);
if (hash_equals($reqHash, $localHash)){
$data = json_decode($notification_data, true);
if ($data["webhookId"] == getWebhookId() && $data["storeId"] == getStoreId()){
if (array_key_exists("invoiceId", $data) && $data["metadata"] != null){
$agentId = $data["metadata"]["posData"]["avatartId"];
$secureId = getSecureId($agentId);
$amount = $data["metadata"]["posData"]["localAmount"];
$isWebPurchase = (bool)$data["metadata"]["posData"]["isWebPurchase"];
if ($agentId != null && $secureId != null && $amount != null){
if ($data["type"] == "InvoiceExpired" || $data["type"] == "InvoiceInvalid"){
$message = "Invoice Expired!\nID: ". $data["invoiceId"];
if(!$isWebPurchase){
user_alert($agentId, $message, $secureId);
}
removeInvoice($agentId, $data["invoiceId"]);
header("HTTP/1.1 200 OK");
return "";
}
else if ($data["type"] == "InvoiceProcessing"){
$message = "Invoice ID: ". $data["invoiceId"] ."\n is paid and waiting the usual confirmations";
if(!$isWebPurchase){
user_alert($agentId, $message, $secureId);
}
updateInvoice($agentId, $data["invoiceId"], "paid");
header("HTTP/1.1 200 OK");
return "";
}
else if ($data["type"] == "InvoiceSettled" && !(bool)$data["isRedelivery"]){
$message = "Thank you for your purchase!\nInvoice ID: ". $data["invoiceId"] ."\nis fully paid and confirmed. you have recived ". $amount ." ". getLocalCurrencySymbol() .".";
$description = "";
if ($data["metadata"]["posData"]["txType"] == "5010"){
$description = "Currency Buy Invoice:". $data["invoiceId"];
}
$description = "Currency Buy - Invoice: ". $data["invoiceId"];
if(!$isWebPurchase){
user_alert($agentId, $message, $secureId);
}
if (send_money($agentId, (int)$amount, 5010, null, null, $description)){
updateInvoice($agentId, $data["invoiceId"], "settled");
}
header("HTTP/1.1 200 OK");
return "";
}
}
}
else if (array_key_exists("pullPaymentId", $data) && array_key_exists("payoutId", $data)){
if ($data["type"] == "PayoutCreated" && $data["payoutState"] == "AwaitingApproval"){
$ppData = getPullPaymentData($data["pullPaymentId"], $data["payoutId"]);
if ($ppData != null && $ppData["status"] == "new"){
updatePullPayment($ppData["agentID"], $data["pullPaymentId"], $data["payoutId"], $data["payoutState"]);
move_money($ppData["agentID"], getBankster(), (int)$ppData["localAmount"],null,null);
header("HTTP/1.1 200 OK");
return "";
}
}
else if ($data["type"] == "PayoutApproved" && $data["payoutState"] == "AwaitingPayment" && !(bool)$data["isRedelivery"]){
$ppData = getPullPaymentData($data["pullPaymentId"], $data["payoutId"]);
if ($ppData != null && $ppData["status"] == "AwaitingApproval"){
updatePullPayment($ppData["agentID"], $data["pullPaymentId"], $data["payoutId"], $data["payoutState"]);
$message = "Your withrawal request\nID: ". $data["pullPaymentId"] ."\nwas approved by the administration.";
user_alert($ppData["agentID"], $message, getSecureId($ppData["agentID"]));
header("HTTP/1.1 200 OK");
return "";
}
}
else if ($data["type"] == "PayoutUpdated" && $data["payoutState"] == "InProgress" && !(bool)$data["isRedelivery"]){
$ppData = getPullPaymentData($data["pullPaymentId"], $data["payoutId"]);
if ($ppData != null && $ppData["status"] == "AwaitingPayment"){
updatePullPayment($ppData["agentID"], $data["pullPaymentId"], $data["payoutId"], $data["payoutState"]);
$message = "Your withrawal request\nID: ". $data["pullPaymentId"] ."\nwas honored by the administration.\nPlease, check the incoming trasaction in your wallet.";
user_alert($ppData["agentID"], $message, getSecureId($ppData["agentID"]));
header("HTTP/1.1 200 OK");
return "";
}
}
else if ($data["type"] == "PayoutUpdated" && $data["payoutState"] == "Completed" && !(bool)$data["isRedelivery"]){
$ppData = getPullPaymentData($data["pullPaymentId"], $data["payoutId"]);
if ($ppData != null && $ppData["status"] == "InProgress" || $ppData["status"] == "AwaitingPayment"){
updatePullPayment($ppData["agentID"], $data["pullPaymentId"], $data["payoutId"], $data["payoutState"]);
$message = "Your withrawal request\nID: ". $data["pullPaymentId"] ."\nwas confirmed and completed.\nThank you for using our services.";
user_alert($ppData["agentID"], $message, getSecureId($ppData["agentID"]));
archivePullPayment($data["pullPaymentId"]);
header("HTTP/1.1 200 OK");
return "";
}
}
else if ($data["type"] == "PayoutUpdated" && $data["payoutState"] == "Cancelled"){
$ppData = getPullPaymentData($data["pullPaymentId"], $data["payoutId"]);
if ($ppData != null && $ppData["agentID"] != null){
removePullPayment($ppData["agentID"], $data["pullPaymentId"], $data["payoutId"]);
$message = "Your withrawal request\nID: ". $data["pullPaymentId"] ."\nwas rejected or cancelled by the administration.\nPlease, contact the support and provide the request ID for more infos.";
user_alert($ppData["agentID"], $message, getSecureId($ppData["agentID"]));
archivePullPayment($data["pullPaymentId"]);
header("HTTP/1.1 200 OK");
return "";
}
}
}
}
}
}
header("HTTP/1.1 200 OK");
return "";
}
?>
+350
View File
@@ -0,0 +1,350 @@
<?php
#
# Add by Adil El Farissi for the BTCPay integration.
#
# 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.
#
if (!defined('ENV_READ_CONFIG')) require_once(realpath(dirname(__FILE__).'/../include/config.php'));
require_once(realpath(ENV_HELPER_PATH.'/helpers.php'));
$isDisabled = getwithdrawalStatus();
$cryptoSymbol = getSupportedCrypto();
$fiatSymbol = getSupportedFiat();
$localCurrencySymbol = getLocalCurrencySymbol();
$localCurrencyMinimum = getMinimumAmount();
$localCurrencyWithdrawalPrice = getWithdrawalPrice();
$pullPaymentLink = getPullPaymentLink();
?>
<!DOCTYPE HTML>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<style>
body{background-color:#161B22;font-family:arial;}
h2, h3{text-shadow: 2px 2px 2px #000;}
#page{min-height: auto;margin:10px auto; width:500px;background-color:#0D1117;padding:10px 20px;color:#fff;border: 1px solid #010;border-radius:2px;}
#content{height:auto;min-height:490px;}
#support{position:relative;display:block;background-color:#020;color:#fff;padding:10px;border: 1px solid #010;border-radius:10px;}
hr, a{text-decoration:none;color:#51B13E;}
.support-img{font-size:18px;}
.warning-box{text-align:center;margin-bottom:20px;margin-top:50px;}
.warning-img{font-size:150px;margin-top:10px;}
.warning{font-size:22px;color:#f00;text-shadow:2px 2px 1px #000;margin-bottom:10px;}
.success{font-size:22px;color:#0f0;text-shadow:2px 2px 1px #000;margin-bottom:10px;}
.sub-warning, .sub-success{font-size:14px;color:#ff0;text-shadow:1px 1px 1px #000;margin-bottom:30px;}
.inputs{margin:5px auto;display:block;}
.inputs input{margin:5px auto; display:inline-block;font-size:24px;width:210px;text-align:center;}
.inputs .button, .button{font-size: 16px;color:#fff;border:none;border-radius: 5px;text-shadow:0px 0px 2px #000;font-weight:bold;padding:10px;text-align:center;cursor:pointer;}
.label{text-align:left;color:#8B949E;}
tr{display:block;width:490px;}
hr{color: #51B13E;}
li{margin-bottom:10px;}
.btn-red {background-color: #f56954 !important;background: -moz-linear-gradient(bottom, #f00 0%, #370101 100%);background: -webkit-gradient(linear, bottom, top, color-stop(0%,#f00), color-stop(100%,#370101));background: -webkit-linear-gradient(bottom, #f00 0%,#370101 100%); background: -o-linear-gradient(bottom, #f00 0%,#370101 100%);background: -ms-linear-gradient(bottom, #f00 0%,#370101 100%);background: linear-gradient(to bottom, #f00 0%,#370101 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f00', endColorstr='#370101',GradientType=1 );}
.btn-green {background: #003300;background: -moz-linear-gradient(bottom, #003300 0%, #00AE00 100%);background: -webkit-gradient(linear, bottom, top, color-stop(0%,#003300), color-stop(100%,#00AE00));background: -webkit-linear-gradient(bottom, #003300 0%,#00AE00 100%);background: -o-linear-gradient(bottom, #003300 0%,#00AE00 100%);background: -ms-linear-gradient(bottom, #003300 0%,#00AE00 100%);background: linear-gradient(to top, #003300 0%,#00AE00 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#003300', endColorstr='#00AE00',GradientType=1 );}
.btn-red:hover, .btn-green:hover{background-color: #f39c12 !important;background: -moz-linear-gradient(bottom, #f39c12 0%, #875504 100%);background: -webkit-gradient(linear, bottom, top, color-stop(0%,#f39c12), color-stop(100%,#875504)); background: -webkit-linear-gradient(bottom, #f39c12 0%,#875504 100%);background: -o-linear-gradient(bottom, #f39c12 0%,#875504 100%);background: -ms-linear-gradient(bottom, #f39c12 0%,#875504 100%);background: linear-gradient(to bottom, #f39c12 0%,#875504 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f39c12', endColorstr='#875504',GradientType=1 );}
</style>
<title>BTCPay Withdrawals Proccessor</title>
</head>
<body>
<div id="page">
<div id="content">
<h2 style="margin:5px 0;">Withdraw To <?= $cryptoSymbol ?></h2>
<hr>
<?php
if(getenv('REQUEST_METHOD') == 'GET') {
if ($isDisabled){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">'. $cryptoSymbol .' withdrawals are disabled<br> by the administration !</span><br>
<span class="sub-warning">Please try again in some minutes...<br>Thanks for your patience.</span>
</div>';
return;
}else
if (isset($_GET["a"]) && isset($_GET["sh"])){
$account = $_GET["a"];
$securityHash = $_GET["sh"];
$session = opensim_get_avatar_session($account);
$avatarSecureId = $session["secureID"];
$avatarSession = $session["sessionID"];
$tempHash = getHash($account,$avatarSecureId,$avatarSession,$_SERVER['REMOTE_ADDR']);
$aviName = opensim_get_avatar_name($account)["fullname"];
$balance = get_balance($account, $avatarSecureId);
$price = convert_to_real($balance, true);
$pp = hasPendingPayout($account);
if(hash_equals($securityHash, $tempHash)){
if ($price == null){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">BTCPay Server is not available!</span><br>
<span class="sub-warning">Please try again in some minutes...<br>Thanks for your patience.</span>
</div>';
return;
}else if($pp != null){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">You have a pending withdrawal request!</span><br>
<span class="sub-warning">Please, wait the administration approuval to:<br><a href="'.$pullPaymentLink. $pp .'">'.$pullPaymentLink. $pp .'</a><br>Thanks for your patience.</span>
</div>';
return;
}
else {
echo
'<span>Welcome back <b>'. $aviName .'</b> ✔️</span><br>
<span>Your Balance is: <b>'.$balance.' '.$localCurrencySymbol .'&nbsp;&nbsp;=&nbsp;&nbsp;'. $price["fiatAmount"].' '. $fiatSymbol .'&nbsp;&nbsp;~&nbsp;&nbsp;'. $price["cryptoAmount"].' '. $cryptoSymbol .'</b></span><br>
<span>Exchange Rates: 1 '. $localCurrencySymbol .' = '. $localCurrencyWithdrawalPrice .' '.$fiatSymbol .'&nbsp;&nbsp;|&nbsp;&nbsp;1 '. $cryptoSymbol .' ~ '. $price["rate"] .' '. $fiatSymbol .'</span>
<div class="inputs">
<form method="post">
<table>
<tr>
<td >
<span class="label">Set the withrawal amount:</span><br>
<input id="inputBalance" type="number" name="amount" placeholder="'. $balance .'" min="'. $localCurrencyMinimum.'" oninput="setTimeout(()=>{ if(this.value < '. $localCurrencyMinimum .') this.value = '. $localCurrencyMinimum .'; document.getElementById(\'inputFiat\').value = parseFloat(this.value *'. $localCurrencyWithdrawalPrice.').toFixed(2)+\' '. $fiatSymbol.'\';}, 2000);">
</td>
<td><span style="font-size:40px"> 💱 </span></td>
<td >
<span class="label">You will recive in '. $cryptoSymbol .':</span><br>
<input id="inputFiat" type="text" name="fiat" value="0 '. $fiatSymbol .'" readOnly>
</td>
</tr>
<tr>
<td>
<span class="label">Set the destination '. $cryptoSymbol .' address:</span><br>
<input id="address" type="text" name="address" placeholder="Your '. $cryptoSymbol .' Address..." style="width:490px;font-size:14px;height:30px;" oninput="this.value = this.value.trim();">
</td>
</tr>
<input type="hidden" name="account" value="'. $account .'">
<input type="hidden" name="securityHash" value="'. $securityHash .'">
<input type="hidden" name="avatarSecureId" value="'. $avatarSecureId .'">
<input type="hidden" name="avatarSession" value="'. $avatarSession .'">
<tr>
<td>
<span><b>Important notes:</b></span>
<ul style="margin-top: 10px;">
<li>The withdrawals are not automatic and may take up to 48h.</li>
<li>You will recive the '. $cryptoSymbol .' equivalent (-fees) of the displayed '. $fiatSymbol .' amount at the current rate in real time.</li>
<li>The '. $cryptoSymbol .' network fees are at your charge and deduced from the final amount of '. $cryptoSymbol .' that you will recive in your wallet.</li>
<li>Don\'t forget to save your Pull Payment ID in the next step. You will need it to get fast support in case of problems.</li>
</ul>
</td>
</tr>
<tr>
<td style="float:right;">
<input class="button btn-green" type="submit" name="withdrawal" value="Request a Withdrawal" style="background-color:darkgreen;margin-top:17px;">
</td>
</tr>
</table>
</form>
</div>';
}
}else {
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Security verification failed!</span><br>
<span class="sub-warning">Please try to logout / login inworld to get a new withdrawal link...<br>Thanks for your patience.</span>
</div>';
}
}else{
$uuid = isset($_GET["account"]) ? $_GET["account"] : "";
echo
'<span><b>Step by step guide:</b></span>
<ul>
<li>Set your avatar key and click [ Send Me a Withdrawal Link ]. This will open a dialog box in your viewer... click [ Go To Page ].</li>
<li>In the withdrawal page, set the amount to exchange / withdraw, your '. $cryptoSymbol .' address and click [ Request a Withdrawal ].</li>
<li>A successful withdrawal request will provide you a BTCPay tracking page where you can get infos about the status of your withdrawal. Also, you will recive inworld notifications about the progress of the blockchain transaction.</li>
</ul>
<span><b>Please, set your avatar key:</b></span><br>
<span class="sub-warning">Your avatar must be / stay online inworld during this operation! </span>
<div style="text-align: center;margin-bottom: 30px;">
<form method="post">
<input id="aviKey" type="text" name="aviKey" value="'. $uuid .'" placeholder="Enter Your Avatar Key" style="width:490px;font-size:18px;height:30px;text-align:center;margin:10px 0;" oninput="this.value = this.value.trim();">
<br>
<input class="button btn-red" type="submit" name="get-link" value="Send Me a Withdrawal Link" style="width:auto;margin-top:20px;">
</form>
</div>';
}
}
if(getenv('REQUEST_METHOD') == 'POST') {
if(array_key_exists('aviKey', $_POST) && $_POST['aviKey'] == null){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Missing your avatar UUID key!</span><br>
<span class="sub-warning">You can get your UUID from your avatar\'s "Profile".<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
else if(array_key_exists('aviKey', $_POST) && isUUID($_POST['aviKey'])){
$hash = getLinkHash($_POST['aviKey'],$_SERVER['REMOTE_ADDR']);
$ret = sendWithdrawalLinkRequest($_POST['aviKey'], $hash);
if($ret){
echo
'<div class="warning-box">
<span class="warning-img">✔️</span><br>
<span class="success">Security link successfully sent!</span><br>
<span class="sub-warning">Please open your withdrawal link from your viewer...</span>
</div>';
return;
}else {
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Failed to send the withdrawal link!</span><br>
<span class="sub-warning">Please try to logout / login inworld to get a new withdrawal link...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}
else if(array_key_exists('account', $_POST)
&& $_POST['account'] == $_GET['a']
&& array_key_exists('securityHash', $_POST)
&& $_POST['securityHash'] == $_GET['sh']){
$account = $_POST['account'];
$session = opensim_get_avatar_session($account);
$avatarSecureId = $session["secureID"];
$avatarSession = $session["sessionID"];
$tempHash = getHash($account,$avatarSecureId,$avatarSession,$_SERVER['REMOTE_ADDR']);
if(hash_equals($tempHash, $_POST['securityHash'])){
$aviName = opensim_get_avatar_name($account)["fullname"];
$balance = get_balance($account, $avatarSecureId);
if(array_key_exists('address', $_POST) && $_POST['address'] != null){
$destination = $_POST['address'];
}else{
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Missing '. $cryptoSymbol .' address!</span><br>
<span class="sub-warning">Please set a '. $cryptoSymbol .' address and try again...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
if(array_key_exists('amount', $_POST)
&& $_POST['amount'] >= $localCurrencyMinimum
&& $_POST['amount'] <= $balance){
$price = convert_to_real($_POST['amount'], true);
if($price == null){
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">BTCPay Server is not available!</span><br>
<span class="sub-warning">Please try again in some minutes...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}else{
echo
'<span>Processing withdrawal verifications for <b>'. $aviName .'</b> ✔️</span><br>
<span>Requested amount : <b>'. $_POST['amount'] .' '. $localCurrencySymbol .'</b> ✔️</span><br>
<span>You will recive : <b>'. $price['fiatAmount'] .' '. $fiatSymbol .' in '. $cryptoSymbol .'</b> </span><br>
<span>Sending Pull Payment request...</span><br>';
if ($account != null && $avatarSecureId != null && $_POST['amount'] != null && $destination != null){
$ret = requestWithrawal($account, $avatarSecureId, $_POST['amount'], $destination);
if($ret['success']){
/*echo
'<div class="warning-box">
<span class="warning-img">✔️</span><br>
<span class="success">Withdrawal Successfully Requested!</span><br>
<span class="sub-warning">Please open your tracking page to get more infos...<br><b>URL: <a class="" href="'. $ret["link"].'" >'. $ret["link"].'</b></span><br>
<input class="button" value="Go To Page" style="margin-top:30px;width:100px;background-color:darkgreen;"></a>
</div>';*/
header("Location: ".$ret['link']);
exit();
}else{
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Withdrawal failed!</span><br>
<span class="sub-warning">'.$ret["errorMessage"].'<br> Please, wait the transaction approuval...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}else{
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Missing withdrawal parameters!</span><br>
<span class="sub-warning">Please go back and try again...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}
}else{
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Missing or wrong '.$localCurrencySymbol.' amount!</span><br>
<span class="sub-warning">The amount in '.$localCurrencySymbol.' must be over the minimum '. $localCurrencyMinimum.' '.$localCurrencySymbol.'<br>and under your balance '.$balance.' '.$localCurrencySymbol.'.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}
else {
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Security verification failed!</span><br>
<span class="sub-warning">Please try to logout / login inworld to get a new withdrawal link...<br>Thanks for your patience.</span>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}else {
echo
'<div class="warning-box">
<span class="warning-img">⚠️</span><br>
<span class="warning">Security verification failed!</span><br>
<span class="sub-warning">Please try to logout / login inworld to get a new withdrawal link...<br>Thanks for your patience.</span><br>
<input class="button btn-red" value="Go Back" style="margin-top:30px;width:100px;" onclick="window.history.back();">
</div>';
return;
}
}
?>
<div id="support"><span>Need help?</span>&nbsp;&nbsp;<a href="#" target="_blank"><span class="support-img">👨‍🔧</span> InWorld</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" target="_blank"><span class="support-img">🌐</span> Website</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" target="_blank"><span class="support-img">✉️</span> E-Mail</a></div>
</div>
</div>
</body>
+114
View File
@@ -0,0 +1,114 @@
<?php
//
// Configration file for non Web Interface
// v0.9.0Dev 2016100500
// Modified by Adil El Farissi for the BTCPay integration.
// v0.9.3Dev 2023112700
// Please set this hepler script directory Url
if (!defined("ENV_HELPER_URL")) define("ENV_HELPER_URL", "https://your-domain-or-ip.here/helper_scripts/helper/");
// Please set this hepler script directory absolute path.
if (!defined("ENV_HELPER_PATH")) define("ENV_HELPER_PATH", "D:\\xampp\\htdocs\\helper_scripts\\helper\\" );
/** Database Settings**/
/* Please set OpenSim MySQL DB access informations. Must be the same as [DatabaseService] => "ConnectionString" in StandaloneCommon.ini for standalones or Robust.ini for grids.*/
define("OPENSIM_DB_HOST","localhost");
define("OPENSIM_DB_NAME","opensim");
define("OPENSIM_DB_USER","db_user");
define("OPENSIM_DB_PASS","db_password");
define("OPENSIM_DB_MYSQLI",1);
/** BTCPay settings **/
/* Set your BTCPay URL, if you are not using the standard ports (80 or 443), you have to add it to your URL eg; if your port is 7777 set https://example.com:7777 */
define("BTCPAY_SERVER_URL", "https://testnet.demo.btcpayserver.org");
/* Set your store ID. You can get this after creating a store in your BTCPay instance under "Settings" in the left menu > General */
define("BTCPAY_STORE_ID", "FzeG58ybj2hU9XEkNEz8NqPrJq8LAtYXvZ5MEqfg6gT6");
/* Set your BTCPay account API Key ( Sensive Data !):
The API Key is used to request the invoices and pull payments from your BTCPay stores via the BTCPay's Greenfield API and must be created and set with only 3 permissions "Create an Invoice", "Create non-approved pull payments" and "Archive your pull payments". You can generate an API Key under "Account" in the left menu > "Manage Account" > API Keys. more infos here :
https://docs.btcpayserver.org/API/Greenfield/v1/#section/Authentication */
define("BTCPAY_API_KEY", "5ff92cd7338711627a075f05dd615f98ac8aefbd");
/* The Webhook system in BTCPay send the invoices notifications to the configured destination. in our case the destination is the webhook.php file located in "helper_scripts/helper/webhook.php" that handles the currency delivery to the customer after a seccessful payment / confirmation and the withdrawals.
The following values are used to check the origin and the HMAC of the incoming notifications and are sensive data.
To get your Webhook ID and Secret password, click your store "Settings" in the left menu > Webhooks, create a new webhook and set the full URL of the webhook.php file eg;
https://your-domain-or-ip.here/helper_scripts/helper/webhook.php
When done click "Modify" and copy your webhook ID from the URL in the browser address bar, the ID is the last value in the URL (after the last /) eg;
https://YourBTCPayDomainName.here/stores/FzeG58ybj2hU9XEkNEz8NqPrJq8LAtYXvZ5MEqfg6gT6/webhooks/HwR1T6LKgJkZkbNUvKj41N
in this example your Webhook ID is : HwR1T6LKgJkZkbNUvKj41N
You can get your Webhook Secret pass in the same page "Modify". more infos here :
https://docs.btcpayserver.org/API/Greenfield/v1/#tag/Webhooks */
define("BTCPAY_WEBHOOK_ID", "HwR1T6LKgJkZkbNUvKj41N");
define("BTCPAY_WEBHOOK_SECRET", "x7B3mpvqiyZpCkgD7q3EdmWM5Ke");
/* BTCPay get the rates and calculate in real time the equivalent of the your fiat prices in crypto based the following settings:
- BTCPAY_FIAT : The fiat ticker or symbol in uppercase eg; USD EUR GBP CAD... (Fiat only here!). This value depends on the availabilty of the fiat currency in the rates data provider that you can get and set in your store "Settings" > Rates.
- BTCPAY_PAYMENT_CRYPTOCURRENCY : The cryptocurrency ticker or symbol in uppercase that you want to recive as payment eg; LTC, DOGE, XMR, BTC... (Cryptos only here!)
NOTE: Not all the cryptocurrencies prices are adapted to the micro-payments and BTCPay supports only few ones... so, we are limited to the this list:
https://docs.btcpayserver.org/FAQ/Altcoin/
Recommanded:
- Dogecoin (DOGE): adapted value/price for the hypergrid economy and available in the majority of exchanges... DOGE do some surprises time to time like x2 (or /2!) in the rates.
- Monero (XMR): For privacy and a low ecological impact comparing with many others like Bitcoin. Also Monero is a CPU only minable coin, so you can setup a Monero miner aside your opensim and/or BTCPay instance and mine Monero when there is nobody inWorld...*/
define("BTCPAY_FIAT", "USD");
define("BTCPAY_PAYMENT_CRYPTOCURRENCY", "BTC");
/** End BTCPay settings **/
/** Local currency settings **/
/* Set your bankster avatar UUID to recive the local currency of the withdrawals. This must be the same as BankerAvatar in MoneyServer.ini*/
define("LOCAL_CURRENCY_BANKSTER", "6217ab96-5e6b-4815-9f2f-c2962262adc8");
/* Set the price of 1 local currency unit in 'BTCPAY_FIAT'. eg; if 'BTCPAY_FIAT' is EUR and the 'LOCAL_CURRENCY_PRICE' is set to 0.01 this mean 1 Euro cent and 1€ = 100 local currency units.
Default: 0.004 or 1 'BTCPAY_FIAT' = 250 local currency. */
define("LOCAL_CURRENCY_PRICE", 0.004);
/* The LOCAL_CURRENCY_WITHDRAWAL_PRICE is the local currency buyback price for withdrawals.
If LOCAL_CURRENCY_PRICE > LOCAL_CURRENCY_WITHDRAWAL_PRICE you do profit...
If LOCAL_CURRENCY_PRICE = LOCAL_CURRENCY_WITHDRAWAL_PRICE no profit...
If LOCAL_CURRENCY_PRICE < LOCAL_CURRENCY_WITHDRAWAL_PRICE you lose money...
Default: 0.0036 or 250 local currency = 0.9 'BTCPAY_FIAT' (10% profit is a max!). */
define("LOCAL_CURRENCY_WITHDRAWAL_PRICE", 0.0036);
/* Set the minimum amount to buy and withdraw. This is useful to keep your currency profitable or if you want to limit the currency buy to a category of users like the currencies resellers... In this case you have to adapt your LOCAL_CURRENCY_PRICE to let a profit margin to those entities eg; 0.0038 for a LOCAL_CURRENCY_MIN_AMOUNT >= 50k units.
Default: 250. for a public price / limit based on defaults...*/
define("LOCAL_CURRENCY_MIN_AMOUNT", 250);
/* Set the local currency symbol.
- For a standalone, this must be the same as [LoginService] => "Currency" in your StandaloneCommon.ini.
- For a grid, this must be the same as [LoginService] => "Currency" in your Robust.ini */
define("LOCAL_CURRENCY_SYMBOL", "B$");
/** Security settings **/
/* Disable the SSL/TLS certificates verifications for self-signed or invalid certificates.
Default: 0 for valid certs. If set to 1, will skip the cURL certs verification.*/
define("DISABLE_SSL_VERIFICATION", 1);
/* Disable currency purchases. set to 1 to disable */
define("DISABLE_CURRENCY_PURCHASE", 0);
/* Disable currency withdrawals. set to 1 to disable */
define("DISABLE_CURRENCY_WITHDRAWAL", 0);
/* Needed by the BTCPay integration to interact with the DTL/NSL Region Money Module.
Default: 1. If set to 0 the helper scripts will not send requests or data to Region Module */
define("USE_CURRENCY_SERVER", 1);
/* DTL/NSL Money Server Access Key:
Please set a strong password here!. Must be same key as MoneyScriptAccessKey in MoneyServer.ini and MoneyAccessKey in OpenSim.ini */
define("CURRENCY_SCRIPT_KEY", "123456789");
/** End Security settings **/
/** System settings **/
define("USE_UTC_TIME", 0);
define("DATE_FORMAT", "d.m.Y - H:i");
define("SYSURL", ENV_HELPER_URL);
$GLOBALS["xmlrpc_internalencoding"] = "UTF-8";
if (USE_UTC_TIME) date_default_timezone_set("UTC");
if (!defined("ENV_READ_CONFIG")) define("ENV_READ_CONFIG", "YES");
/** End System settings **/
+1
View File
@@ -0,0 +1 @@
<script>history.go(-1);</script>
+382
View File
@@ -0,0 +1,382 @@
<?php
class DB
{
var $Host = null; // Hostname of our MySQL server
var $Database = null; // Logical database name on that server
var $User = null; // Database user
var $Password = null; // Database user's password
var $Link_ID = null; // Result of mysql_connect()/mysqli_connect()
var $Query_ID = null; // Result of most recent mysql_query()/mysqli_query()
var $Record = array(); // Current mysql_fetch_array()/mysqli_fetch_array() -result
var $Row; // Current row number
var $Errno = 0; // Error state of query
var $Error = '';
var $UseMySQLi = false;
var $Timeout; // not implement yet
/*
function DB($dbhost=null, $dbname=null, $dbuser=null, $dbpass=null, $usemysqli=true, $timeout=60)
{
__construct($dbhost, $dbname, $dbuser, $dbpass, $usemysqli, $timeout);
}
*/
function __construct($dbhost=null, $dbname=null, $dbuser=null, $dbpass=null, $usemysqli=true, $timeout=60)
{
$this->Host = $dbhost;
$this->Database = $dbname;
$this->User = $dbuser;
$this->Password = $dbpass;
$this->UseMySQLi= $usemysqli;
$this->Timeout = $timeout;
ini_set('mysql.connect_timeout', $timeout);
}
function set_DB($dbhost, $dbname, $dbuser, $dbpass, $usemysqli=false)
{
$this->Host = $dbhost;
$this->Database = $dbname;
$this->User = $dbuser;
$this->Password = $dbpass;
$this->UseMySQLi= $usemysqli;
}
function halt($msg)
{
echo "<strong>DB ERROR :</strong> $msg<br />\n";
echo "<strong>MySQL ERROR:</strong> $this->Error ($this->Errno)<br />\n";
die('Session Halted.');
}
function connect()
{
if ($this->Link_ID==null) {
//
if (!$this->UseMySQLi) {
$this->Link_ID = mysql_connect($this->Host, $this->User, $this->Password);
if (!$this->Link_ID) {
$this->Errno = 999;
//error_log('cannot select database. 1/2');
return false;
}
mysql_set_charset('utf8');
$SelectResult = mysql_select_db($this->Database, $this->Link_ID);
if (!$SelectResult) {
$this->Errno = mysql_errno($this->Link_ID);
$this->Error = mysql_error($this->Link_ID);
$this->Link_ID = null;
//$this->halt('cannot select database <i>'.$this->Database.'</i>');
//error_log('cannot select database. 2/2');
return false;
}
}
//
else {
$this->Link_ID = mysqli_connect($this->Host, $this->User, $this->Password, $this->Database);
if (!$this->Link_ID) {
$this->Errno = 999;
$this->Error = mysqli_connect_error();
//$this->halt('cannot select database <i>'.$this->Database.'</i>');
//error_log('cannot select database.');
return false;
}
mysqli_set_charset($this->Link_ID, 'utf8');
}
}
return true;
}
function escape($String)
{
$this->connect();
if (!$this->UseMySQLi) return mysql_real_escape_string($String);
return mysqli_real_escape_string($this->Link_ID, $String);
}
function query($Query_String)
{
$this->connect();
if ($this->Errno!=0) return 0;
if (!$this->UseMySQLi) {
$this->Query_ID = mysql_query($Query_String, $this->Link_ID);
$this->Errno = mysql_errno($this->Link_ID);
$this->Error = mysql_error($this->Link_ID);
}
else {
$this->Query_ID = mysqli_query($this->Link_ID, $Query_String);
$this->Errno = mysqli_errno($this->Link_ID);
$this->Error = mysqli_error($this->Link_ID);
}
$this->Row = 0;
//
if (!$this->Query_ID) {
$this->halt('Invalid SQL: '.$Query_String);
}
return $this->Query_ID;
}
function next_record()
{
if (!$this->UseMySQLi) {
$this->Record = @mysql_fetch_array($this->Query_ID);
$this->Row += 1;
$this->Errno = mysql_errno($this->Link_ID);
$this->Error = mysql_error($this->Link_ID);
$stat = is_array($this->Record);
if (!$stat) {
@mysql_free_result($this->Query_ID);
$this->Query_ID = null;
}
}
else {
$this->Record = @mysqli_fetch_array($this->Query_ID);
$this->Row += 1;
$this->Errno = mysqli_errno($this->Link_ID);
$this->Error = mysqli_error($this->Link_ID);
$stat = is_array($this->Record);
if (!$stat) {
@mysqli_free_result($this->Query_ID);
$this->Query_ID = null;
}
}
return $this->Record;
}
function insert_record($table, $params)
{
if (!is_array($params)) return false;
$num = 0;
$keys = '';
$vals = '';
foreach ($params as $key => $value) {
if ($num==0) {
$keys = $key;
$vals = "'".$value."'";
}
else {
$keys .= ','.$key;
$vals .= ",'".$value."'";
}
$num++;
}
$this->query('INSERT INTO '.$table.' ('.$keys.') VALUES ('.$vals.')');
if ($this->Errno==0) return true;
return false;
}
// params配列の一番最初の要素が キー
function update_record($table, $params)
{
if (!is_array($params)) return false;
$num = 0;
$where = '';
$setval = '';
foreach ($params as $key => $value) {
if ($num==0) {
$where = $key."='".$value."'";
}
else if ($num==1) {
$setval = $key."='".$value."'";
}
else {
$setval .= ','.$key."='".$value."'";
}
$num++;
}
$this->query('UPDATE '.$table.' SET '.$setval.' WHERE '.$where);
if ($this->Errno==0) return true;
return false;
}
function num_rows()
{
if (!$this->UseMySQLi) return mysql_num_rows($this->Query_ID);
return mysqli_num_rows($this->Query_ID);
}
function affected_rows()
{
if (!$this->UseMySQLi) return mysql_affected_rows($this->Link_ID);
return mysqli_affected_rows($this->Link_ID);
}
function optimize($tbl_name)
{
$this->connect();
if ($this->Errno!=0) return;
if (!$this->UseMySQLi) {
$this->Query_ID = @mysql_query('OPTIMIZE TABLE '.$tbl_name, $this->Link_ID);
}
else {
$this->Query_ID = @mysqli_query($this->Link_ID, 'OPTIMIZE TABLE '.$tbl_name);
}
}
function clean_results()
{
if ($this->Query_ID!=null) {
if (!$this->UseMySQLi) {
mysql_freeresult($this->Query_ID);
}
else {
mysqli_freeresult($this->Query_ID);
}
$this->Query_ID = null;
}
}
function close()
{
/*
if ($this->Link_ID) {
if (!$this->UseMySQLi) mysql_close($this->Link_ID);
mysqli_close($this->Link_ID);
$this->Link_ID = null;
}
*/
}
function exist_table($table, $lower_case=true)
{
$ret = false;
if ($lower_case) $table = strtolower($table);
$this->query('SHOW TABLES');
if ($this->Errno==0) {
while (list($db_tbl) = $this->next_record()) {
if ($lower_case) $db_tbl = strtolower($db_tbl);
if ($db_tbl==$table) {
$ret = true;
break;
}
}
}
return $ret;
}
function exist_field($table, $field, $lower_case=true)
{
$ret1 = false;
$ret2 = false;
if ($lower_case) $cmp_table = strtolower($table);
else $cmp_table = $table;
$this->query('SHOW TABLES');
if ($this->Errno==0) {
while (list($db_tbl) = $this->next_record()) {
if ($lower_case) $db_tbl = strtolower($db_tbl);
if ($db_tbl==$cmp_table) {
$ret1 = true;
break;
}
}
}
if ($ret1) {
$this->query('SHOW COLUMNS FROM '.$table);
if ($this->Errno==0) {
while (list($db_fld) = $this->next_record()) {
if ($db_fld==$field) {
$ret2 = true;
break;
}
}
}
}
return $ret2;
}
//
// InnoDB では Update_time は NULL になる!
//
function get_update_time($table, $unixtime=true)
{
$update = '';
if ($unixtime) $update = 0;
$this->query("SHOW TABLE STATUS WHERE name='$table'");
if ($this->Errno==0) {
$table_status = $this->next_record();
$update = $table_status['Update_time'];
if ($unixtime) {
if ($update!='') $update = strtotime($update);
else $update = 0;
}
}
return $update;
}
//
// Lock
//
function lock_table($table, $mode='write')
{
$this->query("LOCK TABLES ".$table." ".$mode);
}
function unlock_table()
{
$this->query("UNLOCK TABLES");
}
//
// Timeout
//
function set_default_timeout($tm)
{
ini_set('mysql.connect_timeout', $tm);
$this->Timeout = $tm;
}
function set_temp_timeout($tm)
{
ini_set('mysql.connect_timeout', $tm);
}
function reset_timeout()
{
ini_set('mysql.connect_timeout', $this->Timeout);
}
}
File diff suppressed because it is too large Load Diff
+224
View File
@@ -0,0 +1,224 @@
<?php
/****************************************************************
* tools.func.php v1.0.0
* by Fumi.Iseki (c) 2010 5/13
*
* http://www.nsl.tuis.ac.jp/
*
****************************************************************/
/****************************************************************
* Function List
function isNumeric($str, $nullok=false)
function isAlphabetNumeric($str, $nullok=false)
function isAlphabetNumericSpecial($str, $nullok=false)
function isGUID($uuid, $nullok=false)
function split_key_value($str)
function make_random_hash()
function make_random_guid()
function j2k_to_tga($file, $iscopy=true)
function get_j2k_to_tga_command() // need j2k_to_image (OpenJpeg)
function get_image_size_convert_command($xsize, $ysize)
function find_command_path($command)
****************************************************************/
function isNumeric($str, $nullok=false)
{
if ($str!='0' and $str==null) return $nullok;
if (!preg_match('/^[0-9\.]+$/', $str)) return false;
return true;
}
function isAlphabetNumeric($str, $nullok=false)
{
if ($str!='0' and $str==null) return $nullok;
if (!preg_match('/^\w+$/', $str)) return false;
return true;
}
function isAlphabetNumericSpecial($str, $nullok=false)
{
if ($str!='0' and $str==null) return $nullok;
//if (!preg_match('/^[_a-zA-Z0-9 &@%#\-\.]+$/', $str)) return false;
if (!preg_match('/^[_a-zA-Z0-9 !&@%#\-\.\$]+$/', $str)) return false;
return true;
}
function isGUID($uuid, $nullok=false)
{
if ($uuid==null) return $nullok;
if (!preg_match('/^[0-9A-Fa-f]{8,8}-[0-9A-Fa-f]{4,4}-[0-9A-Fa-f]{4,4}-[0-9A-Fa-f]{4,4}-[0-9A-Fa-f]{12,12}$/', $uuid)) return false;
return true;
}
function make_random_hash()
{
$ret = sprintf('%04x%04x%04x%04x%04x%04x%04x%04x',mt_rand(0,0xffff),mt_rand(0,0xffff),mt_rand(0,0xffff),mt_rand(0,0xffff),
mt_rand(0,0xffff),mt_rand(0,0xffff),mt_rand(0,0xffff),mt_rand(0,0xffff));
return $ret;
}
function make_random_guid()
{
$uuid = sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ),
mt_rand( 0, 0x0fff ) | 0x4000,
mt_rand( 0, 0x3fff ) | 0x8000,
mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ), mt_rand( 0, 0xffff ) );
return $uuid;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// String Tools
//
// parse {"key1":"value1","key2":{"key3":"value3"}}
//
// --> [key1] => value1
// [key2] => Array
// (
// [key3] => value3
// )
//
function split_key_value($str)
{
$info = array();
$str = trim($str);
if (substr($str, 0, 1)=='{' and substr($str, -1)=='}') {
$str = substr($str, 1, -1);
$inbrkt = 0;
$inquot = false;
$inkkko = false;
$isakey = true;
$key = "";
$val = "";
for ($i=0; $i<strlen($str); $i++) {
$cc = substr($str, $i, 1);
if ($inbrkt==0 and !$inquot and ($cc=='"' or $cc=='\'')) {
$inquot = true;
}
else if ($inbrkt==0 and $inquot and ($cc=='"' or $cc=='\'')) {
$inquot = false;
}
else if ($inbrkt==0 and $isakey and !$inquot and !$inkkko and $cc==':') {
$isakey = false;
}
else if ($inbrkt==0 and !$isakey and !$inquot and !$inkkko and $cc==',') {
if (substr($val, 0, 1)=='{' and substr($val, -1)=='}') {
$info[$key] = split_key_value($val);
}
else $info[$key] = $val;
$isakey = true;
$key = "";
$val = "";
}
else {
if ($cc=='{') $inbrkt++;
else if ($cc=='}') $inbrkt--;
else {
if ($inbrkt==0 and !$inkkko and $cc=='[') $inkkko = true;
else if ($inbrkt==0 and $inkkko and $cc==']') $inkkko = false;
}
if ($isakey) $key .= $cc;
else $val .= $cc;
}
}
//
if ($key!="") {
if (substr($val, 0, 1)=='{' and substr($val, -1)=='}') {
$info[$key] = split_key_value($val);
}
else $info[$key] = $val;
}
}
return $info;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Image
//
//
// Convert Image from JPEG2000 to TGA
// file -> file.tga
//
function j2k_to_tga($file, $iscopy=true)
{
if (!file_exists($file)) return false;
$com_totga = get_j2k_to_tga_command();
if ($com_totga=='') return false;
if ($iscopy) $ret = copy ($file, $file.'.j2k');
else $ret = rename($file, $file.'.j2k');
if (!$ret) return false;
exec("$com_totga -i $file.j2k -o $file.tga 1>/dev/null 2>&1");
unlink($file.'.j2k');
return true;
}
function get_j2k_to_tga_command()
{
$command = find_command_path('j2k_to_image');
return $command;
}
//
// Image Size Convert Command String
//
function get_image_size_convert_command($xsize, $ysize)
{
if (!isNumeric($xsize) or !isNumeric($ysize)) return '';
$command = find_command_path('convert');
if ($command=='') return '';
$prog = $command.' - -geometry '.$xsize.'x'.$ysize.'! -';
return $prog;
}
function find_command_path($command)
{
$path = '';
if (file_exists('/usr/local/bin/'.$command)) $path = '/usr/local/bin/';
else if (file_exists('/usr/bin/'.$command)) $path = '/usr/bin/';
else if (file_exists('/usr/X11R6/bin/'.$command)) $path = '/usr/X11R6/bin/';
else if (file_exists('/bin/'.$command)) $path = '/bin/';
else return '';
return $path.$command;
}
Binary file not shown.
Binary file not shown.
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
</configSections>
<appSettings>
</appSettings>
<log4net>
<appender name="Console" type="OpenSim.Framework.Console.OpenSimAppender, OpenSim.Framework.Console">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{HH:mm:ss} - %message%newline" />
</layout>
</appender>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="MoneyServer.log" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level - %logger %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
+136
View File
@@ -0,0 +1,136 @@
[Startup]
;
; Place to create a PID file
; PIDFile = "/tmp/money.pid"
[MySql]
;
;Connection parameters of MySQL
hostname = localhost
database = opensim
username = db_user
password = db_password
pooling = false
port = 3306
;
; Max DB connections kept by money server.
MaxConnection = 10
[MoneyServer]
; Port No. of this Server
ServerPort = 8008
;
; If the user is not found in database,he/she will be created with the default balance.
DefaultBalance = 0
;
; Is amount==0 transaction enable? Default is false.
;EnableAmountZero = false
;
; If "00000000-0000-0000-0000-000000000000" is specified, all avatars can get money from system.
; If "" is specified, nobody can get money.
BankerAvatar = ""
;
; If you want to use llGiveMoney() function normally even when payer doesn't login to OpenSim,
; please set true to this valiable
EnableForceTransfer = true
;
; Send/Move money to/from avatar by Money Script
EnableScriptSendMoney = true
;; Specify same secret key in include/config.php or WI(XoopenSim/Modlos)
MoneyScriptAccessKey = "123456789"
;; Not use 127.0.0.1. This is used to generate Script key
MoneyScriptIPaddress = "192.168.1.109"
;
; for HG/Guest Avatar. Foreign Avatar is always false
;EnableHGAvatar = false
;EnableGuestAvatar = false
;HGAvatarDefaultBalance = 0
;GuestAvatarDefaultBalance = 0
;
; Message that displayed in blue dialog, when balance is updated.
; If "" is specified, blue dialog is not displayed.
; You can use {0} and {1} in message string.
; {0} means amount and {1} means avatar name or object owner name.
;; for send gift to other avatar
BalanceMessageSendGift = "Sent {0} B$ Gift to {1}."
;; for receieve gift from other avatar
BalanceMessageReceiveGift = "Received {0} B$ Gift from {1}."
;; for upload and group creation charge
;BalanceMessagePayCharge = ""
;; for buy the object
BalanceMessageBuyObject = "Bought the Object {2} from {1} for {0} B$."
;; for sell the object
BalanceMessageSellObject = "{1} bought the Object {2} for {0} B$."
;; for buy the land
BalanceMessageLandSale = "Paid {0} B$ for land purchase."
;; for get the money of the sold land
;BalanceMessageScvLandSale = ""
;; for get the money from object by llGiveMoney()
BalanceMessageGetMoney = "Got {0} B$ from {1}."
;; for buy the money from system
BalanceMessageBuyMoney = "Bought {0} B$ from {1}."
;; when roll back ocuurred
BalanceMessageRollBack = "RollBack the Transaction: {0} B$ from/to {1}."
;; for sender of sending the money
BalanceMessageSendMoney = "Paid {0} B$ to {1}."
;; for receive the money
BalanceMessageReceiveMoney = "Received {0} B$ from {1}."
[Certificate]
;
; Certification Configuration
;
; CA Cert to check Client/Server Cert (unused)
;CACertFilename = "cacert.crt"
;
; HTTPS Server Cert (Server Mode)
ServerCertFilename = "SineWaveCert.pfx"
ServerCertPassword = "123"
;ServerCertFilename = "server_cert.p12"
;ServerCertPassword = ""
; Client Authentication from Region Server
;; check Region Server
CheckClientCert = false
;ClientCrlFilename = "clcrl.crt"
;
; XML RPC to Region Server (Client Mode)
;; check Region Server
CheckServerCert = false
;ClientCertFilename = "client_cert.p12"
;;ClientCertPassword = ""
ClientCertFilename = "SineWaveCert.pfx"
ClientCertPassword = "123"
+14
View File
@@ -0,0 +1,14 @@
{
"runtimeOptions": {
"tfm": "net8.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "8.0.0"
},
"configProperties": {
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": true,
"System.Runtime.TieredCompilation.QuickJit": false
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.