From ad7d15727975cc25e8e79e787adfb0ad6fd1dccc Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Thu, 27 Apr 2023 10:14:06 -0400 Subject: [PATCH 01/11] Remove Cores CI scripts so we dont accidentally run their actions --- .github/workflows/msbuild48.yml | 57 ---------------------------- .github/workflows/msbuildnet6.yml | 63 ------------------------------- 2 files changed, 120 deletions(-) delete mode 100644 .github/workflows/msbuild48.yml delete mode 100644 .github/workflows/msbuildnet6.yml diff --git a/.github/workflows/msbuild48.yml b/.github/workflows/msbuild48.yml deleted file mode 100644 index f22f421b080..00000000000 --- a/.github/workflows/msbuild48.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: .msbuild48 - -on: - push: - branches: [ "master" ] - paths: - - '**.cs' - workflow_dispatch: - -jobs: - build: - if: github.repository == 'opensim/opensim' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: shortsha - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - name: preBuild - run: bash ${GITHUB_WORKSPACE}/runprebuild48.sh - - - name: Build - id: build - run: msbuild /p:Configuration=Release OpenSim.sln - - - name: release - if: success() - run: zip -r LastBuild.zip bin ThirdPartyLicenses README.md CONTRIBUTORS.txt LICENSE.txt - - uses: softprops/action-gh-release@v1 - if: success() - with: - tag_name: r${{ steps.vars.outputs.sha_short }} - name: LastAutoBuild - files: LastBuild.zip - - - name: report push to irc - if: github.event_name == 'push' - uses: rectalogic/notify-irc@v1 - with: - channel: "#opensim-dev" - server: "irc.libera.chat" - nickname: osgithub - message: | - ${{ github.actor }} pushed to ${{ github.repository }} - ${{ join(github.event.commits.*.message, '\n') }} - mono framework4.8 compile: ${{ steps.build.conclusion }} - - - name: manual report to irc - if: github.event_name == 'workflow_dispatch' - uses: rectalogic/notify-irc@v1 - with: - channel: "#opensim-dev" - server: "irc.libera.chat" - nickname: osgithub - message: | - ${{ github.repository }} - mono framework4.8 compile: ${{ steps.build.conclusion }} diff --git a/.github/workflows/msbuildnet6.yml b/.github/workflows/msbuildnet6.yml deleted file mode 100644 index a853c8c44ad..00000000000 --- a/.github/workflows/msbuildnet6.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: .msbuildnet6 - -on: - push: - branches: [ "dotnet6" ] - paths: - - '**.cs' - workflow_dispatch: - -jobs: - build: - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - ref: dotnet6 - - name: shortsha - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - - name: preBuild - run: bash ${GITHUB_WORKSPACE}/runprebuild.sh - - - name: Setup dotnet - uses: actions/setup-dotnet@v3 - with: - dotnet-version: '6.0.x' - - name: Build - id: build - run: dotnet build --configuration Release OpenSim.sln - - - name: release - if: success() - run: zip -r LastDotNetBuild.zip bin ThirdPartyLicenses README.md CONTRIBUTORS.txt LICENSE.txt - - uses: softprops/action-gh-release@v1 - if: success() - with: - tag_name: r${{ steps.vars.outputs.sha_short }} - name: LastDotNetAutoBuild - files: LastDotNetBuild.zip - - - name: report push to irc - if: github.event_name == 'push' - uses: rectalogic/notify-irc@v1 - with: - channel: "#opensim-dev" - server: "irc.libera.chat" - nickname: osgithub - message: | - ${{ github.actor }} pushed to ${{ github.repository }} - ${{ join(github.event.commits.*.message, '\n') }} - dotnet compile: ${{ steps.build.conclusion }} - - - name: manual report to irc - if: github.event_name == 'workflow_dispatch' - uses: rectalogic/notify-irc@v1 - with: - channel: "#opensim-dev" - server: "irc.libera.chat" - nickname: osgithub - message: | - ${{ github.repository }} - dotnet compile: ${{ steps.build.conclusion }} From 1c6cce4ceab56714ea09d8cb5d8e19a10cec7e04 Mon Sep 17 00:00:00 2001 From: Michael Dickson Date: Sun, 2 Jul 2023 22:27:37 -0400 Subject: [PATCH 02/11] Migrate from the Oracle Mysql connector to the more performance Pomello MySqlConnector dll. --- .gitattributes | 4 ++ .../OfflineIM/OpenSim.Addons.OfflineIM.csproj | 1 - .../Data/MySQL/MySQLAgentPreferencesData.cs | 1 - OpenSim/Data/MySQL/MySQLAssetData.cs | 3 +- OpenSim/Data/MySQL/MySQLAuthenticationData.cs | 2 +- OpenSim/Data/MySQL/MySQLAvatarData.cs | 2 +- OpenSim/Data/MySQL/MySQLEstateData.cs | 4 +- OpenSim/Data/MySQL/MySQLFSAssetData.cs | 3 +- OpenSim/Data/MySQL/MySQLFramework.cs | 7 +--- OpenSim/Data/MySQL/MySQLFriendsData.cs | 6 +-- .../Data/MySQL/MySQLGenericTableHandler.cs | 2 +- OpenSim/Data/MySQL/MySQLGridUserData.cs | 8 ---- OpenSim/Data/MySQL/MySQLGroupsData.cs | 7 +--- OpenSim/Data/MySQL/MySQLHGTravelData.cs | 8 +--- OpenSim/Data/MySQL/MySQLInventoryData.cs | 2 +- OpenSim/Data/MySQL/MySQLMigrations.cs | 39 ++++++++++++------- OpenSim/Data/MySQL/MySQLMuteListData.cs | 2 +- OpenSim/Data/MySQL/MySQLOfflineIMData.cs | 10 +---- OpenSim/Data/MySQL/MySQLPresenceData.cs | 8 +--- OpenSim/Data/MySQL/MySQLRegionData.cs | 4 +- OpenSim/Data/MySQL/MySQLSimulationData.cs | 2 +- OpenSim/Data/MySQL/MySQLUserAccountData.cs | 6 +-- OpenSim/Data/MySQL/MySQLUserAliasData.cs | 4 +- OpenSim/Data/MySQL/MySQLUserProfilesData.cs | 3 +- OpenSim/Data/MySQL/MySQLXAssetData.cs | 4 +- OpenSim/Data/MySQL/MySQLXInventoryData.cs | 2 +- OpenSim/Data/MySQL/OpenSim.Data.MySQL.csproj | 2 +- OpenSim/Data/OpenSim.Data.csproj | 1 + OpenSim/Data/Tests/AssetTests.cs | 6 +-- OpenSim/Data/Tests/EstateTests.cs | 8 +--- OpenSim/Data/Tests/InventoryTests.cs | 9 +---- OpenSim/Data/Tests/OpenSim.Data.Tests.csproj | 2 +- OpenSim/Data/Tests/RegionTests.cs | 5 +-- OpenSim/Framework/VersionInfo.cs | 2 +- .../OpenSim.Region.CoreModules.Tests.csproj | 2 + .../OpenSim.Region.CoreModules.csproj | 2 +- .../Gloebit/GloebitMoneyModule/Gloebit.csproj | 2 +- .../GloebitSubscriptionData.cs | 4 +- .../GloebitTransactionData.cs | 5 +-- .../GloebitMoneyModule/GloebitUserData.cs | 2 + .../MySQLMoneyManager.cs | 3 +- .../OpenSim.Data.MySQL.MoneyData.csproj | 2 +- .../MoneyDBService.cs | 32 +++++++-------- 43 files changed, 83 insertions(+), 150 deletions(-) diff --git a/.gitattributes b/.gitattributes index 70bb56362c1..2b853a4865a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,7 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Denote all files that are truly binary and should not be modified. *.lsl binary *.dat binary *.bmp binary diff --git a/OpenSim/Addons/OfflineIM/OpenSim.Addons.OfflineIM.csproj b/OpenSim/Addons/OfflineIM/OpenSim.Addons.OfflineIM.csproj index ef715584425..1bb689306ea 100644 --- a/OpenSim/Addons/OfflineIM/OpenSim.Addons.OfflineIM.csproj +++ b/OpenSim/Addons/OfflineIM/OpenSim.Addons.OfflineIM.csproj @@ -9,7 +9,6 @@ - diff --git a/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs index 17f13749e84..db5652f79df 100644 --- a/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs +++ b/OpenSim/Data/MySQL/MySQLAgentPreferencesData.cs @@ -31,7 +31,6 @@ using System.Data; using OpenMetaverse; using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index 8569c903a69..091b4b415ae 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -30,10 +30,9 @@ using System.Reflection; using System.Collections.Generic; using log4net; -using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Data; +using MySqlConnector; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs index fef582e8091..25ceee9e88f 100644 --- a/OpenSim/Data/MySQL/MySQLAuthenticationData.cs +++ b/OpenSim/Data/MySQL/MySQLAuthenticationData.cs @@ -32,7 +32,7 @@ using System.Data; using OpenMetaverse; using OpenSim.Framework; -using MySql.Data.MySqlClient; +using MySqlConnector; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLAvatarData.cs b/OpenSim/Data/MySQL/MySQLAvatarData.cs index 63e80209b40..32461fcf04d 100644 --- a/OpenSim/Data/MySQL/MySQLAvatarData.cs +++ b/OpenSim/Data/MySQL/MySQLAvatarData.cs @@ -31,9 +31,9 @@ using System.Reflection; using System.Threading; using log4net; +using MySqlConnector; using OpenMetaverse; using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs index 1cb21e72108..74c3d5744e3 100644 --- a/OpenSim/Data/MySQL/MySQLEstateData.cs +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs @@ -30,11 +30,9 @@ using System.Data; using System.Reflection; using log4net; -using MySql.Data.MySqlClient; +using MySqlConnector; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Data; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLFSAssetData.cs b/OpenSim/Data/MySQL/MySQLFSAssetData.cs index 6c486077d3e..22872175fd9 100644 --- a/OpenSim/Data/MySQL/MySQLFSAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLFSAssetData.cs @@ -30,10 +30,9 @@ using System.Collections.Generic; using System.Data; using OpenSim.Framework; -using OpenSim.Framework.Console; using log4net; -using MySql.Data.MySqlClient; using OpenMetaverse; +using MySqlConnector; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLFramework.cs b/OpenSim/Data/MySQL/MySQLFramework.cs index 98106f0057e..4cdbe2a532d 100644 --- a/OpenSim/Data/MySQL/MySQLFramework.cs +++ b/OpenSim/Data/MySQL/MySQLFramework.cs @@ -25,13 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using MySqlConnector; using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using OpenMetaverse; -using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs index 6ba9fbd33bf..71633b91a5c 100644 --- a/OpenSim/Data/MySQL/MySQLFriendsData.cs +++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs @@ -26,12 +26,8 @@ */ using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; +using MySqlConnector; using OpenMetaverse; -using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index ce228b59a66..29b1b6aea3c 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -30,7 +30,7 @@ using System.Data; using System.Reflection; using System.Text; -using MySql.Data.MySqlClient; +using MySqlConnector; using OpenMetaverse; namespace OpenSim.Data.MySQL diff --git a/OpenSim/Data/MySQL/MySQLGridUserData.cs b/OpenSim/Data/MySQL/MySQLGridUserData.cs index 00560c11db6..aeb480a72c5 100644 --- a/OpenSim/Data/MySQL/MySQLGridUserData.cs +++ b/OpenSim/Data/MySQL/MySQLGridUserData.cs @@ -26,14 +26,6 @@ */ using System; -using System.Collections.Generic; -using System.Data; -using System.Reflection; -using System.Threading; -using log4net; -using OpenMetaverse; -using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLGroupsData.cs b/OpenSim/Data/MySQL/MySQLGroupsData.cs index 77cb2f4db41..8965045e39c 100644 --- a/OpenSim/Data/MySQL/MySQLGroupsData.cs +++ b/OpenSim/Data/MySQL/MySQLGroupsData.cs @@ -26,15 +26,10 @@ */ using System; -using System.Collections; -using System.Collections.Generic; using System.Reflection; - using OpenSim.Framework; -using OpenSim.Data.MySQL; - using OpenMetaverse; -using MySql.Data.MySqlClient; +using MySqlConnector; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLHGTravelData.cs b/OpenSim/Data/MySQL/MySQLHGTravelData.cs index e81b880c95e..d51f8356118 100644 --- a/OpenSim/Data/MySQL/MySQLHGTravelData.cs +++ b/OpenSim/Data/MySQL/MySQLHGTravelData.cs @@ -26,14 +26,8 @@ */ using System; -using System.Collections.Generic; -using System.Data; -using System.Reflection; -using System.Threading; -using log4net; +using MySqlConnector; using OpenMetaverse; -using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLInventoryData.cs b/OpenSim/Data/MySQL/MySQLInventoryData.cs index c0895f58351..963fda91acf 100644 --- a/OpenSim/Data/MySQL/MySQLInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLInventoryData.cs @@ -29,10 +29,10 @@ using System.Collections.Generic; using System.Reflection; using log4net; -using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Data; +using MySqlConnector; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLMigrations.cs b/OpenSim/Data/MySQL/MySQLMigrations.cs index 2043dae0523..917f42216b7 100644 --- a/OpenSim/Data/MySQL/MySQLMigrations.cs +++ b/OpenSim/Data/MySQL/MySQLMigrations.cs @@ -25,15 +25,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using MySqlConnector; using System; -using System.Collections.Generic; -using System.Data; using System.Data.Common; -using System.IO; using System.Reflection; -using System.Text.RegularExpressions; -using log4net; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { @@ -65,19 +60,35 @@ protected override void ExecuteScript(DbConnection conn, string[] script) base.ExecuteScript(conn, script); return; } - - MySqlScript scr = new MySqlScript((MySqlConnection)conn); + foreach (string sql in script) { - foreach (string sql in script) + try { - scr.Query = sql; - scr.Error += delegate(object sender, MySqlScriptErrorEventArgs args) + using (MySqlCommand cmd = new MySqlCommand(sql, (MySqlConnection)conn)) { - throw new Exception(sql); - }; - scr.Execute(); + cmd.ExecuteNonQuery(); + } + } + catch (Exception) + { + throw new Exception(sql); + } } + + // XXX Was + //MySqlScript scr = new MySqlScript((MySqlConnection)conn); + //{ + // foreach (string sql in script) + // { + // scr.Query = sql; + // scr.Error += delegate(object sender, MySqlScriptErrorEventArgs args) + // { + // throw new Exception(sql); + // }; + // scr.Execute(); + // } + //} } } } diff --git a/OpenSim/Data/MySQL/MySQLMuteListData.cs b/OpenSim/Data/MySQL/MySQLMuteListData.cs index a5935a32fac..c12df4f7fb9 100644 --- a/OpenSim/Data/MySQL/MySQLMuteListData.cs +++ b/OpenSim/Data/MySQL/MySQLMuteListData.cs @@ -29,9 +29,9 @@ using System.Collections; using System.Collections.Generic; using System.Data; +using MySqlConnector; using OpenMetaverse; using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLOfflineIMData.cs b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs index 7608858d2ca..88947477719 100644 --- a/OpenSim/Data/MySQL/MySQLOfflineIMData.cs +++ b/OpenSim/Data/MySQL/MySQLOfflineIMData.cs @@ -25,16 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using MySqlConnector; using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; - -using OpenSim.Framework; -using OpenSim.Data.MySQL; - -using OpenMetaverse; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs index cd11fb31e15..758aea4ed2a 100644 --- a/OpenSim/Data/MySQL/MySQLPresenceData.cs +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs @@ -26,14 +26,8 @@ */ using System; -using System.Collections.Generic; -using System.Data; -using System.Reflection; -using System.Threading; -using log4net; +using MySqlConnector; using OpenMetaverse; -using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index d10fba41739..45b1dce25b8 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -26,14 +26,12 @@ */ using System; -using System.Collections; using System.Collections.Generic; using System.Data; using System.Reflection; -using MySql.Data.MySqlClient; +using MySqlConnector; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Data; using RegionFlags = OpenSim.Framework.RegionFlags; namespace OpenSim.Data.MySQL diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index b594a371483..54e846d2260 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -32,7 +32,7 @@ using System.Reflection; using System.Text; using log4net; -using MySql.Data.MySqlClient; +using MySqlConnector; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; diff --git a/OpenSim/Data/MySQL/MySQLUserAccountData.cs b/OpenSim/Data/MySQL/MySQLUserAccountData.cs index d5581317ad4..734f50a7352 100644 --- a/OpenSim/Data/MySQL/MySQLUserAccountData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAccountData.cs @@ -26,12 +26,8 @@ */ using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; +using MySqlConnector; using OpenMetaverse; -using OpenSim.Framework; -using MySql.Data.MySqlClient; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLUserAliasData.cs b/OpenSim/Data/MySQL/MySQLUserAliasData.cs index b0255ee1e3a..b3b1ba0c401 100644 --- a/OpenSim/Data/MySQL/MySQLUserAliasData.cs +++ b/OpenSim/Data/MySQL/MySQLUserAliasData.cs @@ -26,13 +26,11 @@ */ using System; +using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Data; -using MySql.Data.MySqlClient; -using System.Collections.Generic; - namespace OpenSim.Data.MySQL { /// diff --git a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs index c545c7e008c..3cbe5f4d4ae 100644 --- a/OpenSim/Data/MySQL/MySQLUserProfilesData.cs +++ b/OpenSim/Data/MySQL/MySQLUserProfilesData.cs @@ -28,12 +28,11 @@ using System; using System.Data; using System.Reflection; -using OpenSim.Data; using OpenSim.Framework; -using MySql.Data.MySqlClient; using OpenMetaverse; using OpenMetaverse.StructuredData; using log4net; +using MySqlConnector; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLXAssetData.cs b/OpenSim/Data/MySQL/MySQLXAssetData.cs index 0b69ca4f171..a90c2ab3089 100644 --- a/OpenSim/Data/MySQL/MySQLXAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLXAssetData.cs @@ -32,12 +32,10 @@ using System.IO.Compression; using System.Reflection; using System.Security.Cryptography; -using System.Text; using log4net; -using MySql.Data.MySqlClient; +using MySqlConnector; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Data; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index 34106e663d1..31879e819fa 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -31,9 +31,9 @@ using System.Text; using System.Reflection; using log4net; -using MySql.Data.MySqlClient; using OpenMetaverse; using OpenSim.Framework; +using MySqlConnector; namespace OpenSim.Data.MySQL { diff --git a/OpenSim/Data/MySQL/OpenSim.Data.MySQL.csproj b/OpenSim/Data/MySQL/OpenSim.Data.MySQL.csproj index 462bb4d9450..6c298076d00 100644 --- a/OpenSim/Data/MySQL/OpenSim.Data.MySQL.csproj +++ b/OpenSim/Data/MySQL/OpenSim.Data.MySQL.csproj @@ -52,7 +52,7 @@ - + diff --git a/OpenSim/Data/OpenSim.Data.csproj b/OpenSim/Data/OpenSim.Data.csproj index 8502f421237..9bc07d0f0c9 100644 --- a/OpenSim/Data/OpenSim.Data.csproj +++ b/OpenSim/Data/OpenSim.Data.csproj @@ -130,6 +130,7 @@ + \ No newline at end of file diff --git a/OpenSim/Data/Tests/AssetTests.cs b/OpenSim/Data/Tests/AssetTests.cs index cb8df20e5af..cf1ef6ecffb 100644 --- a/OpenSim/Data/Tests/AssetTests.cs +++ b/OpenSim/Data/Tests/AssetTests.cs @@ -25,23 +25,19 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; using System.Collections.Generic; -using log4net.Config; using NUnit.Framework; -using NUnit.Framework.Constraints; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Tests.Common; using System.Data.Common; -using log4net; // DBMS-specific: -using MySql.Data.MySqlClient; using OpenSim.Data.MySQL; using System.Data.SQLite; using OpenSim.Data.SQLite; +using MySqlConnector; namespace OpenSim.Data.Tests { diff --git a/OpenSim/Data/Tests/EstateTests.cs b/OpenSim/Data/Tests/EstateTests.cs index 8e89dd58880..4bfdc64f1da 100644 --- a/OpenSim/Data/Tests/EstateTests.cs +++ b/OpenSim/Data/Tests/EstateTests.cs @@ -25,24 +25,18 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; -using log4net.Config; using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; using OpenSim.Tests.Common; -using System.Text; -using log4net; -using System.Reflection; using System.Data.Common; // DBMS-specific: -using MySql.Data.MySqlClient; using OpenSim.Data.MySQL; using System.Data.SQLite; using OpenSim.Data.SQLite; +using MySqlConnector; namespace OpenSim.Data.Tests { diff --git a/OpenSim/Data/Tests/InventoryTests.cs b/OpenSim/Data/Tests/InventoryTests.cs index efe8920e05d..dc99bf1a5a3 100644 --- a/OpenSim/Data/Tests/InventoryTests.cs +++ b/OpenSim/Data/Tests/InventoryTests.cs @@ -25,22 +25,15 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; -using log4net.Config; using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Tests.Common; -using log4net; -using System.Reflection; using System.Data.Common; // DBMS-specific: -using MySql.Data.MySqlClient; using OpenSim.Data.MySQL; - -using System.Data.SQLite; -using OpenSim.Data.SQLite; +using MySqlConnector; namespace OpenSim.Data.Tests { diff --git a/OpenSim/Data/Tests/OpenSim.Data.Tests.csproj b/OpenSim/Data/Tests/OpenSim.Data.Tests.csproj index f892a1c9990..c4c9e1110b1 100644 --- a/OpenSim/Data/Tests/OpenSim.Data.Tests.csproj +++ b/OpenSim/Data/Tests/OpenSim.Data.Tests.csproj @@ -31,10 +31,10 @@ + - diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index afa5063fd5b..75d644aa0af 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -29,24 +29,21 @@ using System.Collections.Generic; using System.Drawing; using System.Text; -using log4net.Config; using NUnit.Framework; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Tests.Common; -using log4net; -using System.Reflection; using System.Data.Common; using System.Threading; // DBMS-specific: -using MySql.Data.MySqlClient; using OpenSim.Data.MySQL; using System.Data.SQLite; using OpenSim.Data.SQLite; +using MySqlConnector; namespace OpenSim.Data.Tests { diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index d5a201ad6f8..03dc412fd33 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs @@ -33,7 +33,7 @@ public class VersionInfo { public const string VersionNumber = "0.9.2.2"; public const string AssemblyVersionNumber = "0.9.2.2"; - public const string Release = "8510"; + public const string Release = "8584"; public const Flavour VERSION_FLAVOUR = Flavour.Dev; diff --git a/OpenSim/Region/CoreModules/OpenSim.Region.CoreModules.Tests.csproj b/OpenSim/Region/CoreModules/OpenSim.Region.CoreModules.Tests.csproj index aec7fe662ee..6da238e98b7 100644 --- a/OpenSim/Region/CoreModules/OpenSim.Region.CoreModules.Tests.csproj +++ b/OpenSim/Region/CoreModules/OpenSim.Region.CoreModules.Tests.csproj @@ -272,6 +272,8 @@ + + diff --git a/OpenSim/Region/CoreModules/OpenSim.Region.CoreModules.csproj b/OpenSim/Region/CoreModules/OpenSim.Region.CoreModules.csproj index 927255cf211..95eda71a891 100644 --- a/OpenSim/Region/CoreModules/OpenSim.Region.CoreModules.csproj +++ b/OpenSim/Region/CoreModules/OpenSim.Region.CoreModules.csproj @@ -106,7 +106,7 @@ - + diff --git a/addon-modules/Gloebit/GloebitMoneyModule/Gloebit.csproj b/addon-modules/Gloebit/GloebitMoneyModule/Gloebit.csproj index eaf112fb6d9..3f1b5c5c7a2 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/Gloebit.csproj +++ b/addon-modules/Gloebit/GloebitMoneyModule/Gloebit.csproj @@ -64,6 +64,6 @@ - + \ No newline at end of file diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitSubscriptionData.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitSubscriptionData.cs index d8df071a86e..9635303906a 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitSubscriptionData.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitSubscriptionData.cs @@ -21,15 +21,13 @@ using System.Data; using System.Reflection; using System.Text; -using MySql.Data.MySqlClient; -using Nini.Config; using OpenSim.Data.MySQL; using OpenSim.Data.PGSQL; using OpenSim.Data.SQLite; using Npgsql; using NpgsqlTypes; using OpenMetaverse; // Necessary for UUID type - +using MySqlConnector; namespace Gloebit.GloebitMoneyModule { diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitTransactionData.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitTransactionData.cs index 91cbe0546ab..f49aa237f97 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitTransactionData.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitTransactionData.cs @@ -18,13 +18,10 @@ using System; using System.Collections.Generic; -using System.Data; using System.Data.SqlTypes; using System.Reflection; -using System.Xml; using log4net; -using MySql.Data.MySqlClient; -using Nini.Config; +using MySqlConnector; using OpenSim.Data.MySQL; using OpenSim.Data.PGSQL; using OpenSim.Data.SQLite; diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitUserData.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitUserData.cs index 5bedffe55fb..9e40b0e864e 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitUserData.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitUserData.cs @@ -18,6 +18,8 @@ using System; using Nini.Config; +using MySqlConnector; + using OpenSim.Data.MySQL; using OpenSim.Data.PGSQL; using OpenSim.Data.SQLite; diff --git a/addon-modules/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData/MySQLMoneyManager.cs b/addon-modules/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData/MySQLMoneyManager.cs index f3d89a8e856..f166b755fe9 100644 --- a/addon-modules/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData/MySQLMoneyManager.cs +++ b/addon-modules/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData/MySQLMoneyManager.cs @@ -31,9 +31,8 @@ using System.Collections.Generic; using System.Text.RegularExpressions; using log4net; -using MySql.Data.MySqlClient; using OpenMetaverse; - +using MySqlConnector; namespace OpenSim.Data.MySQL.MoneyData { diff --git a/addon-modules/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData.csproj b/addon-modules/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData.csproj index fa11883e838..2285e1edf4f 100644 --- a/addon-modules/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData.csproj +++ b/addon-modules/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData/OpenSim.Data.MySQL.MoneyData.csproj @@ -9,7 +9,7 @@ - + diff --git a/addon-modules/OpenSim.Server.MoneyServer/OpenSim.Server.MoneyServer/MoneyDBService.cs b/addon-modules/OpenSim.Server.MoneyServer/OpenSim.Server.MoneyServer/MoneyDBService.cs index 0f281dc797d..aa7c2b2399b 100644 --- a/addon-modules/OpenSim.Server.MoneyServer/OpenSim.Server.MoneyServer/MoneyDBService.cs +++ b/addon-modules/OpenSim.Server.MoneyServer/OpenSim.Server.MoneyServer/MoneyDBService.cs @@ -33,7 +33,7 @@ using log4net; using System.Reflection; using OpenMetaverse; - +using MySqlConnector; namespace OpenSim.Server.MoneyServer { @@ -135,7 +135,7 @@ public int getBalance(string userID) return dbm.Manager.getBalance(userID); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -162,7 +162,7 @@ public bool withdrawMoney(UUID transactionID, string senderID, int amount) return dbm.Manager.withdrawMoney(transactionID, senderID, amount); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -189,7 +189,7 @@ public bool giveMoney(UUID transactionID, string receiverID, int amount) return dbm.Manager.giveMoney(transactionID, receiverID, amount); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -219,10 +219,8 @@ public bool setTotalSale(TransactionData transaction) { return dbm.Manager.setTotalSale(transaction.Receiver, transaction.ObjectUUID, transaction.Type, 1, transaction.Amount, time); } -#pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException) { -#pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); return dbm.Manager.setTotalSale(transaction.Receiver, transaction.ObjectUUID, transaction.Type, 1, transaction.Amount, time); } @@ -247,7 +245,7 @@ public bool addTransaction(TransactionData transaction) return dbm.Manager.addTransaction(transaction); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -293,7 +291,7 @@ public bool addUser(string userID, int balance, int status, int type) ret = dbm.Manager.addUser(userID, 0, status, type); // make Balance Table } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -324,7 +322,7 @@ public bool updateTransactionStatus(UUID transactionID, int status, string descr return dbm.Manager.updateTransactionStatus(transactionID, status, description); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -351,7 +349,7 @@ public bool SetTransExpired(int deadTime) return dbm.Manager.SetTransExpired(deadTime); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -378,7 +376,7 @@ public bool ValidateTransfer(string secureCode, UUID transactionID) return dbm.Manager.ValidateTransfer(secureCode, transactionID); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -405,7 +403,7 @@ public TransactionData FetchTransaction(UUID transactionID) return dbm.Manager.FetchTransaction(transactionID); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -436,7 +434,7 @@ public TransactionData FetchTransaction(string userID, int startTime, int endTim arrTransaction = dbm.Manager.FetchTransaction(userID, startTime, endTime, index, 1); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -585,7 +583,7 @@ public bool TryAddUserInfo(UserInfo user) userInfo = dbm.Manager.fetchUserInfo(user.UserID); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -636,7 +634,7 @@ public UserInfo FetchUserInfo(string userID) return userInfo; } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); @@ -664,7 +662,7 @@ public int getTransactionNum(string userID, int startTime, int endTime) return dbm.Manager.getTransactionNum(userID, startTime, endTime); } #pragma warning disable CS0168 // Variable ist deklariert, wird jedoch niemals verwendet - catch (MySql.Data.MySqlClient.MySqlException e) + catch (MySqlException e) { #pragma warning restore CS0168 // Variable ist deklariert, wird jedoch niemals verwendet dbm.Manager.Reconnect(); From 70a7ad07c98641cb9db01efc9fcf2e3e9c7f81b1 Mon Sep 17 00:00:00 2001 From: Michael Dickson Date: Wed, 5 Jul 2023 16:39:43 -0400 Subject: [PATCH 03/11] Additional changes in Region persistence to explicitely call ToString() with UUID rather than assume the database command handler will do it for you. This is a compatability issue with SqlConnector vs the Oracle connector. --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 54e846d2260..655bba8c102 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -784,7 +784,7 @@ public virtual RegionSettings LoadRegionSettings(UUID regionUUID) using (MySqlCommand cmd = dbcon.CreateCommand()) { cmd.CommandText = "select * from regionsettings where regionUUID = ?RegionUUID"; - cmd.Parameters.AddWithValue("regionUUID", regionUUID); + cmd.Parameters.AddWithValue("regionUUID", regionUUID.ToString()); using (IDataReader reader = ExecuteReader(cmd)) { @@ -1452,7 +1452,7 @@ private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneG cmd.Parameters.AddWithValue("CreationDate", prim.CreationDate); cmd.Parameters.AddWithValue("Name", prim.Name); cmd.Parameters.AddWithValue("SceneGroupID", sceneGroupID.ToString()); - // the UUID of the root part for this SceneObjectGroup + // the UUID of the root part for this SceneObjectGroup // various text fields cmd.Parameters.AddWithValue("Text", prim.Text); cmd.Parameters.AddWithValue("ColorR", prim.Color.R); @@ -1526,7 +1526,7 @@ private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneG } else { - cmd.Parameters.AddWithValue("LoopedSound", UUID.Zero); + cmd.Parameters.AddWithValue("LoopedSound", UUID.Zero.ToString()); cmd.Parameters.AddWithValue("LoopedSoundGain", 0.0f); } @@ -1629,10 +1629,10 @@ private void FillPrimCommand(MySqlCommand cmd, SceneObjectPart prim, UUID sceneG /// private static void FillItemCommand(MySqlCommand cmd, TaskInventoryItem taskItem) { - cmd.Parameters.AddWithValue("itemID", taskItem.ItemID); - cmd.Parameters.AddWithValue("primID", taskItem.ParentPartID); - cmd.Parameters.AddWithValue("assetID", taskItem.AssetID); - cmd.Parameters.AddWithValue("parentFolderID", taskItem.ParentID); + cmd.Parameters.AddWithValue("itemID", taskItem.ItemID.ToString()); + cmd.Parameters.AddWithValue("primID", taskItem.ParentPartID.ToString()); + cmd.Parameters.AddWithValue("assetID", taskItem.AssetID.ToString()); + cmd.Parameters.AddWithValue("parentFolderID", taskItem.ParentID.ToString()); cmd.Parameters.AddWithValue("invType", taskItem.InvType); cmd.Parameters.AddWithValue("assetType", taskItem.Type); @@ -1641,9 +1641,9 @@ private static void FillItemCommand(MySqlCommand cmd, TaskInventoryItem taskItem cmd.Parameters.AddWithValue("description", taskItem.Description); cmd.Parameters.AddWithValue("creationDate", taskItem.CreationDate); cmd.Parameters.AddWithValue("creatorID", taskItem.CreatorIdentification); - cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID); - cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID); - cmd.Parameters.AddWithValue("groupID", taskItem.GroupID); + cmd.Parameters.AddWithValue("ownerID", taskItem.OwnerID.ToString()); + cmd.Parameters.AddWithValue("lastOwnerID", taskItem.LastOwnerID.ToString()); + cmd.Parameters.AddWithValue("groupID", taskItem.GroupID.ToString()); cmd.Parameters.AddWithValue("nextPermissions", taskItem.NextPermissions); cmd.Parameters.AddWithValue("currentPermissions", taskItem.CurrentPermissions); cmd.Parameters.AddWithValue("basePermissions", taskItem.BasePermissions); @@ -1697,13 +1697,13 @@ private static void FillRegionSettingsCommand(MySqlCommand cmd, RegionSettings s cmd.Parameters.AddWithValue("CovenantChangedDateTime", settings.CovenantChangedDateTime); cmd.Parameters.AddWithValue("LoadedCreationDateTime", settings.LoadedCreationDateTime); cmd.Parameters.AddWithValue("LoadedCreationID", settings.LoadedCreationID); - cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID); + cmd.Parameters.AddWithValue("TerrainImageID", settings.TerrainImageID.ToString()); cmd.Parameters.AddWithValue("block_search", settings.GodBlockSearch); cmd.Parameters.AddWithValue("casino", settings.Casino); - cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID); - cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject); - cmd.Parameters.AddWithValue("cacheID", settings.CacheID); + cmd.Parameters.AddWithValue("ParcelImageID", settings.ParcelImageID.ToString()); + cmd.Parameters.AddWithValue("TelehubObject", settings.TelehubObject.ToString()); + cmd.Parameters.AddWithValue("cacheID", settings.CacheID.ToString()); } /// @@ -1748,7 +1748,7 @@ private static void FillLandCommand(MySqlCommand cmd, LandData land, UUID region cmd.Parameters.AddWithValue("UserLookAtX", land.UserLookAt.X); cmd.Parameters.AddWithValue("UserLookAtY", land.UserLookAt.Y); cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z); - cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID); + cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID.ToString()); cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime); cmd.Parameters.AddWithValue("Dwell", land.Dwell); cmd.Parameters.AddWithValue("MediaDescription", land.MediaDescription); From a39a4794bfd5f034cc7a08f3dc06018de6e040fc Mon Sep 17 00:00:00 2001 From: Michael Dickson Date: Thu, 6 Jul 2023 19:48:06 -0400 Subject: [PATCH 04/11] A few more cases of needing ToString() on an UUID for persistence, Found by inspection walking through each of the persistence modules. --- OpenSim/Data/MySQL/MySQLEstateData.cs | 6 +++--- OpenSim/Data/MySQL/MySQLFSAssetData.cs | 2 +- OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 3 +-- OpenSim/Data/MySQL/MySQLPresenceData.cs | 3 +-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs index 74c3d5744e3..6d5cfbc342b 100644 --- a/OpenSim/Data/MySQL/MySQLEstateData.cs +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs @@ -496,7 +496,7 @@ public List GetEstatesByOwner(UUID ownerID) using (MySqlCommand cmd = dbcon.CreateCommand()) { cmd.CommandText = "select estateID from estate_settings where EstateOwner = ?EstateOwner"; - cmd.Parameters.AddWithValue("?EstateOwner", ownerID); + cmd.Parameters.AddWithValue("?EstateOwner", ownerID.ToString()); using (IDataReader reader = cmd.ExecuteReader()) { @@ -528,7 +528,7 @@ public bool LinkRegion(UUID regionID, int estateID) { cmd.Transaction = transaction; cmd.CommandText = "delete from estate_map where RegionID = ?RegionID"; - cmd.Parameters.AddWithValue("?RegionID", regionID); + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); cmd.ExecuteNonQuery(); } @@ -537,7 +537,7 @@ public bool LinkRegion(UUID regionID, int estateID) { cmd.Transaction = transaction; cmd.CommandText = "insert into estate_map values (?RegionID, ?EstateID)"; - cmd.Parameters.AddWithValue("?RegionID", regionID); + cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); cmd.Parameters.AddWithValue("?EstateID", estateID); int ret = cmd.ExecuteNonQuery(); diff --git a/OpenSim/Data/MySQL/MySQLFSAssetData.cs b/OpenSim/Data/MySQL/MySQLFSAssetData.cs index 22872175fd9..b7c691b18d9 100644 --- a/OpenSim/Data/MySQL/MySQLFSAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLFSAssetData.cs @@ -255,7 +255,7 @@ public bool Store(AssetMetadata meta, string hash) catch(Exception e) { m_log.Error("[FSAssets] Failed to store asset with ID " + meta.ID); - m_log.Error(e.ToString()); + m_log.Error(e.ToString()); return false; } } diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 29b1b6aea3c..c907ae79058 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -107,8 +107,7 @@ private void CheckColumnNames(IDataReader reader) DataTable schemaTable = reader.GetSchemaTable(); foreach (DataRow row in schemaTable.Rows) { - if (row["ColumnName"] != null && - (!m_Fields.ContainsKey(row["ColumnName"].ToString()))) + if (row["ColumnName"] != null && (!m_Fields.ContainsKey(row["ColumnName"].ToString()))) columnNames.Add(row["ColumnName"].ToString()); } diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs index 758aea4ed2a..41c8a839743 100644 --- a/OpenSim/Data/MySQL/MySQLPresenceData.cs +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs @@ -46,8 +46,7 @@ public MySQLPresenceData(string connectionString, string realm) : public PresenceData Get(UUID sessionID) { - PresenceData[] ret = Get("SessionID", - sessionID.ToString()); + PresenceData[] ret = Get("SessionID", sessionID.ToString()); if (ret.Length == 0) return null; From e949d31e3fb93030e72dd4db5ee4d211af6210e5 Mon Sep 17 00:00:00 2001 From: Michael Dickson Date: Fri, 7 Jul 2023 12:00:36 -0400 Subject: [PATCH 05/11] Bump version number --- OpenSim/Framework/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index 03dc412fd33..fe69c58f8a8 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs @@ -33,7 +33,7 @@ public class VersionInfo { public const string VersionNumber = "0.9.2.2"; public const string AssemblyVersionNumber = "0.9.2.2"; - public const string Release = "8584"; + public const string Release = "8588"; public const Flavour VERSION_FLAVOUR = Flavour.Dev; From ff696e05275c0df44f394e43044b61562afb8248 Mon Sep 17 00:00:00 2001 From: Michael Dickson Date: Fri, 7 Jul 2023 17:21:04 -0400 Subject: [PATCH 06/11] One more database change. Add an options field for the MoneyServer connect string so we can add things like OldGuids=true --- .../OpenSim.Server.MoneyServer/MoneyServerBase.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/addon-modules/OpenSim.Server.MoneyServer/OpenSim.Server.MoneyServer/MoneyServerBase.cs b/addon-modules/OpenSim.Server.MoneyServer/OpenSim.Server.MoneyServer/MoneyServerBase.cs index 347e805effa..9cfeb761428 100644 --- a/addon-modules/OpenSim.Server.MoneyServer/OpenSim.Server.MoneyServer/MoneyServerBase.cs +++ b/addon-modules/OpenSim.Server.MoneyServer/OpenSim.Server.MoneyServer/MoneyServerBase.cs @@ -204,11 +204,18 @@ protected void ReadIniConfig() string password = db_config.GetString("password", "password"); string pooling = db_config.GetString("pooling", "false"); string port = db_config.GetString("port", "3306"); + string options = db_config.GetString("options", ""); + MAX_DB_CONNECTION = db_config.GetInt("MaxConnection", MAX_DB_CONNECTION); connectionString = "Server=" + sqlserver + ";Port=" + port + ";Database=" + database + ";User ID=" + username + ";Password=" + password + ";Pooling=" + pooling + ";"; + if (string.IsNullOrEmpty(options) == false) + { + connectionString += options; + } + // [MoneyServer] m_server_config = moneyConfig.m_config.Configs["MoneyServer"]; DEAD_TIME = m_server_config.GetInt("ExpiredTime", DEAD_TIME); From cd768396610baeaf8cbe55c7324441e769ca8f72 Mon Sep 17 00:00:00 2001 From: Michael Dickson Date: Thu, 13 Jul 2023 10:55:18 -0400 Subject: [PATCH 07/11] Missed a database update where UUID is used. Bumped Version --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 2 +- OpenSim/Framework/VersionInfo.cs | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 655bba8c102..0e6e1432327 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -858,7 +858,7 @@ public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) { cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)"; - cmd.Parameters.AddWithValue("region_id", regionUUID); + cmd.Parameters.AddWithValue("region_id", regionUUID.ToString()); cmd.Parameters.AddWithValue("llsd_settings", settings); ExecuteNonQuery(cmd); diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index fe69c58f8a8..8cbb3677dd2 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs @@ -1,4 +1,10 @@ -/* + + + + + + +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -33,7 +39,7 @@ public class VersionInfo { public const string VersionNumber = "0.9.2.2"; public const string AssemblyVersionNumber = "0.9.2.2"; - public const string Release = "8588"; + public const string Release = "8593"; public const Flavour VERSION_FLAVOUR = Flavour.Dev; From 4a1122eb137628860426aae3ee1eed1dc1f9b320 Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Thu, 20 Jul 2023 13:10:32 -0400 Subject: [PATCH 08/11] Rework the Gloebit startup logic so its consistent with the other money modules and allows more than one money module to be present. This will short-circuit some startup actions if the Gloebit module is not configured which is really more correct anyway. It shouldn't be trying to start at all in that case. --- OpenSim/Framework/VersionInfo.cs | 2 +- .../World/MoneyModule/SampleMoneyModule.cs | 19 +- .../GloebitMoneyModule/GloebitMoneyModule.cs | 398 +++++++++--------- 3 files changed, 192 insertions(+), 227 deletions(-) diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index 8cbb3677dd2..3d90555f842 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs @@ -39,7 +39,7 @@ public class VersionInfo { public const string VersionNumber = "0.9.2.2"; public const string AssemblyVersionNumber = "0.9.2.2"; - public const string Release = "8593"; + public const string Release = "8600"; public const Flavour VERSION_FLAVOUR = Flavour.Dev; diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index 9e3e358e906..30312b4c3b6 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs @@ -253,24 +253,11 @@ private void ReadConfigAndPopulate() { // we are enabled by default - IConfig startupConfig = m_gConfig.Configs["Startup"]; - - if(startupConfig == null) // should not happen - return; - IConfig economyConfig = m_gConfig.Configs["Economy"]; - // economymodule may be at startup or Economy (legacy) - string mmodule = startupConfig.GetString("economymodule",""); - if(string.IsNullOrEmpty(mmodule)) - { - if(economyConfig != null) - { - mmodule = economyConfig.GetString("economymodule", ""); - if (String.IsNullOrEmpty(mmodule)) - mmodule = economyConfig.GetString("EconomyModule", ""); - } - } + var mmodule = economyConfig?.GetString("economymodule", ""); + if (String.IsNullOrEmpty(mmodule)) + mmodule = economyConfig?.GetString("EconomyModule", ""); if (!string.IsNullOrEmpty(mmodule) && mmodule != Name) { diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs index c7259351a6d..796f4542d35 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs @@ -6,7 +6,7 @@ * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * OpenSim-MoneyModule-Gloebit is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -69,7 +69,6 @@ using System.Collections; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net; using System.Reflection; using System.Threading; @@ -84,7 +83,6 @@ using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.OptionalModules.ViewerSupport; // Necessary for SimulatorFeaturesHelper using OpenSim.Services.Interfaces; using OpenMetaverse.StructuredData; // TODO: turn transactionData into a dictionary of and remove this. using OpenSim.Region.ScriptEngine.Shared.ScriptBase; // For ScriptBaseClass permissions constants @@ -117,29 +115,16 @@ public class GloebitMoneyModule : IMoneyModule, ISharedRegionModule, GloebitTran { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - /*** GMM CONFIGURATION ***/ - private IConfigSource m_gConfig; // TODO: Consider moving these into the GAPI // Gloebit Service URLs private const string SANDBOX_URL = "https://sandbox.gloebit.com/"; private const string PRODUCTION_URL = "https://www.gloebit.com/"; - // populated from Startup and Economy - private string m_startupEconomyModule; - private string m_economyEconomyModule; - // m_enabled = true signifies that GMM is enabled across entire sim process - // Combination of [Economy]/[Startup] EconomyModule set to "Gloebit" and [Gloebit] Enabled set to true - // If false, may still be enabled on individual regions. see m_enabledRegions below. + // Combination of [Economy]/[Startup] EconomyModule set to "GloebitMoneyModule" and [Gloebit] Enabled set to true private bool m_enabled = true; - // Set to false if anything is misconfigured - private bool m_configured = true; - - // Populated from Gloebit.ini - private UUID[] m_enabledRegions = null; // Regions on sim to individually enable GMM. - // Only necessary if m_enabled is false + private GLBEnv m_environment = GLBEnv.None; private string m_keyAlias; private string m_key; @@ -208,7 +193,6 @@ public class GloebitMoneyModule : IMoneyModule, ISharedRegionModule, GloebitTran private bool m_newLandPassFlow = false; private bool m_newHTTPFlow = false; - #region IRegionModuleBase Interface /********************** @@ -218,11 +202,13 @@ public class GloebitMoneyModule : IMoneyModule, ISharedRegionModule, GloebitTran * --- registering Scene events for enabled regions to handle user management and commerce functionality **********************/ - public string Name { + public string Name + { get { return "GloebitMoneyModule"; } } - public Type ReplaceableInterface { + public Type ReplaceableInterface + { get { return null; } } @@ -233,66 +219,97 @@ public Type ReplaceableInterface { public void Initialise(IConfigSource config) { m_log.Info ("[GLOEBITMONEYMODULE] Initialising."); - m_gConfig = config; - LoadConfig(m_gConfig); + IConfig economyConfig = config.Configs["Economy"]; - string[] sections = {"Startup", "Economy", "Gloebit"}; - foreach (string section in sections) { - IConfig sec_config = m_gConfig.Configs[section]; + var mmodule = economyConfig?.GetString("economymodule", ""); + if (String.IsNullOrEmpty(mmodule)) + mmodule = economyConfig?.GetString("EconomyModule", ""); - if (null == sec_config) { + if ((string.IsNullOrEmpty(mmodule) == false) && ((mmodule == Name) || (mmodule == "Gloebit"))) + { + m_enabled = true; + } + else + { + // some other money module selected + m_enabled = false; + return; + } + + LoadConfig(config); + + string[] sections = { "Economy", "Gloebit" }; + foreach (var section in sections) + { + IConfig sec_config = config.Configs[section]; + + if (null == sec_config) + { m_log.WarnFormat("[GLOEBITMONEYMODULE] Config section {0} is missing. Skipping.", section); continue; } + ReadConfigAndPopulate(sec_config, section); } // Load Grid info from GridInfoService if Standalone and GridInfo if Robust - IConfig standalone_config = m_gConfig.Configs["GridInfoService"]; - IConfig robust_config = m_gConfig.Configs["GridInfo"]; - if (standalone_config == null && robust_config == null) { + IConfig standalone_config = config.Configs["GridInfoService"]; + IConfig robust_config = config.Configs["GridInfo"]; + + if (standalone_config == null && robust_config == null) + { m_log.Warn("[GLOEBITMONEYMODULE] GridInfoService and GridInfo are both missing. Can not retrieve GridInfoURI, GridName and GridNick."); // NOTE: we can continue and enable as this will just cause transaction history records to be missing some data. - } else { - if(standalone_config != null && robust_config != null) { + } + else + { + if (standalone_config != null && robust_config != null) + { m_log.Warn("[GLOEBITMONEYMODULE] GridInfoService and GridInfo are both present. Deferring to GridInfo to retrieve GridInfoURI, GridName and GridNick."); } - if (robust_config != null) { + + if (robust_config != null) + { ReadConfigAndPopulate(robust_config, "GridInfo"); - } else { + } + else + { ReadConfigAndPopulate(standalone_config, "GridInfoService"); } } - m_log.InfoFormat("[GLOEBITMONEYMODULE] Initialised. Gloebit enabled: {0}, GLBEnvironment: {1}, GLBApiUrl: {2} GLBKeyAlias {3}, GLBKey: {4}, GLBSecret {5}", m_enabled, m_environment, m_apiUrl, m_keyAlias, m_key, (m_secret == null ? "null" : "configured")); // TODO: I've added GLBEnv.Custom for testing. Remove before we ship - if(m_environment != GLBEnv.Sandbox && m_environment != GLBEnv.Production && m_environment != GLBEnv.Custom) { + if (m_environment != GLBEnv.Sandbox && m_environment != GLBEnv.Production && m_environment != GLBEnv.Custom) + { m_log.ErrorFormat("[GLOEBITMONEYMODULE] Unsupported environment selected: {0}, disabling GloebitMoneyModule", m_environment); m_enabled = false; - m_configured = false; } - if (String.IsNullOrEmpty(m_dbProvider)) { + if (String.IsNullOrEmpty(m_dbProvider)) + { // GLBSpecificStorageProvider wasn't specified so fall back to using the global // DatabaseService settings m_log.Info("[GLOEBITMONEYMODULE] using default StorageProvider and ConnectionString from DatabaseService"); - m_dbProvider = m_gConfig.Configs["DatabaseService"].GetString("StorageProvider"); - m_dbConnectionString = m_gConfig.Configs["DatabaseService"].GetString("ConnectionString"); - } else { + m_dbProvider = config.Configs["DatabaseService"].GetString("StorageProvider"); + m_dbConnectionString = config.Configs["DatabaseService"].GetString("ConnectionString"); + } + else + { m_log.Info("[GLOEBITMONEYMODULE] using GLBSpecificStorageProvider and GLBSpecificConnectionString"); } - if(String.IsNullOrEmpty(m_dbProvider) || String.IsNullOrEmpty(m_dbConnectionString)) { + if (String.IsNullOrEmpty(m_dbProvider) || String.IsNullOrEmpty(m_dbConnectionString)) + { m_log.Error("[GLOEBITMONEYMODULE] database connection misconfigured, disabling GloebitMoneyModule"); m_enabled = false; - m_configured = false; } - if(m_configured) { + if (m_enabled == true) + { InitGloebitAPI(); } } @@ -306,11 +323,13 @@ private void LoadConfig(IConfigSource config) string configPath = string.Empty; bool created; string assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + if (!Util.MergeConfigurationFile(config, "Gloebit.ini", Path.Combine(assemblyDirectory, "Gloebit.ini.example"), out configPath, out created)) { m_log.WarnFormat("[GLOEBITMONEYMODULE]: Gloebit.ini configuration file not merged"); return; } + if (created) { m_log.ErrorFormat("[GLOEBITMONEYMODULE]: PLEASE EDIT {0} BEFORE RUNNING THIS ADDIN", configPath); @@ -325,17 +344,9 @@ private void LoadConfig(IConfigSource config) /// private void ReadConfigAndPopulate(IConfig config, string section) { - /********** [Startup] ************/ - if (section == "Startup") { - m_startupEconomyModule = config.GetString("EconomyModule", String.Empty); - m_log.InfoFormat("[GLOEBITMONEYMODULE] Startup EconomyModule = {0}.", m_startupEconomyModule); - } - /********** [Economy] ************/ - if (section == "Economy") { - m_economyEconomyModule = config.GetString("EconomyModule", String.Empty); - m_log.InfoFormat("[GLOEBITMONEYMODULE] Economy EconomyModule = {0}.", m_economyEconomyModule); - + if (section == "Economy") + { /*** Get OpenSim built in pricing configuration info ***/ PriceEnergyUnit = config.GetInt("PriceEnergyUnit", 100); PriceObjectClaim = config.GetInt("PriceObjectClaim", 10); @@ -356,96 +367,47 @@ private void ReadConfigAndPopulate(IConfig config, string section) } /********** [Gloebit] ************/ - if (section == "Gloebit") { - /*** Determine what the sim EconomyModule setting is ***/ - // Original standard is to be in the Startup section. New standard is to be in Economy section. Need to check both. - // Two money modules should never be enabled on the same region as they'll conflict. - // If all respect this param then this can't happen across the entire sim process. - // Unfortunately, this does not handle per-region configuration on a multi-region sim. - // Gloebit for instance allows enabling by region if not enabled globally, - // but many other money modules can not be enabled/disabled by region. - string economyModule; - if (String.IsNullOrEmpty(m_startupEconomyModule) && String.IsNullOrEmpty(m_economyEconomyModule)) { - m_log.Warn("[GLOEBITMONEYMODULE] no sim-wide EconomyModule is set. Defaulting to Gloebit since dll is present."); - economyModule = "Gloebit"; - } else if (!String.IsNullOrEmpty(m_startupEconomyModule) && !String.IsNullOrEmpty(m_economyEconomyModule)) { - m_log.Warn("[GLOEBITMONEYMODULE] EconomyModule is set in 2 places. Should only be defined once."); - if (m_startupEconomyModule != m_economyEconomyModule) { - m_log.Error("[GLOEBITMONEYMODULE] EconomyModule in [Startup] does not match setting in [Economy]. Sim-wide setting is undefined."); - economyModule = String.Empty; - } else { - m_log.InfoFormat("[GLOEBITMONEYMODULE] EconomyModule settings match as {0}", m_startupEconomyModule); - economyModule = m_startupEconomyModule; - } - } else if (!String.IsNullOrEmpty(m_startupEconomyModule)) { - m_log.InfoFormat("[GLOEBITMONEYMODULE] EconomyModule is {0}.", m_startupEconomyModule); - economyModule = m_startupEconomyModule; - } else { - m_log.InfoFormat("[GLOEBITMONEYMODULE] EconomyModule is {0}.", m_economyEconomyModule); - economyModule = m_economyEconomyModule; - } - - if (economyModule == "Gloebit") { - m_log.Info("[GLOEBITMONEYMODULE] selected as global sim EconomyModule."); - m_enabled = true; - } else { - m_log.Info("[GLOEBITMONEYMODULE] not selected as global sim EconomyModule."); - m_enabled = false; - } - + if (section == "Gloebit") + { /*** Get GloebitMoneyModule configuration details ***/ - // Is Gloebit disabled, enabled across the entire sim process, or on certain regions? - bool enabled = config.GetBoolean("Enabled", false); - m_log.InfoFormat("[GLOEBITMONEYMODULE] [Gloebit] Enabled flag set to {0}.", enabled); - m_enabled = m_enabled && enabled; - if (!m_enabled) { - m_log.Info("[GLOEBITMONEYMODULE] Not enabled globally for sim. (to enable set \"Enabled = true\" in [Gloebit] and \"EconomyModule = Gloebit\" in [Economy])"); - } - string enabledRegionIdsStr = config.GetString("GLBEnabledOnlyInRegions"); - if(!String.IsNullOrEmpty(enabledRegionIdsStr)) { - // null for the delimiter argument means split on whitespace - string[] enabledRegionIds = enabledRegionIdsStr.Split((string[])null, StringSplitOptions.RemoveEmptyEntries); - int numRegions = enabledRegionIds.Length; - m_log.InfoFormat("[GLOEBITMONEYMODULE] GLBEnabledOnlyInRegions num regions: {0}", numRegions); - m_enabledRegions = new UUID[numRegions]; - for(int i = 0; i < numRegions; i++) { - m_enabledRegions[i] = UUID.Parse(enabledRegionIds[i]); - m_log.InfoFormat("[GLOEBITMONEYMODULE] selected as local EconomyModule for region {0}", enabledRegionIds[i]); - } - if ((numRegions > 0) && (economyModule != "Gloebit")) { - m_log.WarnFormat("[GLOEBITMONEYMODULE] Gloebit enabled by region on sim with global EconomyModule set to {0}. Ensure that sim-wide EconomyModule is disabled in Gloebit enabled regions.", economyModule); - } - } // Get region/grid owner contact details for transaction failure contact instructions. string ownerName = config.GetString("GLBOwnerName", "region or grid owner"); string ownerEmail = config.GetString("GLBOwnerEmail", null); m_contactOwner = ownerName; - if (!String.IsNullOrEmpty(ownerEmail)) { + if (!String.IsNullOrEmpty(ownerEmail)) + { m_contactOwner = String.Format("{0} at {1}", ownerName, ownerEmail); } + // Should we disable adding info to OpenSimExtras map m_disablePerSimCurrencyExtras = config.GetBoolean("DisablePerSimCurrencyExtras", false); + // Should we send new session IMs informing user how to auth or purchase gloebits m_showNewSessionPurchaseIM = config.GetBoolean("GLBShowNewSessionPurchaseIM", false); m_showNewSessionAuthIM = config.GetBoolean("GLBShowNewSessionAuthIM", true); + // Should we send a welcome message informing user that Gloebit is enabled m_showWelcomeMessage = config.GetBoolean("GLBShowWelcomeMessage", true); string nsms_msg = "\n\t"; nsms_msg = String.Format("{0}Welcome Message: {1},\tTo modify, set GLBShowWelcomeMessage in [Gloebit] section of config\n\t", nsms_msg, m_showWelcomeMessage); nsms_msg = String.Format("{0}Auth Message: {1},\tTo modify, set GLBShowNewSessionAuthIM in [Gloebit] section of config\n\t", nsms_msg, m_showNewSessionAuthIM); nsms_msg = String.Format("{0}Purchase Message: {1},\tTo modify, set GLBShowNewSessionPurchaseIM in [Gloebit] section of config", nsms_msg, m_showNewSessionPurchaseIM); + m_log.InfoFormat("[GLOEBITMONEYMODULE] [Gloebit] is configured with the following settings for messaging users connecting to a new session{0}", nsms_msg); + // If version cannot be detected override workflow selection via config // Currently not documented because last resort if all version checking fails m_forceNewLandPassFlow = config.GetBoolean("GLBNewLandPassFlow", false); m_forceNewHTTPFlow = config.GetBoolean("GLBNewHTTPFlow", false); + // Are we using custom db connection info m_dbProvider = config.GetString("GLBSpecificStorageProvider"); m_dbConnectionString = config.GetString("GLBSpecificConnectionString"); /*** Get Gloebit API configuration details ***/ string envString = config.GetString("GLBEnvironment", "sandbox"); - switch(envString) { + switch(envString) + { case "sandbox": m_environment = GLBEnv.Sandbox; m_apiUrl = SANDBOX_URL; @@ -469,40 +431,50 @@ private void ReadConfigAndPopulate(IConfig config, string section) m_log.WarnFormat("[GLOEBITMONEYMODULE] GLBEnvironment \"{0}\" unrecognized, setting to None", envString); break; } + m_keyAlias = config.GetString("GLBKeyAlias", null); m_key = config.GetString("GLBKey", null); m_secret = config.GetString("GLBSecret", null); } /********** [GridInfoService] ************/ - if (section == "GridInfoService") { + if (section == "GridInfoService") + { // If we're here, this is a standalone mode grid /*** Grab the grid info locally ***/ setGridInfo(config.GetString("gridname", m_gridname), config.GetString("gridnick", m_gridnick), config.GetString("economy", null)); } /********** [GridInfo] ************/ - if (section == "GridInfo") { + if (section == "GridInfo") + { // If we're here, this is a robust mode grid /*** Grab the grid info via the grid info uri ***/ string gridInfoURI = config.GetString("GridInfoURI", null); // TODO: Should we store the info url? m_log.InfoFormat("[GLOEBITMONEYMODULE] GRID INFO URL = {0}", gridInfoURI); - if (String.IsNullOrEmpty(gridInfoURI)) { + + if (String.IsNullOrEmpty(gridInfoURI)) + { m_log.ErrorFormat("[GloebitMoneyModule] Failed to retrieve GridInfoURI from [GridInfo] section of config."); return; } + // Create http web request from URL Uri requestURI = new Uri(new Uri(gridInfoURI), "json_grid_info"); m_log.InfoFormat("[GLOEBITMONEYMODULE] Constructed and requesting URI = {0}", requestURI); + HttpWebRequest request = (HttpWebRequest) WebRequest.Create(requestURI); request.Method = "GET"; - try { + try + { // Get the response HttpWebResponse response = (HttpWebResponse) request.GetResponse(); string status = response.StatusDescription; m_log.InfoFormat("[GLOEBITMONEYMODULE] Grid Info status:{0}", status); - using(StreamReader response_stream = new StreamReader(response.GetResponseStream())) { + + using(StreamReader response_stream = new StreamReader(response.GetResponseStream())) + { string response_str = response_stream.ReadToEnd(); m_log.InfoFormat("[GLOEBITMONEYMODULE] Grid Info:{0}", response_str); // Parse the response @@ -511,7 +483,9 @@ private void ReadConfigAndPopulate(IConfig config, string section) setGridInfo(responseData["gridname"], responseData["gridnick"], responseData["economy"]); // TODO: do we want anything else from grid info? } - } catch (Exception e) { + } + catch (Exception e) + { m_log.ErrorFormat("[GloebitMoneyModule] Failed to retrieve Grid Info. {0}", e); } } @@ -543,7 +517,6 @@ private void setGridInfo(string gridName, string gridNick, string ecoUrl) { public void Close() { m_enabled = false; - m_configured = false; } // Helper funciton used in AddRegion for post 0.9.2.0 XML RPC Handlers @@ -556,95 +529,93 @@ public void processPHP(IOSHttpRequest request, IOSHttpResponse response) public void AddRegion(Scene scene) { - if(!m_configured) { + if (m_enabled == false) + { return; } - if (m_enabled || (m_enabledRegions != null && m_enabledRegions.Contains(scene.RegionInfo.RegionID))) - { - m_log.InfoFormat("[GLOEBITMONEYMODULE] region added {0}", scene.RegionInfo.RegionID.ToString()); - scene.RegisterModuleInterface(this); - IHttpServer httpServer = MainServer.Instance; + m_log.InfoFormat("[GLOEBITMONEYMODULE] region added {0}", scene.RegionInfo.RegionID.ToString()); + scene.RegisterModuleInterface(this); + IHttpServer httpServer = MainServer.Instance; - lock (m_scenel) + lock (m_scenel) + { + // TODO: What happens if all regions are removed and one is re-created without a sim restart? + // Should we use a bool instead of the count here? + if (m_scenel.Count == 0) { - // TODO: What happens if all regions are removed and one is re-created without a sim restart? - // Should we use a bool instead of the count here? - if (m_scenel.Count == 0) + /* + * For land sales, buy-currency button, and the insufficient funds flows to operate, + * the economy helper uri needs to be present. + * + * The GMM provides this helper-uri and the currency symbol via the OpenSim Extras. + * Some viewers (Firestorm & Alchemy at time of writing) consume these so this requires no + * configuration to work for a user on a Gloebit enabled region. For users with other or older viewers, + * the helper-uri will have to be configured properly, and if not pointed at a Gloebit enabled sim, + * the grid will have to handle these calls, which it has traditionally done with an XMLRPC server and + * currency.php and landtool.php helper scripts. That is rather complex, so we recommend that all + * viewers adopt this patch and that grids request that their users update to a viewer with this patch. + * --- Patch Info: http://dev.gloebit.com/blog/Upgrade-Viewer/ + * --- Patch Info: https://medium.com/@colosi/multi-currency-support-coming-to-opensim-viewers-cd20e75f7990 + * --- Patch Download: http://dev.gloebit.com/opensim/downloads/ColosiOpenSimMultiCurrencySupport.patch + * --- Firestorm Jira: https://jira.phoenixviewer.com/browse/FIRE-21587 + */ + + // These functions can handle the calls to the economy helper-uri if it is configured to point at the sim. + // They will enable land purchasing, buy-currency, and insufficient-funds flows. + // *NOTE* gloebits can not currently be purchased from a viewer, but this allows Gloebit to control the + // messaging in this flow and send users to the Gloebit website for purchasing. + + // Post version 0.9.2.0 the httpserver changed requiring different approach to the preflights + if (m_newHTTPFlow == true) { - /* - * For land sales, buy-currency button, and the insufficient funds flows to operate, - * the economy helper uri needs to be present. - * - * The GMM provides this helper-uri and the currency symbol via the OpenSim Extras. - * Some viewers (Firestorm & Alchemy at time of writing) consume these so this requires no - * configuration to work for a user on a Gloebit enabled region. For users with other or older viewers, - * the helper-uri will have to be configured properly, and if not pointed at a Gloebit enabled sim, - * the grid will have to handle these calls, which it has traditionally done with an XMLRPC server and - * currency.php and landtool.php helper scripts. That is rather complex, so we recommend that all - * viewers adopt this patch and that grids request that their users update to a viewer with this patch. - * --- Patch Info: http://dev.gloebit.com/blog/Upgrade-Viewer/ - * --- Patch Info: https://medium.com/@colosi/multi-currency-support-coming-to-opensim-viewers-cd20e75f7990 - * --- Patch Download: http://dev.gloebit.com/opensim/downloads/ColosiOpenSimMultiCurrencySupport.patch - * --- Firestorm Jira: https://jira.phoenixviewer.com/browse/FIRE-21587 - */ - - // These functions can handle the calls to the economy helper-uri if it is configured to point at the sim. - // They will enable land purchasing, buy-currency, and insufficient-funds flows. - // *NOTE* gloebits can not currently be purchased from a viewer, but this allows Gloebit to control the - // messaging in this flow and send users to the Gloebit website for purchasing. - - // Post version 0.9.2.0 the httpserver changed requiring different approach to the preflights - if (m_newHTTPFlow == true) - { - m_rpcHandlers = new Dictionary(); - m_rpcHandlers.Add("getCurrencyQuote", quote_func); - m_rpcHandlers.Add("buyCurrency", buy_func); - m_rpcHandlers.Add("preflightBuyLandPrep", preflightBuyLandPrep_func); - m_rpcHandlers.Add("buyLandPrep", landBuy_func); + m_rpcHandlers = new Dictionary(); + m_rpcHandlers.Add("getCurrencyQuote", quote_func); + m_rpcHandlers.Add("buyCurrency", buy_func); + m_rpcHandlers.Add("preflightBuyLandPrep", preflightBuyLandPrep_func); + m_rpcHandlers.Add("buyLandPrep", landBuy_func); #if NEWHTTPFLOW - MainServer.Instance.AddSimpleStreamHandler(new SimpleStreamHandler("/landtool.php", processPHP)); - MainServer.Instance.AddSimpleStreamHandler(new SimpleStreamHandler("/currency.php", processPHP)); + MainServer.Instance.AddSimpleStreamHandler(new SimpleStreamHandler("/landtool.php", processPHP)); + MainServer.Instance.AddSimpleStreamHandler(new SimpleStreamHandler("/currency.php", processPHP)); #endif - } else { - httpServer.AddXmlRPCHandler("getCurrencyQuote", quote_func); - httpServer.AddXmlRPCHandler("buyCurrency", buy_func); - httpServer.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func); - httpServer.AddXmlRPCHandler("buyLandPrep", landBuy_func); - } - - /********** Register endpoints the Gloebit Service will call back into **********/ - RegisterGloebitWebhooks(httpServer); + } else { + httpServer.AddXmlRPCHandler("getCurrencyQuote", quote_func); + httpServer.AddXmlRPCHandler("buyCurrency", buy_func); + httpServer.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func); + httpServer.AddXmlRPCHandler("buyLandPrep", landBuy_func); } - if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle)) - { - m_scenel[scene.RegionInfo.RegionHandle] = scene; - } - else - { - m_scenel.Add(scene.RegionInfo.RegionHandle, scene); - } + /********** Register endpoints the Gloebit Service will call back into **********/ + RegisterGloebitWebhooks(httpServer); } - // Register for events for user management - scene.EventManager.OnNewClient += OnNewClient; // Registers client events - scene.EventManager.OnClientLogin += OnClientLogin; // Handles a login issue - - // Register for commerce events that come through scene - scene.EventManager.OnMoneyTransfer += OnMoneyTransfer; // Handles 5001 (pay user) & 5008 (pay object) events - scene.EventManager.OnValidateLandBuy += ValidateLandBuy; // Handles validation for free land transactions - scene.EventManager.OnLandBuy += ProcessLandBuy; // Handles land purchases - - } else { - if(m_enabledRegions != null) { - m_log.InfoFormat("[GLOEBITMONEYMODULE] SKIPPING region add {0} is not in enabled region list", scene.RegionInfo.RegionID.ToString()); + if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle)) + { + m_scenel[scene.RegionInfo.RegionHandle] = scene; + } + else + { + m_scenel.Add(scene.RegionInfo.RegionHandle, scene); } } + + // Register for events for user management + scene.EventManager.OnNewClient += OnNewClient; // Registers client events + scene.EventManager.OnClientLogin += OnClientLogin; // Handles a login issue + + // Register for commerce events that come through scene + scene.EventManager.OnMoneyTransfer += OnMoneyTransfer; // Handles 5001 (pay user) & 5008 (pay object) events + scene.EventManager.OnValidateLandBuy += ValidateLandBuy; // Handles validation for free land transactions + scene.EventManager.OnLandBuy += ProcessLandBuy; // Handles land purchases } public void RemoveRegion(Scene scene) { + if (m_enabled == false) + { + return; + } + lock (m_scenel) { m_scenel.Remove(scene.RegionInfo.RegionHandle); @@ -653,10 +624,11 @@ public void RemoveRegion(Scene scene) public void RegionLoaded(Scene scene) { - if (!m_enabled && (m_enabledRegions == null || !m_enabledRegions.Contains(scene.RegionInfo.RegionID))) { - m_log.InfoFormat("[GLOEBITMONEYMODULE] region not loaded as not enabled {0}", scene.RegionInfo.RegionID.ToString()); + if (m_enabled == false) + { return; } + m_log.InfoFormat("[GLOEBITMONEYMODULE] region loaded {0}", scene.RegionInfo.RegionID.ToString()); ISimulatorFeaturesModule featuresModule = scene.RequestModuleInterface(); @@ -668,26 +640,32 @@ public void RegionLoaded(Scene scene) private void OnSimulatorFeaturesRequest(UUID agentID, ref OSDMap features, Scene scene) { + if (m_enabled == false) + { + return; + } + UUID regionID = scene.RegionInfo.RegionID; - if (m_enabled || (m_enabledRegions != null && m_enabledRegions.Contains(regionID))) { - // Get or create the extras section of the features map - OSDMap extrasMap; - if (features.ContainsKey("OpenSimExtras")) { - extrasMap = (OSDMap)features["OpenSimExtras"]; - } else { - extrasMap = new OSDMap(); - features["OpenSimExtras"] = extrasMap; - } - - // Add our values to the extras map - extrasMap["currency"] = "G$"; - // replaced G$ with ₲ (hex 0x20B2 / unicode U+20B2), but screwed up balance display in Firestorm - extrasMap["currency-base-uri"] = GetCurrencyBaseURI(scene); + // Get or create the extras section of the features map + OSDMap extrasMap; + if (features.ContainsKey("OpenSimExtras")) + { + extrasMap = (OSDMap)features["OpenSimExtras"]; + } + else + { + extrasMap = new OSDMap(); + features["OpenSimExtras"] = extrasMap; } + + // Add our values to the extras map + extrasMap["currency"] = "G$"; + extrasMap["currency-base-uri"] = GetCurrencyBaseURI(scene); } - private string GetCurrencyBaseURI(Scene scene) { + private string GetCurrencyBaseURI(Scene scene) + { return scene.RegionInfo.ServerURI; } From a2eb2d8d9756cdc25052376c2680057e935a9081 Mon Sep 17 00:00:00 2001 From: Michael Dickson Date: Fri, 21 Jul 2023 12:48:16 -0400 Subject: [PATCH 09/11] Add a log message on intiialization indicating wether the Gloebit Noney Module is enabled or disabled. Debug Aid. --- addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs index 796f4542d35..af48cb8e094 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs @@ -229,10 +229,11 @@ public void Initialise(IConfigSource config) if ((string.IsNullOrEmpty(mmodule) == false) && ((mmodule == Name) || (mmodule == "Gloebit"))) { m_enabled = true; + m_log.InfoFormat("[GLOEBITMONEYMODULE]: The Gloebit MoneyModule is enabled"); } else { - // some other money module selected + m_log.InfoFormat("[GLOEBITMONEYMODULE]: The Gloebit MoneyModule is disabled (not selected in OpenSim.ini)"); m_enabled = false; return; } From 98413d7d7b0acae70a750d0dec36136fab1d50f7 Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Sat, 22 Jul 2023 16:35:40 -0400 Subject: [PATCH 10/11] Bump version to 8603 --- OpenSim/Framework/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index 3d90555f842..7cd61a4c25e 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs @@ -39,7 +39,7 @@ public class VersionInfo { public const string VersionNumber = "0.9.2.2"; public const string AssemblyVersionNumber = "0.9.2.2"; - public const string Release = "8600"; + public const string Release = "8603"; public const Flavour VERSION_FLAVOUR = Flavour.Dev; From 089c82f671db5f032d02b7e1778066a5a4c5ccc8 Mon Sep 17 00:00:00 2001 From: Mike Dickson Date: Thu, 3 Aug 2023 14:33:56 -0400 Subject: [PATCH 11/11] Rework Gloebit Subscriptions and Transactions to use the native database type (strings) for ID based entries instead of UUIDs. You can't hand a UUID to the database layer because it doesnt know how to convert it (or if it should). This means the MoneyModule is doing some conversions to/from UUIDs using ToString and UUID.Parse when persisting data but that actually correct unless we revise the database types to use a MySQL Guid (in which case we would have to convert to that). Bumped Build Version to 8615. --- OpenSim/Framework/VersionInfo.cs | 2 +- .../Gloebit/GloebitMoneyModule/GloebitAPI.cs | 17 +- .../GloebitMoneyModule/GloebitAPIWrapper.cs | 64 ++- .../GloebitMoneyModule/GloebitMoneyModule.cs | 429 +++++++++++++----- .../GloebitMoneyModule/GloebitSubscription.cs | 22 +- .../GloebitMoneyModule/GloebitTransaction.cs | 57 ++- 6 files changed, 450 insertions(+), 141 deletions(-) diff --git a/OpenSim/Framework/VersionInfo.cs b/OpenSim/Framework/VersionInfo.cs index 7cd61a4c25e..38bfeae6a4d 100644 --- a/OpenSim/Framework/VersionInfo.cs +++ b/OpenSim/Framework/VersionInfo.cs @@ -39,7 +39,7 @@ public class VersionInfo { public const string VersionNumber = "0.9.2.2"; public const string AssemblyVersionNumber = "0.9.2.2"; - public const string Release = "8603"; + public const string Release = "8615"; public const Flavour VERSION_FLAVOUR = Flavour.Dev; diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitAPI.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitAPI.cs index 7109fb9265f..e7da369f190 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitAPI.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitAPI.cs @@ -836,8 +836,8 @@ public bool CreateSubscription(GloebitSubscription subscription, Uri baseURI) { m_log.DebugFormat("[GLOEBITMONEYMODULE] GloebitAPI.CreateSubscription about to BeginGetResponse"); // **** Asynchronously make web request **** // IAsyncResult r = request.BeginGetResponse(GloebitWebResponseCallback, - new GloebitRequestState(request, - delegate(OSDMap responseDataMap) { + new GloebitRequestState(request, delegate(OSDMap responseDataMap) + { m_log.DebugFormat("[GLOEBITMONEYMODULE] GloebitAPI.CreateSubscription response: {0}", responseDataMap); @@ -849,16 +849,21 @@ public bool CreateSubscription(GloebitSubscription subscription, Uri baseURI) { string status = responseDataMap["status"]; m_log.InfoFormat("[GLOEBITMONEYMODULE] GloebitAPI.CreateSubscription success: {0} reason: {1} status: {2}", success, reason, status); - if (success) { + if (success) + { string subscriptionIDStr = responseDataMap["id"]; bool enabled = (bool) responseDataMap["enabled"]; - subscription.SubscriptionID = UUID.Parse(subscriptionIDStr); + subscription.SubscriptionID = subscriptionIDStr; subscription.Enabled = enabled; GloebitSubscriptionData.Instance.UpdateFromGloebit(subscription); - if (status == "duplicate") { + + if (status == "duplicate") + { m_log.DebugFormat("[GLOEBITMONEYMODULE] GloebitAPI.CreateSubscription duplicate request to create subscription"); } - } else { + } + else + { switch(reason) { case "Unexpected DB insert integrity error. Please try again.": m_log.ErrorFormat("[GLOEBITMONEYMODULE] GloebitAPI.CreateSubscription failed from {0}", reason); diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitAPIWrapper.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitAPIWrapper.cs index 3f2c47dece5..c741ecbd02e 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitAPIWrapper.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitAPIWrapper.cs @@ -433,9 +433,19 @@ public bool SubmitTransaction(GloebitTransaction txn, string description, OSDMap // TODO: Should we wrap TransactU2U or request.BeginGetResponse in Try/Catch? bool result = false; - if (u2u) { - result = m_api.TransactU2U(txn, description, descMap, GloebitUser.Get(m_key, txn.PayerID), GloebitUser.Get(m_key, txn.PayeeID), m_platformAccessors.resolveAgentEmail(txn.PayeeID), m_platformAccessors.GetBaseURI()); - } else { + if (u2u) + { + result = m_api.TransactU2U( + txn, + description, + descMap, + GloebitUser.Get(m_key, txn.PayerID), + GloebitUser.Get(m_key, txn.PayeeID), + m_platformAccessors.resolveAgentEmail(UUID.Parse(txn.PayeeID)), + m_platformAccessors.GetBaseURI()); + } + else + { result = m_api.Transact(txn, description, descMap, GloebitUser.Get(m_key, txn.PayerID), m_platformAccessors.GetBaseURI()); } @@ -477,18 +487,33 @@ public bool SubmitSyncTransaction(GloebitTransaction txn, string description, OS // TODO: Should we wrap TransactU2U or request.GetResponse in Try/Catch? GloebitAPI.TransactionStage stage = GloebitAPI.TransactionStage.BUILD; GloebitAPI.TransactionFailure failure = GloebitAPI.TransactionFailure.NONE; - bool result = m_api.TransactU2USync(txn, description, descMap, GloebitUser.Get(m_key, txn.PayerID), GloebitUser.Get(m_key, txn.PayeeID), m_platformAccessors.resolveAgentEmail(txn.PayeeID), m_platformAccessors.GetBaseURI(), out stage, out failure); - if (!result) { + bool result = m_api.TransactU2USync( + txn, + description, + descMap, + GloebitUser.Get(m_key, txn.PayerID), + GloebitUser.Get(m_key, txn.PayeeID), + m_platformAccessors.resolveAgentEmail(UUID.Parse(txn.PayeeID)), + m_platformAccessors.GetBaseURI(), + out stage, + out failure); + + if (!result) + { m_log.ErrorFormat("[GLOEBITMONEYMODULE] SubmitSyncTransaction failed in stage: {0} with failure: {1}", stage, failure); - if (stage == GloebitAPI.TransactionStage.SUBMIT) { + if (stage == GloebitAPI.TransactionStage.SUBMIT) + { // currently need to handle these errors here as the TransactU2UCallback is not called unless submission is successful and we receive a response m_transactionAlerts.AlertTransactionFailed(txn, GloebitAPI.TransactionStage.SUBMIT, failure, String.Empty, new OSDMap()); } - } else { + } + else + { // TODO: figure out how/where to send this alert in a synchronous transaction. Maybe it should always come from the API. // m_transactionAlerts.AlertTransactionStageCompleted(txn, GloebitAPI.TransactionStage.SUBMIT, String.Empty); } + return result; } @@ -746,8 +771,10 @@ public Hashtable transactionState_func(Hashtable requestData) { public UUID CreateSubscription(UUID appSubID, string subName, string subDesc) { m_log.InfoFormat("[GLOEBITMONEYMODULE] GloebitAPIWrapper.CreateSubscription for appSubID:{0}, subName:{1}, subDesc:{2}", appSubID, subName, subDesc); + // Validate that subName and subDesc are not empty or null as Gloebit requires both for a Subscription creation - if (String.IsNullOrEmpty(subName) || String.IsNullOrEmpty(subDesc)) { + if (String.IsNullOrEmpty(subName) || String.IsNullOrEmpty(subDesc)) + { m_log.WarnFormat("[GLOEBITMONEYMODULE] GloebitAPIWrapper.CreateSubscription - Can not create subscription because subscription name or description is blank - Name:{0} Description:{1}", subName, subDesc); //TODO: should this throw an exception? return UUID.Zero; @@ -755,7 +782,8 @@ public UUID CreateSubscription(UUID appSubID, string subName, string subDesc) // If no local appSubID provided, then generate one randomly bool idIsRandom = false; - if (appSubID == UUID.Zero) { + if (appSubID == UUID.Zero) + { // Create a transaction ID appSubID = UUID.Random(); idIsRandom = true; @@ -763,28 +791,38 @@ public UUID CreateSubscription(UUID appSubID, string subName, string subDesc) // Create a local subscription GloebitSubscription sub = null; + // Double check that a local subscription hasn't already been created sub = GloebitSubscription.Get(appSubID, m_key, m_url); - if(sub != null) { + + if (sub != null) + { m_log.WarnFormat("[GLOEBITMONEYMODULE] GloebitAPIWrapper.CreateSubscription found existing local sub for appSubID:{0}", appSubID); + // TODO: Should we check to see if there is a SubscriptionID on sub which would mean that this was already created on Gloebit as well? // For now, we'll assume that this could be an attempt to recreate after an issue and that Gloebit will return the Subscription ID // on a duplicate create request and that this will refresh that ID for the app. - if(idIsRandom) { + if(idIsRandom) + { m_log.ErrorFormat("[GLOEBITMONEYMODULE] GloebitAPIWrapper.CreateSubscription randomly generated appSubID:{0} conflicted with existing sub", appSubID); return UUID.Zero; } + // TODO: Should consider checking that name and desc match, but can't do so until we verify that OpenSim integration doesn't need adjustment. // Can't recall if the UUID of an object is changed when the name or desc are updated. If not, we need to handle that in GMM first. } - if(sub == null) { + + if (sub == null) + { m_log.DebugFormat("[GLOEBITMONEYMODULE] GloebitAPIWrapper.CreateSubscription - creating local subscription for {0}", subName); + // Create local sub in cache and db - sub = GloebitSubscription.Init(appSubID, m_key, m_url.ToString(), subName, subDesc); + sub = GloebitSubscription.Init(appSubID.ToString(), m_key, m_url.ToString(), subName, subDesc); } // Ask Gloebit to create this subscription on the server m_api.CreateSubscription(sub, m_platformAccessors.GetBaseURI()); + // TODO: should we handle false return from api call? return appSubID; } diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs index af48cb8e094..8abd4c19b60 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitMoneyModule.cs @@ -959,7 +959,9 @@ public bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, int amount, U // Check subscription table. If not exists, send create call to Gloebit m_log.DebugFormat("[GLOEBITMONEYMODULE] ObjectGiveMoney - looking for local subscription"); GloebitSubscription sub = GloebitSubscription.Get(objectID, m_key, m_apiUrl); - if (sub == null || sub.SubscriptionID == UUID.Zero) { + + if (sub == null || (sub.SubscriptionID == UUID.Zero.ToString())) + { // null means we haven't attempted creation yet // SubscriptionID == UUID.Zero means we have a local sub, but haven't created this on Gloebit through API. Likely a previous creation request failed // In either case, we need to create a subscription on Gloebit before proceeding @@ -998,7 +1000,8 @@ public bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, int amount, U // Check that user has authed Gloebit and token is on file. GloebitUser payerUser = GloebitUser.Get(m_key, fromID); - if (payerUser != null && String.IsNullOrEmpty(payerUser.GloebitToken)) { + if (payerUser != null && String.IsNullOrEmpty(payerUser.GloebitToken)) + { // send message asking to auth Gloebit. alertUsersSubscriptionTransactionFailedForGloebitAuthorization(fromID, toID, amount, sub); reason = "Owner has not authorized this app with Gloebit."; @@ -1008,13 +1011,15 @@ public bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, int amount, U // Checks done. Ready to build and submit transaction. OSDMap descMap = buildOpenSimTransactionDescMap(regionname, regionID, "ObjectGiveMoney", part); - + UUID subId = UUID.Parse(sub.SubscriptionID); + GloebitTransaction txn = buildTransaction(transactionID: txnID, transactionType: TransactionType.OBJECT_PAYS_USER, - payerID: fromID, payeeID: toID, amount: amount, subscriptionID: sub.SubscriptionID, + payerID: fromID, payeeID: toID, amount: amount, subscriptionID: subId, partID: objectID, partName: part.Name, partDescription: part.Description, categoryID: UUID.Zero, localID: 0, saleType: 0); - if (txn == null) { + if (txn == null) + { // build failed, likely due to a reused transactionID. Shouldn't happen, but possible in ObjectGiveMoney. IClientAPI payerClient = LocateClientObject(fromID); alertUsersTransactionPreparationFailure(TransactionType.OBJECT_PAYS_USER, TransactionPrecheckFailure.EXISTING_TRANSACTION_ID, payerClient); @@ -1559,12 +1564,45 @@ private GloebitTransaction buildTransaction(UUID transactionID, TransactionType partDescription = String.Empty; } - GloebitTransaction txn = GloebitTransaction.Create(transactionID, payerID, payerName, payeeID, payeeName, amount, (int)transactionType, transactionTypeString, isSubscriptionDebit, subscriptionID, partID, partName, partDescription, categoryID, localID, saleType); + GloebitTransaction txn = GloebitTransaction.Create( + transactionID.ToString(), + payerID.ToString(), + payerName, + payeeID.ToString(), + payeeName, + amount, + (int)transactionType, + transactionTypeString, + isSubscriptionDebit, + subscriptionID.ToString(), + partID.ToString(), + partName, + partDescription, + categoryID.ToString(), + localID, + saleType); - if (txn == null && isRandomID) { + if (txn == null && isRandomID) + { // Try one more time in case the incredibly unlikely event of a UUID.Random overlap has occurred. transactionID = UUID.Random(); - txn = GloebitTransaction.Create(transactionID, payerID, payerName, payeeID, payeeName, amount, (int)transactionType, transactionTypeString, isSubscriptionDebit, subscriptionID, partID, partName, partDescription, categoryID, localID, saleType); + txn = GloebitTransaction.Create( + transactionID.ToString(), + payerID.ToString(), + payerName, + payeeID.ToString(), + payeeName, + amount, + (int)transactionType, + transactionTypeString, + isSubscriptionDebit, + subscriptionID.ToString(), + partID.ToString(), + partName, + partDescription, + categoryID.ToString(), + localID, + saleType); } return txn; @@ -1701,18 +1739,23 @@ public bool processAssetEnactHold(GloebitTransaction txn, out string returnMsg) return false; } break; + case TransactionType.USER_PAYS_USER: // 5001 - OnMoneyTransfer - Pay User // nothing to enact break; + case TransactionType.USER_PAYS_OBJECT: // 5008 - OnMoneyTransfer - Pay Object // need to alert the object that it has been paid. ObjectPaid handleObjectPaid = OnObjectPaid; - if(handleObjectPaid != null) { - handleObjectPaid(txn.PartID, txn.PayerID, txn.Amount); + if(handleObjectPaid != null) + { + handleObjectPaid(UUID.Parse(txn.PartID), UUID.Parse(txn.PayerID), txn.Amount); // This doesn't provide a return or ability to query state, so we assume success - } else { + } + else + { // This really shouldn't happen, as it would mean that the OpenSim region is not properly set up // However, we won't fail here as expectation is unclear // We have received this when a sim has another active money module which didn't respect the config and tried to enable on @@ -1720,27 +1763,34 @@ public bool processAssetEnactHold(GloebitTransaction txn, out string returnMsg) m_log.ErrorFormat("[GLOEBITMONEYMODULE].processAssetEnactHold - IMoneyModule OnObjectPaid event not properly subscribed. Object payment may have failed."); } break; + case TransactionType.OBJECT_PAYS_USER: // 5009 - ObjectGiveMoney // nothing to enact. break; + case TransactionType.USER_BUYS_LAND: // 5002 - OnLandBuy // Need to transfer land bool transferred = transferLand(txn, out returnMsg); - if (!transferred) { + + if (!transferred) + { // Local Asset Enact failed - set returnMsg returnMsg = String.Format("Asset enact failed: {0}", returnMsg); // remove land asset from map since cancel will not get called // TODO: should we do this here, or // - adjust ProcessAssetCancelHold to always be called and check state to see if something needs to be undone? // - do this from AlertTransactionFailed() - lock(m_landAssetMap) { - m_landAssetMap.Remove(txn.TransactionID); + lock(m_landAssetMap) + { + m_landAssetMap.Remove(UUID.Parse(txn.TransactionID)); } + return false; } break; + case TransactionType.USER_BUYS_LANDPASS: // 5006 - OnParcelBuyPass prior to 0.9.1; MoveMoney after; // NOTE: new flow: delivery is outside of our system. Nothing to enact. @@ -1753,18 +1803,22 @@ public bool processAssetEnactHold(GloebitTransaction txn, out string returnMsg) } } break; + case TransactionType.FEE_GROUP_CREATION: // 1002 - ApplyCharge // Nothing to do since the group was already created. Ideally, this would create group or finalize creation. break; + case TransactionType.FEE_UPLOAD_ASSET: // 1101 - ApplyUploadCharge // Nothing to do since the asset was already uploaded. Ideally, this would upload asset or finalize upload. break; + case TransactionType.FEE_CLASSIFIED_AD: // 1103 - ApplyCharge // Nothing to do since the ad was already placed. Ideally, this would create ad finalize ad. break; + default: m_log.ErrorFormat("[GLOEBITMONEYMODULE] processAssetEnactHold called on unknown transaction type: {0}", txn.TransactionType); // TODO: should we throw an exception? return null? just continue? @@ -1778,54 +1832,65 @@ public bool processAssetEnactHold(GloebitTransaction txn, out string returnMsg) return true; } - public bool processAssetConsumeHold(GloebitTransaction txn, out string returnMsg) { - + public bool processAssetConsumeHold(GloebitTransaction txn, out string returnMsg) + { m_log.InfoFormat("[GLOEBITMONEYMODULE].processAssetConsumeHold SUCCESS - transaction complete"); // If we've gotten this call, then the Gloebit components have enacted successfully // all transferred funds have been committed. // ITransactionAlert.AlertTransactionStageCompleted for CONSUME_GLOEBIT just fired - switch ((TransactionType)txn.TransactionType) { + switch ((TransactionType)txn.TransactionType) + { case TransactionType.USER_BUYS_OBJECT: // 5000 - ObjectBuy // nothing to finalize break; + case TransactionType.USER_PAYS_USER: // 5001 - OnMoneyTransfer - Pay User // nothing to finalize break; + case TransactionType.USER_PAYS_OBJECT: // 5008 - OnMoneyTransfer - Pay Object // nothing to finalize break; + case TransactionType.OBJECT_PAYS_USER: // 5009 - ObjectGiveMoney // nothing to finalize break; + case TransactionType.USER_BUYS_LAND: // 5002 - OnLandBuy // Remove land asset from map - lock(m_landAssetMap) { - m_landAssetMap.Remove(txn.TransactionID); + lock(m_landAssetMap) + { + m_landAssetMap.Remove(UUID.Parse(txn.TransactionID)); } break; + case TransactionType.USER_BUYS_LANDPASS: // 5006 - OnParcelBuyPass pre 0.9.1; MoveMoney after; // nothing to finalize break; + case TransactionType.FEE_GROUP_CREATION: // 1002 - ApplyCharge // Nothing to do since the group was already created. Ideally, this would finalize creation. break; + case TransactionType.FEE_UPLOAD_ASSET: // 1101 - ApplyUploadCharge // Nothing to do since the asset was already uploaded. Ideally, this would finalize upload. break; + case TransactionType.FEE_CLASSIFIED_AD: // 1103 - ApplyCharge // Nothing to do since the ad was already placed. Ideally, this would finalize ad. break; + default: m_log.ErrorFormat("[GLOEBITMONEYMODULE] processAssetConsumeHold called on unknown transaction type: {0}", txn.TransactionType); // TODO: should we throw an exception? return null? just continue? @@ -1846,43 +1911,53 @@ public bool processAssetCancelHold(GloebitTransaction txn, out string returnMsg) { m_log.InfoFormat("[GLOEBITMONEYMODULE].processAssetCancelHold SUCCESS - transaction rolled back"); // nothing to cancel - either enact of asset failed or was never called if we're here. - switch ((TransactionType)txn.TransactionType) { + switch ((TransactionType)txn.TransactionType) + { case TransactionType.USER_BUYS_OBJECT: // 5000 - ObjectBuy // no mechanism for reversing delivery break; + case TransactionType.USER_PAYS_USER: // 5001 - OnMoneyTransfer - Pay User // nothing to cancel break; + case TransactionType.USER_PAYS_OBJECT: // 5008 - OnMoneyTransfer - Pay Object // no mechanism for notifying object break; + case TransactionType.OBJECT_PAYS_USER: // 5009 - ObjectGiveMoney // nothing to cancel break; + case TransactionType.USER_BUYS_LAND: // 5002 - OnLandBuy // nothing to cancel, if we're here, it is because land was not transferred successfully. break; + case TransactionType.USER_BUYS_LANDPASS: // 5006 - OnParcelBuyPass pre 0.9.1; MoveMoney after; // nothing to cancel, if we're here, it is because landpass was not granted successfully. break; + case TransactionType.FEE_GROUP_CREATION: // 1002 - ApplyCharge // TODO: can we delete the group? break; + case TransactionType.FEE_UPLOAD_ASSET: // 1101 - ApplyUploadCharge // TODO: can we delete the asset? break; + case TransactionType.FEE_CLASSIFIED_AD: // 1103 - ApplyCharge // TODO: can we delete the ad? break; + default: m_log.ErrorFormat("[GLOEBITMONEYMODULE] processAssetCancelHold called on unknown transaction type: {0}", txn.TransactionType); // TODO: should we throw an exception? return null? just continue? @@ -1920,9 +1995,12 @@ public void AlertTransactionFailed(GloebitTransaction txn, GloebitAPI.Transactio // Handle any functional/flow requirements of any failures. // Since OpenSim uses subscriptions in an odd way and doesn't yet store subscription authorizations, those need special handling here. - if (stage == GloebitAPI.TransactionStage.VALIDATE) { - IClientAPI payerClient = LocateClientObject(txn.PayerID); - switch(failure) { + if (stage == GloebitAPI.TransactionStage.VALIDATE) + { + IClientAPI payerClient = LocateClientObject(UUID.Parse(txn.PayerID)); + + switch(failure) + { case GloebitAPI.TransactionFailure.SUBSCRIPTION_AUTH_NOT_FOUND: /* No sub_auth has been created for this user for this subscription */ m_log.InfoFormat("[GLOEBITMONEYMODULE].AlertTransactionFailed No subscription authorization in place. Asking payer to auth. transactionID:{0}, app-subscription-id:{1} PayerID:{2} PayerName:{3}", txn.TransactionID, txn.SubscriptionID, txn.PayerID, txn.PayerName); // TODO: Should we store auths so we know if we need to create it or just to ask user to auth after failed transaction? @@ -1930,35 +2008,75 @@ public void AlertTransactionFailed(GloebitTransaction txn, GloebitAPI.Transactio // Ask user if they would like to authorize // Don't call CreateSubscriptionAuthorization unless they do. If this is fraud, the user will not want to see a pending auth on Gloebit. - if (payerClient != null) { - Dialog.Send(new CreateSubscriptionAuthorizationDialog(payerClient, txn.PayerID, txn.PayerName, txn.PartID, txn.PartName, txn.PartDescription, txn.TransactionID, txn.PayeeID, txn.PayeeName, txn.Amount, txn.SubscriptionID, m_apiW, BaseURI)); - } else { + if (payerClient != null) + { + Dialog.Send(new CreateSubscriptionAuthorizationDialog( + payerClient, + UUID.Parse(txn.PayerID), + txn.PayerName, + UUID.Parse(txn.PartID), + txn.PartName, + txn.PartDescription, + UUID.Parse(txn.TransactionID), + UUID.Parse(txn.PayeeID), + txn.PayeeName, + txn.Amount, + UUID.Parse(txn.SubscriptionID), + m_apiW, + BaseURI)); + } + else + { // TODO: does the message eventually make it if the user is offline? Is there a way to send a Dialog to a user the next time they log in? // Should we just create the subscription_auth in this case? // TODO: This is an issue with restoring of auto-debit scripted objects with new UUID. If owner isn't online, they won't get asked to re-auth on failure. } break; + case GloebitAPI.TransactionFailure.SUBSCRIPTION_AUTH_PENDING: /* User has not yet approved or declined the authorization for this subscription */ // User has been asked and chose to auth already. // Subscription-authorization has already been created. // User has not yet responded to that request, so send a dialog again to ask for auth and allow reporting of fraud. m_log.InfoFormat("[GLOEBITMONEYMODULE].AlertTransactionFailed subscription authorization pending. Asking payer to auth again. transactionID:{0}, app-subscription-id:{1} PayerID:{2} PayerName:{3}", txn.TransactionID, txn.SubscriptionID, txn.PayerID, txn.PayerName); + // Send request to user again - if (payerClient != null) { + if (payerClient != null) + { UUID subscriptionAuthID = UUID.Zero; // pull from extraData because not in transaction - if (extraData.ContainsKey("subscription-authorization-id")) { + if (extraData.ContainsKey("subscription-authorization-id")) + { subscriptionAuthID = UUID.Parse(extraData["subscription-authorization-id"]); - } else { + } + else + { m_log.Error("[GLOEBITMONEYMODULE].AlertTransactionFailed subscription-authorization-id expected, but missing from extraData"); } - Dialog.Send(new PendingSubscriptionAuthorizationDialog(payerClient, txn.PayerID, txn.PayerName, txn.PartID, txn.PartName, txn.PartDescription, txn.TransactionID, txn.PayeeID, txn.PayeeName, txn.Amount, txn.SubscriptionID, subscriptionAuthID, m_apiW, BaseURI)); - } else { + + Dialog.Send(new PendingSubscriptionAuthorizationDialog( + payerClient, + UUID.Parse(txn.PayerID), + txn.PayerName, + UUID.Parse(txn.PartID), + txn.PartName, + txn.PartDescription, + UUID.Parse(txn.TransactionID), + UUID.Parse(txn.PayeeID), + txn.PayeeName, + txn.Amount, + UUID.Parse(txn.SubscriptionID), + subscriptionAuthID, + m_apiW, + BaseURI)); + } + else + { // TODO: does the message eventually make it if the user is offline? Is there a way to send a Dialog to a user the next time they log in? // Should we just create the subscription_auth in this case? } break; + case GloebitAPI.TransactionFailure.SUBSCRIPTION_AUTH_DECLINED: /* User has declined the authorization for this subscription */ m_log.InfoFormat("[GLOEBITMONEYMODULE].AlertTransactionFailed subscription authorization declined. Asking payer to auth again. transactionID:{0}, app-subscription-id:{1} PayerID:{2} PayerName:{3}", txn.TransactionID, txn.SubscriptionID, txn.PayerID, txn.PayerName); @@ -1966,13 +2084,17 @@ public void AlertTransactionFailed(GloebitTransaction txn, GloebitAPI.Transactio // Send dialog asking user to auth or report --- needs different message. string subscriptionAuthIDStr = String.Empty; // pull from extraData because not in transaction - if (extraData.ContainsKey("subscription-authorization-id")) { + if (extraData.ContainsKey("subscription-authorization-id")) + { subscriptionAuthIDStr = extraData["subscription-authorization-id"]; - } else { + } + else + { m_log.Error("[GLOEBITMONEYMODULE].AlertTransactionFailed subscription-authorization-id expected, but missing from extraData"); } + GloebitSubscription sub = GloebitSubscription.GetBySubscriptionID(txn.SubscriptionID.ToString(), m_apiW.m_url.ToString()); - m_apiW.AuthorizeSubscription(txn.PayerID, subscriptionAuthIDStr, sub, true); + m_apiW.AuthorizeSubscription(UUID.Parse(txn.PayerID), subscriptionAuthIDStr, sub, true); break; } } @@ -2129,6 +2251,7 @@ public void AlertUserAuthorized(GloebitUser user, UUID agentID, double balance, public void AlertSubscriptionCreated(GloebitSubscription subscription) { m_log.InfoFormat ("[GLOEBITMONEYMODULE].AlertSubscriptionCreated appSubID:{0} GloebitSubID:{1}", subscription.ObjectID, subscription.SubscriptionID); + // TODO: Do we need to message any client? // OpenSim needs to handle this specially because we are using subscriptions for auto-debit and therefore creating @@ -2138,24 +2261,34 @@ public void AlertSubscriptionCreated(GloebitSubscription subscription) // Look at authWaitingForSubMap - if auth waiting, start that flow. IClientAPI client = null; bool foundClient = false; - lock (m_authWaitingForSubMap) { - foundClient = m_authWaitingForSubMap.TryGetValue (subscription.ObjectID, out client); - if (foundClient) { - m_authWaitingForSubMap.Remove (subscription.ObjectID); + UUID objectId = UUID.Parse(subscription.ObjectID); + + lock (m_authWaitingForSubMap) + { + foundClient = m_authWaitingForSubMap.TryGetValue (objectId, out client); + if (foundClient) + { + m_authWaitingForSubMap.Remove (objectId); } } + // TODO: Not sending dialog. Just creating auth. Should we separate flow from transaction failure and deliver dialog? - if (foundClient) { + if (foundClient) + { m_apiW.AuthorizeSubscription(client.AgentId, String.Empty, subscription, false); } } public void AlertSubscriptionCreationFailed(GloebitSubscription subscription) { - m_log.InfoFormat ("[GLOEBITMONEYMODULE].AlertSubscriptionCreationFailed appSubID:{0}", subscription.ObjectID); + UUID objectId = UUID.Parse(subscription.ObjectID); + + m_log.InfoFormat ("[GLOEBITMONEYMODULE].AlertSubscriptionCreationFailed appSubID:{0}", objectId); + // If we added to this map. remove so we're not leaking memory in failure cases. - lock(m_authWaitingForSubMap) { - m_authWaitingForSubMap.Remove(subscription.ObjectID); + lock(m_authWaitingForSubMap) + { + m_authWaitingForSubMap.Remove(objectId); } } @@ -2702,11 +2835,13 @@ private void ObjectBuy(IClientAPI remoteClient, UUID agentID, m_log.InfoFormat("[GLOEBITMONEYMODULE] ObjectBuy Transaction queued {0}", txn.TransactionID.ToString()); } - private bool deliverObject(GloebitTransaction txn, out string returnMsg) { + private bool deliverObject(GloebitTransaction txn, out string returnMsg) + { // TODO: this could fail if user logs off right after submission. Is this what we want? // TODO: This basically always fails when you crash opensim and recover during a transaction. Is this what we want? - IClientAPI buyerClient = LocateClientObject(txn.PayerID); - if (buyerClient == null) { + IClientAPI buyerClient = LocateClientObject(UUID.Parse(txn.PayerID)); + if (buyerClient == null) + { m_log.ErrorFormat("[GLOEBITMONEYMODULE].deliverObject FAILED to locate buyer agent. Agent may have logged out prior to delivery."); returnMsg = "Can't locate buyer."; return false; @@ -2714,9 +2849,11 @@ private bool deliverObject(GloebitTransaction txn, out string returnMsg) { // Retrieve BuySellModule used for delivering this asset Scene s = LocateSceneClientIn(buyerClient.AgentId); + // TODO: we should be locating the scene the part is in instead of the agent in case the agent moved (to a non Gloebit region) -- maybe store scene ID in asset -- see processLandBuy? IBuySellModule module = s.RequestModuleInterface(); - if (module == null) { + if (module == null) + { m_log.ErrorFormat("[GLOEBITMONEYMODULE].deliverObject FAILED to access to IBuySellModule"); returnMsg = "Can't access IBuySellModule."; return false; @@ -2724,24 +2861,33 @@ private bool deliverObject(GloebitTransaction txn, out string returnMsg) { // Rebuild delivery params from Asset and attempt delivery of object uint localID; - if (!txn.TryGetLocalID(out localID)) { + if (!txn.TryGetLocalID(out localID)) + { SceneObjectPart part; - if (s.TryGetSceneObjectPart(txn.PartID, out part)) { + if (s.TryGetSceneObjectPart(UUID.Parse(txn.PartID), out part)) + { localID = part.LocalId; - } else { + } + else + { m_log.ErrorFormat("[GLOEBITMONEYMODULE].deliverObject FAILED to deliver asset - could not retrieve SceneObjectPart from ID"); returnMsg = "Failed to deliver asset. Could not retrieve SceneObjectPart from ID."; return false; } } - bool success = module.BuyObject(buyerClient, txn.CategoryID, localID, (byte)txn.SaleType, txn.Amount); - if (!success) { + + bool success = module.BuyObject(buyerClient, UUID.Parse(txn.CategoryID), localID, (byte)txn.SaleType, txn.Amount); + if (!success) + { m_log.ErrorFormat("[GLOEBITMONEYMODULE].deliverObject FAILED to deliver asset"); returnMsg = "IBuySellModule.BuyObject failed delivery attempt."; - } else { + } + else + { m_log.InfoFormat("[GLOEBITMONEYMODULE].deliverObject SUCCESS - delivered asset"); returnMsg = "object delivery succeeded"; } + return success; } @@ -2855,8 +3001,9 @@ private bool deliverLandPass(GloebitTransaction txn, out string returnMsg) { return false; } int parcelLocalID = (int)localID; - UUID agentID = txn.PayerID; - UUID regionID = txn.CategoryID; + UUID agentID = UUID.Parse(txn.PayerID); + UUID regionID = UUID.Parse(txn.CategoryID); + Scene s = GetSceneByUUID(regionID); if (s == null) { // Should probably never happen @@ -2880,11 +3027,13 @@ private bool deliverLandPass(GloebitTransaction txn, out string returnMsg) { return false; } // Make sure owner hasn't changed - if ((parcel.LandData.OwnerID != txn.PayeeID)) { + if (parcel.LandData.OwnerID != UUID.Parse(txn.PayeeID)) + { m_log.WarnFormat("[GLOEBITMONEYMODULE] AgentID:{0} attempted to buy a pass on parcel:{1} which changed ownership before transaction completed.", agentID, parcel.LandData.GlobalID); returnMsg = "Parcel ownership has changed. Please retry purchase."; return false; } + // Make sure price hasn't changed if(parcel.LandData.PassPrice != txn.Amount) { @@ -3112,27 +3261,36 @@ private void ProcessLandBuy(Object osender, EventManager.LandBuyArgs e) // Add region UUID and LandBuyArgs to dictionary accessible for callback and wait for callback // Needs to happen before we submit because C# can delay wakeup for this synchronous call and // the enact could be received before we know if the submission succeeded. - lock(m_landAssetMap) { - m_landAssetMap[txn.TransactionID] = new Object[2]{s.RegionInfo.originRegionID, e}; + lock(m_landAssetMap) + { + m_landAssetMap[UUID.Parse(txn.TransactionID)] = new Object[2]{s.RegionInfo.originRegionID, e}; } bool submission_result = m_apiW.SubmitTransaction(txn, description, descMap, true); // See GloebitAPIWrapper.TransactU2UCompleted and helper messaging functions for error messaging on failure - no action required. // See ProcessAssetEnactHold for proceeding with txn on success. - if (!submission_result) { + if (!submission_result) + { // payment failed. message user and halt attempt to transfer land //// TODO: message error - lock(m_landAssetMap) { - m_landAssetMap.Remove(txn.TransactionID); + lock(m_landAssetMap) + { + m_landAssetMap.Remove(UUID.Parse(txn.TransactionID)); } + return; } } - } else { /* economy is validated. Second time through or 0G txn */ - if (e.parcelPrice == 0) { + } + else + { /* economy is validated. Second time through or 0G txn */ + if (e.parcelPrice == 0) + { // Free land. No economic part. e.amountDebited = 0; - } else { + } + else + { // Second time through. Completing a transaction we launched the first time through. // if e.landValidated, land has or will transfer. // We can't verify here because the land process may happen after economy, so do nothing here. @@ -3141,16 +3299,20 @@ private void ProcessLandBuy(Object osender, EventManager.LandBuyArgs e) } } - private bool transferLand(GloebitTransaction txn, out string returnMsg) { + private bool transferLand(GloebitTransaction txn, out string returnMsg) + { //// retrieve LandBuyArgs from assetMap - bool foundArgs = m_landAssetMap.ContainsKey(txn.TransactionID); - if (!foundArgs) { + bool foundArgs = m_landAssetMap.ContainsKey(UUID.Parse(txn.TransactionID)); + if (!foundArgs) + { returnMsg = "Could not locate land asset for transaction."; return false; } - Object[] landBuyAsset = m_landAssetMap[txn.TransactionID]; + + Object[] landBuyAsset = m_landAssetMap[UUID.Parse(txn.TransactionID)]; UUID regionID = (UUID)landBuyAsset[0]; EventManager.LandBuyArgs e = (EventManager.LandBuyArgs)landBuyAsset[1]; + // Set land buy args that need setting // TODO: should we be creating a new LandBuyArgs and copying the data instead in case anything else subscribes to the LandBuy events and mucked with these? e.economyValidated = true; @@ -3158,12 +3320,14 @@ private bool transferLand(GloebitTransaction txn, out string returnMsg) { e.landValidated = false; //// retrieve client - IClientAPI sender = LocateClientObject(txn.PayerID); - if (sender == null) { + IClientAPI sender = LocateClientObject(UUID.Parse(txn.PayerID)); + if (sender == null) + { // TODO: Does it matter if we can't locate the client? Does this break if sender is null? returnMsg = "Could not locate buyer."; return false; } + //// retrieve scene Scene s = GetSceneByUUID(regionID); if (s == null) { @@ -3173,12 +3337,16 @@ private bool transferLand(GloebitTransaction txn, out string returnMsg) { //// Trigger validate s.EventManager.TriggerValidateLandBuy(sender, e); + // Check land validation - if (!e.landValidated) { + if (!e.landValidated) + { returnMsg = "Land validation failed."; return false; } - if (e.parcelOwnerID != txn.PayeeID) { + + if (e.parcelOwnerID != UUID.Parse(txn.PayeeID)) + { returnMsg = "Parcel owner changed."; return false; } @@ -3188,7 +3356,8 @@ private bool transferLand(GloebitTransaction txn, out string returnMsg) { // Verify that land transferred successfully - sad that we have to check this. ILandObject parcel = s.LandChannel.GetLandObject(e.parcelLocalID); UUID newOwnerID = parcel.LandData.OwnerID; - if (newOwnerID != txn.PayerID) { + if (newOwnerID != UUID.Parse(txn.PayerID)) + { // This should only happen if due to race condition. Unclear if possible or result. returnMsg = "Land transfer failed. Owner is not buyer."; return false; @@ -3210,7 +3379,8 @@ private bool transferLand(GloebitTransaction txn, out string returnMsg) { /// SceneObjectPart UUID of the item the client is granting permissions on /// UUID of the TaskInventoryItem associated with this SceneObjectPart which handles permissions /// Bitmap of the permissions which are being granted - private void handleScriptAnswer(IClientAPI client, UUID objectID, UUID itemID, int answer) { + private void handleScriptAnswer(IClientAPI client, UUID objectID, UUID itemID, int answer) + { // m_log.InfoFormat("[GLOEBITMONEYMODULE] handleScriptAnswer for client:{0} with objectID:{1}, itemID:{2}, answer:{3}", client.AgentId, objectID, itemID, answer); if ((answer & ScriptBaseClass.PERMISSION_DEBIT) == 0) @@ -3227,16 +3397,22 @@ private void handleScriptAnswer(IClientAPI client, UUID objectID, UUID itemID, i // Check subscription table. If not exists, send create call to Gloebit. m_log.DebugFormat("[GLOEBITMONEYMODULE] handleScriptAnswer - looking for local subscription"); GloebitSubscription sub = GloebitSubscription.Get(objectID, m_key, m_apiUrl); - if (sub == null || sub.SubscriptionID == UUID.Zero) { + + if (sub == null || (sub.SubscriptionID == UUID.Zero.ToString())) + { // Don't create unless the object has a name and description // Make sure Name and Description are not null to avoid pgsql issue with storing null values // Make sure neither are empty as they are required by Gloebit to create a subscription SceneObjectPart part = findPrim(objectID); - if (part == null) { + + if (part == null) + { m_log.ErrorFormat("[GLOEBITMONEYMODULE] handleScriptAnswer - Could not find object - ID:{0}", objectID); return; } - if (String.IsNullOrEmpty(part.Name) || String.IsNullOrEmpty(part.Description)) { + + if (String.IsNullOrEmpty(part.Name) || String.IsNullOrEmpty(part.Description)) + { m_log.WarnFormat("[GLOEBITMONEYMODULE] handleScriptAnswer - Can not create local subscription because part name or description is blank - Name:{0} Description:{1}", part.Name, part.Description); // Send message to the owner to let them know they must edit the object and add a name and description String imMsg = String.Format("Object with auto-debit script is missing a name or description. Name and description are required by Gloebit in order to create a subscription for this auto-debit object. Please enter a name and description in the object. Current values are Name:[{0}] and Description:[{1}].", part.Name, part.Description); @@ -3245,7 +3421,8 @@ private void handleScriptAnswer(IClientAPI client, UUID objectID, UUID itemID, i } // Add this user to map of waiting for sub to create auth. - lock(m_authWaitingForSubMap) { + lock(m_authWaitingForSubMap) + { m_authWaitingForSubMap[objectID] = client; } @@ -3547,7 +3724,7 @@ private void SendNewSessionMessaging(IClientAPI client, GloebitUser user) { /// private void sendTxnStatusToClient(GloebitTransaction txn, IClientAPI client, string baseStatus, bool showTxnDetails, bool showTxnID) { - sendTxnStatusToClient(txn, client, baseStatus, showTxnDetails, showTxnID, txn.PayerID); + sendTxnStatusToClient(txn, client, baseStatus, showTxnDetails, showTxnID, UUID.Parse(txn.PayerID)); } /// @@ -3868,19 +4045,22 @@ private void alertUsersTransactionBegun(GloebitTransaction txn, string descripti } // Alert payer - IClientAPI payerClient = LocateClientObject(txn.PayerID); + IClientAPI payerClient = LocateClientObject(UUID.Parse(txn.PayerID)); + // TODO: remove description once in txn and managed in sendTxnStatusToClient //string baseStatus = String.Format("Submitting transaction request...\n {0}", actionStr); string baseStatus = String.Format("Submitting transaction request...\n {0}\nDescription: {1}", actionStr, description); sendTxnStatusToClient(txn, payerClient, baseStatus, showDetailsWithTxnBegun, showIDWithTxnBegun); // If necessary, alert Payee - if (messagePayee && (txn.PayerID != txn.PayeeID)) { - IClientAPI payeeClient = LocateClientObject(txn.PayeeID); + if (messagePayee && (txn.PayerID != txn.PayeeID)) + { + IClientAPI payeeClient = LocateClientObject(UUID.Parse(txn.PayeeID)); + // TODO: remove description once in txn and managed in sendTxnStatusToClient // string payeeBaseStatus = String.Format("Submitting transaction request...\n {0}", payeeActionStr); string payeeBaseStatus = String.Format("Submitting transaction request...\n {0}\nDescription: {1}", payeeActionStr, description); - sendTxnStatusToClient(txn, payeeClient, payeeBaseStatus, showDetailsWithTxnBegun, showIDWithTxnBegun, txn.PayeeID); + sendTxnStatusToClient(txn, payeeClient, payeeBaseStatus, showDetailsWithTxnBegun, showIDWithTxnBegun, UUID.Parse(txn.PayeeID)); } } @@ -4040,7 +4220,7 @@ private void alertUsersTransactionStageCompleted(GloebitTransaction txn, Gloebit } // for now, we're only going to send these to the payer. - IClientAPI payerClient = LocateClientObject(txn.PayerID); + IClientAPI payerClient = LocateClientObject(UUID.Parse(txn.PayerID)); sendTxnStatusToClient(txn, payerClient, status, showDetailsWithTxnStage, showIDWithTxnStage); } @@ -4246,32 +4426,36 @@ private void alertUsersTransactionFailed(GloebitTransaction txn, GloebitAPI.Tran } // send failure alert to payer - IClientAPI payerClient = LocateClientObject(txn.PayerID); + IClientAPI payerClient = LocateClientObject(UUID.Parse(txn.PayerID)); sendTxnStatusToClient(txn, payerClient, statusAndInstruction, showDetailsWithTxnFailed, showIDWithTxnFailed); // Determine if alert needs to be sent to payee and send IClientAPI payeeClient = null; - if (txn.TransactionType == (int)TransactionType.OBJECT_PAYS_USER || messagePayee) { + if (txn.TransactionType == (int)TransactionType.OBJECT_PAYS_USER || messagePayee) + { // locate payee since we'll need to message - payeeClient = LocateClientObject(txn.PayeeID); + payeeClient = LocateClientObject(UUID.Parse(txn.PayeeID)); } + // If this is a transaction type where we notified the payer the txn started, we should alert to failure as payer may have triggered the txn - if (txn.TransactionType == (int)TransactionType.OBJECT_PAYS_USER) { + if (txn.TransactionType == (int)TransactionType.OBJECT_PAYS_USER) + { // build failure alert from temp strings statusAndInstruction = status; if (!String.IsNullOrEmpty(payeeInstruction)) { statusAndInstruction = String.Format("{0}\n{1}", status, payeeInstruction); } - sendTxnStatusToClient(txn, payeeClient, statusAndInstruction, showDetailsWithTxnFailed, showIDWithTxnFailed, txn.PayeeID); + sendTxnStatusToClient(txn, payeeClient, statusAndInstruction, showDetailsWithTxnFailed, showIDWithTxnFailed, UUID.Parse(txn.PayeeID)); } // If necessary, send separate message to Payee if (messagePayee) { - sendMessageToClient(payeeClient, payeeMessage, txn.PayeeID); + sendMessageToClient(payeeClient, payeeMessage, UUID.Parse(txn.PayeeID)); // TODO: this message should be delivered to email if client is not online and didn't trigger this message. // Since unidentified seller can now be fixed by auth, send the auth link if they are online - if (payeeClient != null && failure == GloebitAPI.TransactionFailure.PAYEE_CANNOT_BE_IDENTIFIED) { + if (payeeClient != null && failure == GloebitAPI.TransactionFailure.PAYEE_CANNOT_BE_IDENTIFIED) + { m_apiW.Authorize(payeeClient.AgentId, payeeClient.Name); } } @@ -4289,20 +4473,20 @@ private void alertUsersTransactionSucceeded(GloebitTransaction txn) bool showDetailsWithTxnSucceeded = false; bool showIDWithTxnSucceeded = false; - IClientAPI payerClient = LocateClientObject(txn.PayerID); - IClientAPI payeeClient = LocateClientObject(txn.PayeeID); // get this regardless of messaging since we'll try to update balance + IClientAPI payerClient = LocateClientObject(UUID.Parse(txn.PayerID)); + IClientAPI payeeClient = LocateClientObject(UUID.Parse(txn.PayeeID)); // get this regardless of messaging since we'll try to update balance // send success message to payer sendTxnStatusToClient(txn, payerClient, "Transaction SUCCEEDED.", showDetailsWithTxnSucceeded, showIDWithTxnSucceeded); // If this is a transaction type where we notified the payee the txn started, we should alert to successful completion if ((txn.TransactionType == (int)TransactionType.OBJECT_PAYS_USER) && (txn.PayerID != txn.PayeeID)) { - sendTxnStatusToClient(txn, payeeClient, "Transaction SUCCEEDED.", showDetailsWithTxnSucceeded, showIDWithTxnSucceeded, txn.PayeeID); + sendTxnStatusToClient(txn, payeeClient, "Transaction SUCCEEDED.", showDetailsWithTxnSucceeded, showIDWithTxnSucceeded, UUID.Parse(txn.PayeeID)); } // If this transaction was one user paying another, if the user is online, we should let them know they received a payment if (txn.TransactionType == (int)TransactionType.USER_PAYS_USER) { string message = String.Format("You've received Gloebits from {0}.", resolveAgentName(payerClient.AgentId)); - sendTxnStatusToClient(txn, payeeClient, message, true, showIDWithTxnSucceeded, txn.PayeeID); + sendTxnStatusToClient(txn, payeeClient, message, true, showIDWithTxnSucceeded, UUID.Parse(txn.PayeeID)); } // TODO: consider if we want to send an alert that payee earned money with transaction details for other transaction types @@ -4311,19 +4495,58 @@ private void alertUsersTransactionSucceeded(GloebitTransaction txn) // TODO: Once we store description in txn, change 3rd arg in SMB below to Utils.StringToBytes(description) // Update Payer & Payee balances if still logged in. - if (payerClient != null) { - if (txn.PayerEndingBalance >= 0) { /* if -1, got an invalid balance in response. possible this shouldn't ever happen */ - payerClient.SendMoneyBalance(txn.TransactionID, true, new byte[0], txn.PayerEndingBalance, txn.TransactionType, txn.PayerID, false, txn.PayeeID, false, txn.Amount, txn.PartDescription); - } else { + if (payerClient != null) + { + if (txn.PayerEndingBalance >= 0) + { /* if -1, got an invalid balance in response. possible this shouldn't ever happen */ + payerClient.SendMoneyBalance( + UUID.Parse(txn.TransactionID), + true, + new byte[0], + txn.PayerEndingBalance, + txn.TransactionType, + UUID.Parse(txn.PayerID), + false, + UUID.Parse(txn.PayeeID), + false, + txn.Amount, + txn.PartDescription); + } + else + { // TODO: consider what this delays while it makes non async call GetBalance from GetUserBalance call get balance - int payerBalance = (int)m_apiW.GetUserBalance(txn.PayerID, true, payerClient.Name); - payerClient.SendMoneyBalance(txn.TransactionID, true, new byte[0], payerBalance, txn.TransactionType, txn.PayerID, false, txn.PayeeID, false, txn.Amount, txn.PartDescription); + int payerBalance = (int)m_apiW.GetUserBalance(UUID.Parse(txn.PayerID), true, payerClient.Name); + payerClient.SendMoneyBalance( + UUID.Parse(txn.TransactionID), + true, + new byte[0], + payerBalance, + txn.TransactionType, + UUID.Parse(txn.PayerID), + false, + UUID.Parse(txn.PayeeID), + false, + txn.Amount, + txn.PartDescription); } } - if ((payeeClient != null) && (txn.PayerID != txn.PayeeID)) { + + if ((payeeClient != null) && (txn.PayerID != txn.PayeeID)) + { // TODO: consider what this delays while it makes non async call GetBalance from GetUserBalance call get balance - int payeeBalance = (int)m_apiW.GetUserBalance(txn.PayeeID, false, payeeClient.Name); - payeeClient.SendMoneyBalance(txn.TransactionID, true, new byte[0], payeeBalance, txn.TransactionType, txn.PayerID, false, txn.PayeeID, false, txn.Amount, txn.PartDescription); + int payeeBalance = (int)m_apiW.GetUserBalance(UUID.Parse(txn.PayeeID), false, payeeClient.Name); + payeeClient.SendMoneyBalance( + UUID.Parse(txn.TransactionID), + true, + new byte[0], + payeeBalance, + txn.TransactionType, + UUID.Parse(txn.PayerID), + false, + UUID.Parse(txn.PayeeID), + false, + txn.Amount, + txn.PartDescription); } } diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitSubscription.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitSubscription.cs index 81330511054..544a4753f7f 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitSubscription.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitSubscription.cs @@ -39,11 +39,13 @@ public class GloebitSubscription { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // These 3 make up the primary key -- allows sim to swap back and forth between apps or GlbEnvs without getting errors - public UUID ObjectID; // ID of object with an LLGiveMoney or LLTransferLinden's script - local subscription ID + // public UUID ObjectID; // ID of object with an LLGiveMoney or LLTransferLinden's script - local subscription ID + public string ObjectID; // ID of object with an LLGiveMoney or LLTransferLinden's script - local subscription ID public string AppKey; // AppKey active when created public string GlbApiUrl; // GlbEnv Url active when created - public UUID SubscriptionID; // ID returned by create-subscription Gloebit endpoint + //public UUID SubscriptionID; // ID returned by create-subscription Gloebit endpoint + public string SubscriptionID; // ID returned by create-subscription Gloebit endpoint public bool Enabled; // enabled returned by Gloebit Endpoint - if not enabled, can't use. public DateTime cTime; // time of creation @@ -59,7 +61,7 @@ public class GloebitSubscription { public GloebitSubscription() { } - private GloebitSubscription(UUID objectID, string appKey, string apiURL, string objectName, string objectDescription) { + private GloebitSubscription(string objectID, string appKey, string apiURL, string objectName, string objectDescription) { this.ObjectID = objectID; this.AppKey = appKey; this.GlbApiUrl = apiURL; @@ -68,7 +70,7 @@ private GloebitSubscription(UUID objectID, string appKey, string apiURL, string this.Description = objectDescription; // Set defaults until we fill them in - SubscriptionID = UUID.Zero; + SubscriptionID = UUID.Zero.ToString(); this.cTime = DateTime.UtcNow; this.Enabled = false; @@ -76,13 +78,15 @@ private GloebitSubscription(UUID objectID, string appKey, string apiURL, string } - public static GloebitSubscription Init(UUID objectID, string appKey, string apiUrl, string objectName, string objectDescription) { - string objectIDstr = objectID.ToString(); - + public static GloebitSubscription Init(string objectID, string appKey, string apiUrl, string objectName, string objectDescription) + { GloebitSubscription s = new GloebitSubscription(objectID, appKey, apiUrl, objectName, objectDescription); - lock(s_subscriptionMap) { - s_subscriptionMap[objectIDstr] = s; + + lock(s_subscriptionMap) + { + s_subscriptionMap[objectID] = s; } + GloebitSubscriptionData.Instance.Store(s); return s; } diff --git a/addon-modules/Gloebit/GloebitMoneyModule/GloebitTransaction.cs b/addon-modules/Gloebit/GloebitMoneyModule/GloebitTransaction.cs index 1c6cc390ca6..907b0e12596 100644 --- a/addon-modules/Gloebit/GloebitMoneyModule/GloebitTransaction.cs +++ b/addon-modules/Gloebit/GloebitMoneyModule/GloebitTransaction.cs @@ -36,12 +36,15 @@ public class GloebitTransaction { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // Primary Key value - public UUID TransactionID; + //public UUID TransactionID; + public string TransactionID; // Common, vital transaction details - public UUID PayerID; + //public UUID PayerID; + public string PayerID; public string PayerName; // TODO: do we need to ensure this is not larger than the db field on hypergrid? - VARCHAR(255) - public UUID PayeeID; + //public UUID PayeeID; + public string PayeeID; public string PayeeName; // TODO: do we need to ensure this is not larger than the db field on hypergrid? - VARCHAR(255) public int Amount; @@ -51,15 +54,18 @@ public class GloebitTransaction { // Subscription info public bool IsSubscriptionDebit; - public UUID SubscriptionID; + //public UUID SubscriptionID; + public string SubscriptionID; // Object info required when enacting/consume/canceling, delivering, and handling subscriptions - public UUID PartID; // UUID of object + //public UUID PartID; // UUID of object + public string PartID; // UUID of object public string PartName; // object name public string PartDescription; // Details required by IBuySellModule when delivering an object - public UUID CategoryID; // Appears to be a folder id used when saleType is copy + //public UUID CategoryID; // Appears to be a folder id used when saleType is copy + public string CategoryID; // Appears to be a folder id used when saleType is copy private uint? m_localID; // Region specific ID of object. Unclear why this is passed instead of UUID public int SaleType; // object, copy, or contents @@ -97,8 +103,24 @@ public GloebitTransaction() { m_localID = null; } - private GloebitTransaction(UUID transactionID, UUID payerID, string payerName, UUID payeeID, string payeeName, int amount, int transactionType, string transactionTypeString, bool isSubscriptionDebit, UUID subscriptionID, UUID partID, string partName, string partDescription, UUID categoryID, uint localID, int saleType) { - + private GloebitTransaction( + string transactionID, + string payerID, + string payerName, + string payeeID, + string payeeName, + int amount, + int transactionType, + string transactionTypeString, + bool isSubscriptionDebit, + string subscriptionID, + string partID, + string partName, + string partDescription, + string categoryID, + uint localID, + int saleType) + { // Primary Key value this.TransactionID = transactionID; @@ -145,6 +167,7 @@ private GloebitTransaction(UUID transactionID, UUID payerID, string payerName, U this.cTime = DateTime.UtcNow; this.enactedTime = null; // set to null instead of DateTime.MinValue to avoid crash on reading 0 timestamp this.finishedTime = null; // set to null instead of DateTime.MinValue to avoid crash on reading 0 timestamp + // TODO: We have made these nullable and initialize to null. We could alternatively choose a time that is not zero // and avoid any potential conflicts from allowing null. // On MySql, I had to set the columns to allow NULL, otherwise, inserting null defaulted to the current local time. @@ -156,7 +179,23 @@ private GloebitTransaction(UUID transactionID, UUID payerID, string payerName, U // First verifies that a transaction with this ID does not already exist // --- If existing txn is found, returns null // Creates new Transaction, stores it in the cache and db - public static GloebitTransaction Create(UUID transactionID, UUID payerID, string payerName, UUID payeeID, string payeeName, int amount, int transactionType, string transactionTypeString, bool isSubscriptionDebit, UUID subscriptionID, UUID partID, string partName, string partDescription, UUID categoryID, uint localID, int saleType) + public static GloebitTransaction Create( + string transactionID, + string payerID, + string payerName, + string payeeID, + string payeeName, + int amount, + int transactionType, + string transactionTypeString, + bool isSubscriptionDebit, + string subscriptionID, + string partID, + string partName, + string partDescription, + string categoryID, + uint localID, + int saleType) { // Create the Transaction GloebitTransaction txn = new GloebitTransaction(transactionID, payerID, payerName, payeeID, payeeName, amount, transactionType, transactionTypeString, isSubscriptionDebit, subscriptionID, partID, partName, partDescription, categoryID, localID, saleType);