diff --git a/OpenSim/Services/AssetService/TSAssetConnector.cs b/OpenSim/Services/AssetService/TSAssetConnector.cs index 59cafaf..b7ef326 100644 --- a/OpenSim/Services/AssetService/TSAssetConnector.cs +++ b/OpenSim/Services/AssetService/TSAssetConnector.cs @@ -78,6 +78,9 @@ namespace OpenSim.Services.AssetService IConfig tsConfig = config.Configs["TSAssetService"]; IConfig dbConfig = config.Configs["DatabaseService"]; + if (tsConfig == null || !tsConfig.GetBoolean("Enabled", false)) + throw new Exception("TSAssetConnector disabled. Set [TSAssetService] Enabled = true to enable."); + string storageProvider = string.Empty; string defaultConnectionString = string.Empty; @@ -124,7 +127,10 @@ namespace OpenSim.Services.AssetService AddProbeDatabase(m_defaultDatabase); if (tsConfig != null) + { ParseTypedDatabaseMappings(tsConfig.GetString("AssetDatabases", string.Empty), storageProvider); + ParseTypedDatabaseMappingsFromKeys(tsConfig, storageProvider); + } string loaderName = assetConfig.GetString("DefaultAssetLoader", string.Empty); if (!string.IsNullOrEmpty(loaderName)) @@ -177,6 +183,11 @@ namespace OpenSim.Services.AssetService m_log.InfoFormat("[TSASSET SERVICE]: Enabled with {0} type routes", m_typeDatabases.Count); } + public TSAssetConnector(IConfigSource config, string configName) + : this(config) + { + } + public AssetBase Get(string id) { Interlocked.Increment(ref m_requestsInWindow); @@ -489,7 +500,7 @@ namespace OpenSim.Services.AssetService if (string.IsNullOrWhiteSpace(rawMappings)) return; - string[] lines = rawMappings.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + string[] lines = rawMappings.Split(new char[] { '\r', '\n', '|' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < lines.Length; i++) { string line = lines[i].Trim(); @@ -530,6 +541,60 @@ namespace OpenSim.Services.AssetService } } + private void ParseTypedDatabaseMappingsFromKeys(IConfig tsConfig, string storageProvider) + { + if (tsConfig == null) + return; + + string[] keys = tsConfig.GetKeys(); + if (keys == null || keys.Length == 0) + return; + + for (int i = 0; i < keys.Length; i++) + { + string key = keys[i]; + if (string.IsNullOrWhiteSpace(key)) + continue; + + string prefix = null; + if (key.StartsWith("AssetDatabase_", StringComparison.OrdinalIgnoreCase)) + prefix = "AssetDatabase_"; + else if (key.StartsWith("AssetDatabase.", StringComparison.OrdinalIgnoreCase)) + prefix = "AssetDatabase."; + + if (prefix == null) + continue; + + string typeToken = key.Substring(prefix.Length).Trim(); + if (!sbyte.TryParse(typeToken, NumberStyles.Integer, CultureInfo.InvariantCulture, out sbyte assetType)) + { + m_log.WarnFormat("[TSASSET SERVICE]: Ignoring invalid asset type key '{0}'", key); + continue; + } + + if (m_allowedTypes.Count > 0 && !m_allowedTypes.Contains(assetType)) + continue; + + string connectionString = tsConfig.GetString(key, string.Empty).Trim(); + if (connectionString.Length >= 2 && + connectionString[0] == '"' && + connectionString[connectionString.Length - 1] == '"') + { + connectionString = connectionString.Substring(1, connectionString.Length - 2).Trim(); + } + + if (string.IsNullOrEmpty(connectionString)) + { + m_log.WarnFormat("[TSASSET SERVICE]: Ignoring empty connection string for asset type key '{0}'", key); + continue; + } + + IAssetDataPlugin db = GetOrCreateDatabase(storageProvider, connectionString); + m_typeDatabases[assetType] = db; + AddProbeDatabase(db); + } + } + private IAssetDataPlugin ResolveDatabaseForType(sbyte type) { if (m_typeDatabases.TryGetValue(type, out IAssetDataPlugin db)) diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 40a14d9..02085df 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -257,7 +257,7 @@ ; Uncomment these lines if you want to use PGSQL storage ; Change the connection string to your db details ;StorageProvider = "OpenSim.Data.PGSQL.dll" - ;ConnectionString = "Server=localhost;Database=opensim;User Id=opensim; password=***;" + ;ConnectionString = "Data Source=localhost;Database=opensim;User Id=opensim; password=***;" ; MySQL ; Uncomment these lines if you want to use MySQL storage @@ -265,7 +265,7 @@ ; If using MySQL 8.0.4 or later, check that default-authentication-plugin=mysql_native_password ; rather than caching_sha2_password is set in /etc/mysql/mysql.conf.d/mysqld.cnf (not applicable to MariaDB). StorageProvider = "OpenSim.Data.MySQL.dll" - ConnectionString = "Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + ConnectionString = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" ; * As an example, the below configuration precisely mimicks the legacy @@ -276,8 +276,8 @@ [AssetService] ;; Choose an asset service (Only one option should be enabled) - LocalServiceModule = "OpenSim.Services.AssetService.dll:TSAssetConnector" - ;LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" + ;LocalServiceModule = "OpenSim.Services.AssetService.dll:TSAssetConnector" + LocalServiceModule = "OpenSim.Services.AssetService.dll:AssetService" ;LocalServiceModule = "OpenSim.Services.FSAssetService.dll:FSAssetConnector" ;; FSAssets Directories. Base directory, where final asset files are stored and Spool directory for temp files @@ -289,8 +289,8 @@ ;; for secondary instances uncoment this line ;SecondaryInstance = true - ;; Optional fallback to original asset service if TS routing misses - FallbackService = "OpenSim.Services.AssetService.dll:AssetService" + ;; FallbackService is only needed when TSAssetConnector is enabled + ;FallbackService = "OpenSim.Services.AssetService.dll:AssetService" ;; How many days since last updating the access time before its updated again by FSAssets when accessing an asset ;; Reduces DB calls if asset is requested often. Default value 0 will always update access time @@ -301,7 +301,7 @@ ;; Legacy provider used by FallbackService (optional but recommended) StorageProvider = "OpenSim.Data.MySQL.dll:MySQLAssetData" - ConnectionString = "Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + ConnectionString = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" ;; FSAssets uses a folder structure to reduce file access times. By default that structure is 00/00/00 ;; Setting this to true will switch to an older 000/000 format, which can cause issues with long file lists @@ -328,9 +328,12 @@ [TSAssetService] + ;; Master switch for TS asset service. Must be true to activate TSAssetConnector. + Enabled = false + ;; TS provider (explicit class avoids wrong provider selection) StorageProvider = "OpenSim.Data.MySQL.dll:MySQLtsAssetData" - ConnectionString = "Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + ConnectionString = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" ;; Optional type allowlist. Empty means all asset types. TSAssetType = "" @@ -346,34 +349,22 @@ MigrationBatchSize = 25 MigrationQueueMax = 50000 - ;; Per-type DB routing. Format: AssetType:ConnectionString - ;; Everything was inserted here without any consideration. - AssetDatabases = " - -2:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 0:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 1:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 2:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 3:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 5:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 6:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 7:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 8:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 10:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 11:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 13:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 17:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 18:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 19:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 20:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 21:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 22:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 24:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 25:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 26:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 49:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 56:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - 57:Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;; - " + ;; Per-type DB routing (editierbar): nur Kern-Typen. + ;; Alle anderen Typen nutzen automatisch die Default-ConnectionString oben. + AssetDatabase_-2 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_0 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_1 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_3 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_5 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_6 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_7 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_10 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_13 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_20 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_21 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_49 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_56 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" + AssetDatabase_57 = "Data Source=localhost;Database=robust;User ID=opensim;Password=opensim123;Old Guids=true;SslMode=None;" ; * This configuration loads the inventory server modules. It duplicates ; * the function of the legacy inventory server