aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
authorDavid Walter Seikel2016-11-03 21:44:39 +1000
committerDavid Walter Seikel2016-11-03 21:44:39 +1000
commit134f86e8d5c414409631b25b8c6f0ee45fbd8631 (patch)
tree216b89d3fb89acfb81be1e440c25c41ab09fa96d /OpenSim/Services
parentMore changing to production grid. Double oops. (diff)
downloadopensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.zip
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.gz
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.bz2
opensim-SC_OLD-134f86e8d5c414409631b25b8c6f0ee45fbd8631.tar.xz
Initial update to OpenSim 0.8.2.1 source code.
Diffstat (limited to 'OpenSim/Services')
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs51
-rw-r--r--OpenSim/Services/AssetService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/AssetService/XAssetService.cs77
-rw-r--r--OpenSim/Services/AssetService/XAssetServiceBase.cs47
-rw-r--r--OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/Base/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/Base/ServiceBase.cs13
-rw-r--r--OpenSim/Services/Connectors/AgentPreferences/AgentPreferencesConnector.cs230
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs118
-rw-r--r--OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs104
-rw-r--r--OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs14
-rw-r--r--OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs3
-rw-r--r--OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs17
-rw-r--r--OpenSim/Services/Connectors/BaseServiceConnector.cs33
-rw-r--r--OpenSim/Services/Connectors/Estate/EstateDataConnector.cs338
-rw-r--r--OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs2
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs12
-rw-r--r--OpenSim/Services/Connectors/Grid/GridServicesConnector.cs121
-rw-r--r--OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs17
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs99
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs2
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs57
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs591
-rw-r--r--OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs1
-rw-r--r--OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs405
-rw-r--r--OpenSim/Services/Connectors/Land/LandServicesConnector.cs4
-rw-r--r--OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs83
-rw-r--r--OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs72
-rw-r--r--OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs26
-rw-r--r--OpenSim/Services/Connectors/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs4
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs526
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs12
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs8
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs180
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs8
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs118
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs118
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs49
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs119
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs212
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs8
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs13
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs165
-rw-r--r--OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs57
-rw-r--r--OpenSim/Services/EstateService/EstateDataService.cs (renamed from OpenSim/Services/Connectors/Simulation/EstateDataService.cs)5
-rw-r--r--OpenSim/Services/FSAssetService/FSAssetService.cs723
-rw-r--r--OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/Friends/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/GridService/GridService.cs415
-rw-r--r--OpenSim/Services/GridService/HypergridLinker.cs236
-rw-r--r--OpenSim/Services/GridService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/HypergridService/GatekeeperService.cs121
-rw-r--r--OpenSim/Services/HypergridService/HGAssetService.cs34
-rw-r--r--OpenSim/Services/HypergridService/HGFSAssetService.cs189
-rw-r--r--OpenSim/Services/HypergridService/HGFriendsService.cs3
-rw-r--r--OpenSim/Services/HypergridService/HGInstantMessageService.cs19
-rw-r--r--OpenSim/Services/HypergridService/HGInventoryService.cs27
-rw-r--r--OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs258
-rw-r--r--OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/HypergridService/UserAccountCache.cs7
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs259
-rw-r--r--OpenSim/Services/HypergridService/UserAgentServiceBase.cs84
-rw-r--r--OpenSim/Services/Interfaces/IAgentPreferencesService.cs115
-rw-r--r--OpenSim/Services/Interfaces/IAssetService.cs9
-rw-r--r--OpenSim/Services/Interfaces/IAvatarService.cs46
-rw-r--r--OpenSim/Services/Interfaces/IBakedTextureService.cs38
-rw-r--r--OpenSim/Services/Interfaces/IBansService.cs48
-rw-r--r--OpenSim/Services/Interfaces/IEstateDataService.cs115
-rw-r--r--OpenSim/Services/Interfaces/IGridService.cs286
-rw-r--r--OpenSim/Services/Interfaces/IHypergridServices.cs66
-rw-r--r--OpenSim/Services/Interfaces/IInventoryService.cs36
-rw-r--r--OpenSim/Services/Interfaces/IMapImageService.cs1
-rw-r--r--OpenSim/Services/Interfaces/IOfflineIMService.cs7
-rw-r--r--OpenSim/Services/Interfaces/ISimulationService.cs39
-rw-r--r--OpenSim/Services/Interfaces/IUserAccountService.cs2
-rw-r--r--OpenSim/Services/Interfaces/IUserManagement.cs97
-rw-r--r--OpenSim/Services/Interfaces/IUserProfilesService.cs80
-rw-r--r--OpenSim/Services/Interfaces/OpenProfileClient.cs134
-rw-r--r--OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/InventoryService/LibraryService.cs1
-rw-r--r--OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/InventoryService/XInventoryService.cs172
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs83
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs166
-rw-r--r--OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/MapImageService/MapImageService.cs110
-rw-r--r--OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/PresenceService/PresenceService.cs87
-rw-r--r--OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/SimulationService/SimulationDataService.cs (renamed from OpenSim/Services/Connectors/Simulation/SimulationDataService.cs)13
-rw-r--r--OpenSim/Services/UserAccountService/AgentPreferencesService.cs82
-rw-r--r--OpenSim/Services/UserAccountService/AgentPreferencesServiceBase.cs73
-rw-r--r--OpenSim/Services/UserAccountService/GridUserService.cs127
-rw-r--r--OpenSim/Services/UserAccountService/GridUserServiceBase.cs10
-rw-r--r--OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs4
-rw-r--r--OpenSim/Services/UserAccountService/UserAccountService.cs56
-rw-r--r--OpenSim/Services/UserProfilesService/UserProfilesService.cs263
-rw-r--r--OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs87
101 files changed, 6856 insertions, 2171 deletions
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index e7eb6fe..0aefa16 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -123,53 +123,54 @@ namespace OpenSim.Services.AssetService
123 public virtual AssetMetadata GetMetadata(string id) 123 public virtual AssetMetadata GetMetadata(string id)
124 { 124 {
125// m_log.DebugFormat("[ASSET SERVICE]: Get asset metadata for {0}", id); 125// m_log.DebugFormat("[ASSET SERVICE]: Get asset metadata for {0}", id);
126
127 UUID assetID;
128 126
129 if (!UUID.TryParse(id, out assetID)) 127 AssetBase asset = Get(id);
130 return null;
131 128
132 AssetBase asset = m_Database.GetAsset(assetID);
133 if (asset != null) 129 if (asset != null)
134 return asset.Metadata; 130 return asset.Metadata;
135 131 else
136 return null; 132 return null;
137 } 133 }
138 134
139 public virtual byte[] GetData(string id) 135 public virtual byte[] GetData(string id)
140 { 136 {
141// m_log.DebugFormat("[ASSET SERVICE]: Get asset data for {0}", id); 137// m_log.DebugFormat("[ASSET SERVICE]: Get asset data for {0}", id);
142
143 UUID assetID;
144 138
145 if (!UUID.TryParse(id, out assetID)) 139 AssetBase asset = Get(id);
146 return null;
147 140
148 AssetBase asset = m_Database.GetAsset(assetID); 141 if (asset != null)
149 return asset.Data; 142 return asset.Data;
143 else
144 return null;
150 } 145 }
151 146
152 public virtual bool Get(string id, Object sender, AssetRetrieved handler) 147 public virtual bool Get(string id, Object sender, AssetRetrieved handler)
153 { 148 {
154 //m_log.DebugFormat("[AssetService]: Get asset async {0}", id); 149 //m_log.DebugFormat("[AssetService]: Get asset async {0}", id);
155
156 UUID assetID;
157 150
158 if (!UUID.TryParse(id, out assetID)) 151 handler(id, sender, Get(id));
159 return false;
160
161 AssetBase asset = m_Database.GetAsset(assetID);
162
163 //m_log.DebugFormat("[AssetService]: Got asset {0}", asset);
164
165 handler(id, sender, asset);
166 152
167 return true; 153 return true;
168 } 154 }
169 155
156 public virtual bool[] AssetsExist(string[] ids)
157 {
158 try
159 {
160 UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id));
161 return m_Database.AssetsExist(uuid);
162 }
163 catch (Exception e)
164 {
165 m_log.Error("[ASSET SERVICE]: Exception getting assets ", e);
166 return new bool[ids.Length];
167 }
168 }
169
170 public virtual string Store(AssetBase asset) 170 public virtual string Store(AssetBase asset)
171 { 171 {
172 if (!m_Database.ExistsAsset(asset.FullID)) 172 bool exists = m_Database.AssetsExist(new[] { asset.FullID })[0];
173 if (!exists)
173 { 174 {
174// m_log.DebugFormat( 175// m_log.DebugFormat(
175// "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length); 176// "[ASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
@@ -200,4 +201,4 @@ namespace OpenSim.Services.AssetService
200 return m_Database.Delete(id); 201 return m_Database.Delete(id);
201 } 202 }
202 } 203 }
203} \ No newline at end of file 204}
diff --git a/OpenSim/Services/AssetService/Properties/AssemblyInfo.cs b/OpenSim/Services/AssetService/Properties/AssemblyInfo.cs
index 1509400..63654a6 100644
--- a/OpenSim/Services/AssetService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/AssetService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs
index a1d10ed..b1e5184 100644
--- a/OpenSim/Services/AssetService/XAssetService.cs
+++ b/OpenSim/Services/AssetService/XAssetService.cs
@@ -39,16 +39,18 @@ using OpenMetaverse;
39namespace OpenSim.Services.AssetService 39namespace OpenSim.Services.AssetService
40{ 40{
41 /// <summary> 41 /// <summary>
42 /// This will be developed into a de-duplicating asset service. 42 /// A de-duplicating asset service.
43 /// XXX: Currently it's a just a copy of the existing AssetService. so please don't attempt to use it.
44 /// </summary> 43 /// </summary>
44 [Obsolete]
45 public class XAssetService : XAssetServiceBase, IAssetService 45 public class XAssetService : XAssetServiceBase, IAssetService
46 { 46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 48
49 protected static XAssetService m_RootInstance; 49 protected static XAssetService m_RootInstance;
50 50
51 public XAssetService(IConfigSource config) : base(config) 51 public XAssetService(IConfigSource config) : this(config, "AssetService") {}
52
53 public XAssetService(IConfigSource config, string configName) : base(config, configName)
52 { 54 {
53 if (m_RootInstance == null) 55 if (m_RootInstance == null)
54 { 56 {
@@ -56,22 +58,21 @@ namespace OpenSim.Services.AssetService
56 58
57 if (m_AssetLoader != null) 59 if (m_AssetLoader != null)
58 { 60 {
59 IConfig assetConfig = config.Configs["AssetService"]; 61 IConfig assetConfig = config.Configs[configName];
60 if (assetConfig == null) 62 if (assetConfig == null)
61 throw new Exception("No AssetService configuration"); 63 throw new Exception("No AssetService configuration");
62 64
63 string loaderArgs = assetConfig.GetString("AssetLoaderArgs", 65 string loaderArgs = assetConfig.GetString("AssetLoaderArgs", String.Empty);
64 String.Empty);
65 66
66 bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true); 67 bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true);
67 68
68 if (assetLoaderEnabled) 69 if (assetLoaderEnabled && !HasChainedAssetService)
69 { 70 {
70 m_log.DebugFormat("[XASSET SERVICE]: Loading default asset set from {0}", loaderArgs); 71 m_log.DebugFormat("[XASSET SERVICE]: Loading default asset set from {0}", loaderArgs);
71 72
72 m_AssetLoader.ForEachDefaultXmlAsset( 73 m_AssetLoader.ForEachDefaultXmlAsset(
73 loaderArgs, 74 loaderArgs,
74 delegate(AssetBase a) 75 a =>
75 { 76 {
76 AssetBase existingAsset = Get(a.ID); 77 AssetBase existingAsset = Get(a.ID);
77// AssetMetadata existingMetadata = GetMetadata(a.ID); 78// AssetMetadata existingMetadata = GetMetadata(a.ID);
@@ -85,6 +86,7 @@ namespace OpenSim.Services.AssetService
85 } 86 }
86 87
87 m_log.Debug("[XASSET SERVICE]: Local asset service enabled"); 88 m_log.Debug("[XASSET SERVICE]: Local asset service enabled");
89 m_log.Error("[XASSET SERVICE]: THIS ASSET SERVICE HAS BEEN MARKED OBSOLETE. PLEASE USE FSAssetService");
88 } 90 }
89 } 91 }
90 } 92 }
@@ -103,7 +105,23 @@ namespace OpenSim.Services.AssetService
103 105
104 try 106 try
105 { 107 {
106 return m_Database.GetAsset(assetID); 108 AssetBase asset = m_Database.GetAsset(assetID);
109
110 if (asset != null)
111 {
112 return asset;
113 }
114 else if (HasChainedAssetService)
115 {
116 asset = m_ChainedAssetService.Get(id);
117
118 if (asset != null)
119 MigrateFromChainedService(asset);
120
121 return asset;
122 }
123
124 return null;
107 } 125 }
108 catch (Exception e) 126 catch (Exception e)
109 { 127 {
@@ -120,30 +138,25 @@ namespace OpenSim.Services.AssetService
120 public virtual AssetMetadata GetMetadata(string id) 138 public virtual AssetMetadata GetMetadata(string id)
121 { 139 {
122// m_log.DebugFormat("[XASSET SERVICE]: Get asset metadata for {0}", id); 140// m_log.DebugFormat("[XASSET SERVICE]: Get asset metadata for {0}", id);
123
124 UUID assetID;
125 141
126 if (!UUID.TryParse(id, out assetID)) 142 AssetBase asset = Get(id);
127 return null;
128 143
129 AssetBase asset = m_Database.GetAsset(assetID);
130 if (asset != null) 144 if (asset != null)
131 return asset.Metadata; 145 return asset.Metadata;
132 146 else
133 return null; 147 return null;
134 } 148 }
135 149
136 public virtual byte[] GetData(string id) 150 public virtual byte[] GetData(string id)
137 { 151 {
138// m_log.DebugFormat("[XASSET SERVICE]: Get asset data for {0}", id); 152// m_log.DebugFormat("[XASSET SERVICE]: Get asset data for {0}", id);
139 153
140 UUID assetID; 154 AssetBase asset = Get(id);
141 155
142 if (!UUID.TryParse(id, out assetID)) 156 if (asset != null)
157 return asset.Data;
158 else
143 return null; 159 return null;
144
145 AssetBase asset = m_Database.GetAsset(assetID);
146 return asset.Data;
147 } 160 }
148 161
149 public virtual bool Get(string id, Object sender, AssetRetrieved handler) 162 public virtual bool Get(string id, Object sender, AssetRetrieved handler)
@@ -155,7 +168,7 @@ namespace OpenSim.Services.AssetService
155 if (!UUID.TryParse(id, out assetID)) 168 if (!UUID.TryParse(id, out assetID))
156 return false; 169 return false;
157 170
158 AssetBase asset = m_Database.GetAsset(assetID); 171 AssetBase asset = Get(id);
159 172
160 //m_log.DebugFormat("[XASSET SERVICE]: Got asset {0}", asset); 173 //m_log.DebugFormat("[XASSET SERVICE]: Got asset {0}", asset);
161 174
@@ -164,9 +177,16 @@ namespace OpenSim.Services.AssetService
164 return true; 177 return true;
165 } 178 }
166 179
180 public virtual bool[] AssetsExist(string[] ids)
181 {
182 UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id));
183 return m_Database.AssetsExist(uuid);
184 }
185
167 public virtual string Store(AssetBase asset) 186 public virtual string Store(AssetBase asset)
168 { 187 {
169 if (!m_Database.ExistsAsset(asset.FullID)) 188 bool exists = m_Database.AssetsExist(new[] { asset.FullID })[0];
189 if (!exists)
170 { 190 {
171// m_log.DebugFormat( 191// m_log.DebugFormat(
172// "[XASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length); 192// "[XASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
@@ -194,7 +214,16 @@ namespace OpenSim.Services.AssetService
194 if (!UUID.TryParse(id, out assetID)) 214 if (!UUID.TryParse(id, out assetID))
195 return false; 215 return false;
196 216
217 if (HasChainedAssetService)
218 m_ChainedAssetService.Delete(id);
219
197 return m_Database.Delete(id); 220 return m_Database.Delete(id);
198 } 221 }
222
223 private void MigrateFromChainedService(AssetBase asset)
224 {
225 Store(asset);
226 m_ChainedAssetService.Delete(asset.ID);
227 }
199 } 228 }
200} \ No newline at end of file 229}
diff --git a/OpenSim/Services/AssetService/XAssetServiceBase.cs b/OpenSim/Services/AssetService/XAssetServiceBase.cs
index 0c5c2c3..c118c9d 100644
--- a/OpenSim/Services/AssetService/XAssetServiceBase.cs
+++ b/OpenSim/Services/AssetService/XAssetServiceBase.cs
@@ -27,9 +27,11 @@
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using log4net;
30using Nini.Config; 31using Nini.Config;
31using OpenSim.Framework; 32using OpenSim.Framework;
32using OpenSim.Data; 33using OpenSim.Data;
34using OpenSim.Server.Base;
33using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
34using OpenSim.Services.Base; 36using OpenSim.Services.Base;
35 37
@@ -37,10 +39,15 @@ namespace OpenSim.Services.AssetService
37{ 39{
38 public class XAssetServiceBase : ServiceBase 40 public class XAssetServiceBase : ServiceBase
39 { 41 {
40 protected IXAssetDataPlugin m_Database = null; 42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
41 protected IAssetLoader m_AssetLoader = null;
42 43
43 public XAssetServiceBase(IConfigSource config) : base(config) 44 protected IXAssetDataPlugin m_Database;
45 protected IAssetLoader m_AssetLoader;
46 protected IAssetService m_ChainedAssetService;
47
48 protected bool HasChainedAssetService { get { return m_ChainedAssetService != null; } }
49
50 public XAssetServiceBase(IConfigSource config, string configName) : base(config)
44 { 51 {
45 string dllName = String.Empty; 52 string dllName = String.Empty;
46 string connString = String.Empty; 53 string connString = String.Empty;
@@ -48,7 +55,7 @@ namespace OpenSim.Services.AssetService
48 // 55 //
49 // Try reading the [AssetService] section first, if it exists 56 // Try reading the [AssetService] section first, if it exists
50 // 57 //
51 IConfig assetConfig = config.Configs["AssetService"]; 58 IConfig assetConfig = config.Configs[configName];
52 if (assetConfig != null) 59 if (assetConfig != null)
53 { 60 {
54 dllName = assetConfig.GetString("StorageProvider", dllName); 61 dllName = assetConfig.GetString("StorageProvider", dllName);
@@ -77,17 +84,35 @@ namespace OpenSim.Services.AssetService
77 if (m_Database == null) 84 if (m_Database == null)
78 throw new Exception("Could not find a storage interface in the given module"); 85 throw new Exception("Could not find a storage interface in the given module");
79 86
80 m_Database.Initialise(connString); 87 string chainedAssetServiceDesignator = assetConfig.GetString("ChainedServiceModule", null);
88
89 if (chainedAssetServiceDesignator != null)
90 {
91 m_log.InfoFormat(
92 "[XASSET SERVICE BASE]: Loading chained asset service from {0}", chainedAssetServiceDesignator);
81 93
82 string loaderName = assetConfig.GetString("DefaultAssetLoader", 94 Object[] args = new Object[] { config, configName };
83 String.Empty); 95 m_ChainedAssetService = ServerUtils.LoadPlugin<IAssetService>(chainedAssetServiceDesignator, args);
84 96
85 if (loaderName != String.Empty) 97 if (!HasChainedAssetService)
98 throw new Exception(
99 String.Format("Failed to load ChainedAssetService from {0}", chainedAssetServiceDesignator));
100 }
101
102 m_Database.Initialise(connString);
103
104 if (HasChainedAssetService)
86 { 105 {
87 m_AssetLoader = LoadPlugin<IAssetLoader>(loaderName); 106 string loaderName = assetConfig.GetString("DefaultAssetLoader",
107 String.Empty);
108
109 if (loaderName != String.Empty)
110 {
111 m_AssetLoader = LoadPlugin<IAssetLoader>(loaderName);
88 112
89 if (m_AssetLoader == null) 113 if (m_AssetLoader == null)
90 throw new Exception("Asset loader could not be loaded"); 114 throw new Exception("Asset loader could not be loaded");
115 }
91 } 116 }
92 } 117 }
93 } 118 }
diff --git a/OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs b/OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs
index 0eb2ba7..f25accc 100644
--- a/OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs b/OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs
index 6d6b11e..47d47ab 100644
--- a/OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs b/OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs
index 0944149..a233d8a 100644
--- a/OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/Base/Properties/AssemblyInfo.cs b/OpenSim/Services/Base/Properties/AssemblyInfo.cs
index 306b699..b113c42 100644
--- a/OpenSim/Services/Base/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/Base/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/Base/ServiceBase.cs b/OpenSim/Services/Base/ServiceBase.cs
index ef30cba..a7eb2be 100644
--- a/OpenSim/Services/Base/ServiceBase.cs
+++ b/OpenSim/Services/Base/ServiceBase.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
30using System.Reflection; 31using System.Reflection;
31using log4net; 32using log4net;
32using Nini.Config; 33using Nini.Config;
@@ -45,9 +46,15 @@ namespace OpenSim.Services.Base
45 46
46 public T LoadPlugin<T>(string dllName, Object[] args) where T:class 47 public T LoadPlugin<T>(string dllName, Object[] args) where T:class
47 { 48 {
48 string[] parts = dllName.Split(new char[] {':'}); 49 // The path:type separator : is unfortunate because it collides
50 // with Windows paths like C:\...
51 // When the path provided includes the drive, this fails.
52 // Hence the root/noroot thing going on here.
53 string pathRoot = Path.GetPathRoot(dllName);
54 string noRoot = dllName.Substring(pathRoot.Length);
55 string[] parts = noRoot.Split(new char[] {':'});
49 56
50 dllName = parts[0]; 57 dllName = pathRoot + parts[0];
51 58
52 string className = String.Empty; 59 string className = String.Empty;
53 60
@@ -79,7 +86,7 @@ namespace OpenSim.Services.Base
79 continue; 86 continue;
80 87
81 Type typeInterface = 88 Type typeInterface =
82 pluginType.GetInterface(interfaceName, true); 89 pluginType.GetInterface(interfaceName);
83 if (typeInterface != null) 90 if (typeInterface != null)
84 { 91 {
85 T plug = (T)Activator.CreateInstance(pluginType, 92 T plug = (T)Activator.CreateInstance(pluginType,
diff --git a/OpenSim/Services/Connectors/AgentPreferences/AgentPreferencesConnector.cs b/OpenSim/Services/Connectors/AgentPreferences/AgentPreferencesConnector.cs
new file mode 100644
index 0000000..1dbc0c8
--- /dev/null
+++ b/OpenSim/Services/Connectors/AgentPreferences/AgentPreferencesConnector.cs
@@ -0,0 +1,230 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Framework.ServiceAuth;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38using IAvatarService = OpenSim.Services.Interfaces.IAvatarService;
39using OpenSim.Server.Base;
40using OpenMetaverse;
41
42namespace OpenSim.Services.Connectors
43{
44 public class AgentPreferencesServicesConnector : BaseServiceConnector, IAgentPreferencesService
45 {
46 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47
48 private string m_ServerURI = String.Empty;
49
50 public AgentPreferencesServicesConnector()
51 {
52 }
53
54 public AgentPreferencesServicesConnector(string serverURI)
55 {
56 m_ServerURI = serverURI.TrimEnd('/');
57 }
58
59 public AgentPreferencesServicesConnector(IConfigSource source)
60 : base(source, "AgentPreferencesService")
61 {
62 Initialise(source);
63 }
64
65 public virtual void Initialise(IConfigSource source)
66 {
67 IConfig gridConfig = source.Configs["AgentPreferencesService"];
68 if (gridConfig == null)
69 {
70 m_log.Error("[AGENT PREFERENCES CONNECTOR]: AgentPreferencesService missing from OpenSim.ini");
71 throw new Exception("Agent Preferences connector init error");
72 }
73
74 string serviceURI = gridConfig.GetString("AgentPreferencesServerURI", String.Empty);
75
76 if (serviceURI == String.Empty)
77 {
78 m_log.Error("[AGENT PREFERENCES CONNECTOR]: No Server URI named in section AgentPreferences");
79 throw new Exception("Agent Preferences connector init error");
80 }
81 m_ServerURI = serviceURI;
82
83 base.Initialise(source, "AgentPreferencesService");
84 }
85
86 #region IAgentPreferencesService
87
88 public AgentPrefs GetAgentPreferences(UUID principalID)
89 {
90 Dictionary<string, object> sendData = new Dictionary<string, object>();
91
92 string reply = string.Empty;
93 string uri = String.Concat(m_ServerURI, "/agentprefs");
94
95 sendData["METHOD"] = "getagentprefs";
96 sendData["UserID"] = principalID;
97 string reqString = ServerUtils.BuildQueryString(sendData);
98 // m_log.DebugFormat("[AGENT PREFS CONNECTOR]: queryString = {0}", reqString);
99
100 try
101 {
102 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
103 if (String.IsNullOrEmpty(reply))
104 {
105 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: GetAgentPreferences received null or empty reply");
106 return null;
107 }
108 }
109 catch (Exception e)
110 {
111 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: Exception when contacting agent preferences server at {0}: {1}", uri, e.Message);
112 }
113
114 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
115 if (replyData != null)
116 {
117 if (replyData.ContainsKey("result") &&
118 (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure"))
119 {
120 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: GetAgentPreferences received Failure response");
121 return null;
122 }
123 }
124 else
125 {
126 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: GetAgentPreferences received null response");
127 return null;
128 }
129 AgentPrefs prefs = new AgentPrefs(replyData);
130 return prefs;
131 }
132
133 public bool StoreAgentPreferences(AgentPrefs data)
134 {
135 Dictionary<string, object> sendData = new Dictionary<string, object>();
136
137 sendData["METHOD"] = "setagentprefs";
138
139 sendData["PrincipalID"] = data.PrincipalID.ToString();
140 sendData["AccessPrefs"] = data.AccessPrefs;
141 sendData["HoverHeight"] = data.HoverHeight.ToString();
142 sendData["Language"] = data.Language;
143 sendData["LanguageIsPublic"] = data.LanguageIsPublic.ToString();
144 sendData["PermEveryone"] = data.PermEveryone.ToString();
145 sendData["PermGroup"] = data.PermGroup.ToString();
146 sendData["PermNextOwner"] = data.PermNextOwner.ToString();
147
148 string uri = String.Concat(m_ServerURI, "/agentprefs");
149 string reqString = ServerUtils.BuildQueryString(sendData);
150 // m_log.DebugFormat("[AGENT PREFS CONNECTOR]: queryString = {0}", reqString);
151
152 try
153 {
154 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
155 if (reply != string.Empty)
156 {
157 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
158
159 if (replyData.ContainsKey("result"))
160 {
161 if (replyData["result"].ToString().ToLower() == "success")
162 return true;
163 else
164 return false;
165 }
166 else
167 {
168 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: StoreAgentPreferences reply data does not contain result field");
169 }
170
171 }
172 else
173 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: StoreAgentPreferences received empty reply");
174 }
175 catch (Exception e)
176 {
177 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: Exception when contacting agent preferences server at {0}: {1}", uri, e.Message);
178 }
179
180 return false;
181 }
182
183 public string GetLang(UUID principalID)
184 {
185 Dictionary<string, object> sendData = new Dictionary<string, object>();
186 string reply = string.Empty;
187
188 sendData["METHOD"] = "getagentlang";
189 sendData["UserID"] = principalID.ToString();
190
191 string uri = String.Concat(m_ServerURI, "/agentprefs");
192 string reqString = ServerUtils.BuildQueryString(sendData);
193
194 try
195 {
196 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
197 if (String.IsNullOrEmpty(reply))
198 {
199 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: GetLang received null or empty reply");
200 return "en-us"; // I guess? Gotta return somethin'!
201 }
202 }
203 catch (Exception e)
204 {
205 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: Exception when contacting agent preferences server at {0}: {1}", uri, e.Message);
206 }
207
208 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
209 if (replyData != null)
210 {
211 if (replyData.ContainsKey("result") &&
212 (replyData["result"].ToString() == "null" || replyData["result"].ToString() == "Failure"))
213 {
214 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: GetLang received Failure response");
215 return "en-us";
216 }
217 if (replyData.ContainsKey("Language"))
218 return replyData["Language"].ToString();
219 }
220 else
221 {
222 m_log.DebugFormat("[AGENT PREFERENCES CONNECTOR]: GetLang received null response");
223
224 }
225 return "en-us";
226 }
227
228 #endregion IAgentPreferencesService
229 }
230}
diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
index 2b2f11f..bd43552 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs
@@ -33,13 +33,12 @@ using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Console; 35using OpenSim.Framework.Console;
36using OpenSim.Framework.Communications;
37using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
38using OpenMetaverse; 37using OpenMetaverse;
39 38
40namespace OpenSim.Services.Connectors 39namespace OpenSim.Services.Connectors
41{ 40{
42 public class AssetServicesConnector : IAssetService 41 public class AssetServicesConnector : BaseServiceConnector, IAssetService
43 { 42 {
44 private static readonly ILog m_log = 43 private static readonly ILog m_log =
45 LogManager.GetLogger( 44 LogManager.GetLogger(
@@ -55,6 +54,11 @@ namespace OpenSim.Services.Connectors
55 // Maps: Asset ID -> Handlers which will be called when the asset has been loaded 54 // Maps: Asset ID -> Handlers which will be called when the asset has been loaded
56 private Dictionary<string, AssetRetrievedEx> m_AssetHandlers = new Dictionary<string, AssetRetrievedEx>(); 55 private Dictionary<string, AssetRetrievedEx> m_AssetHandlers = new Dictionary<string, AssetRetrievedEx>();
57 56
57 public int MaxAssetRequestConcurrency
58 {
59 get { return m_maxAssetRequestConcurrency; }
60 set { m_maxAssetRequestConcurrency = value; }
61 }
58 62
59 public AssetServicesConnector() 63 public AssetServicesConnector()
60 { 64 {
@@ -66,6 +70,7 @@ namespace OpenSim.Services.Connectors
66 } 70 }
67 71
68 public AssetServicesConnector(IConfigSource source) 72 public AssetServicesConnector(IConfigSource source)
73 : base(source, "AssetService")
69 { 74 {
70 Initialise(source); 75 Initialise(source);
71 } 76 }
@@ -112,8 +117,16 @@ namespace OpenSim.Services.Connectors
112 117
113 if (asset == null) 118 if (asset == null)
114 { 119 {
115 asset = SynchronousRestObjectRequester. 120 // XXX: Commented out for now since this has either never been properly operational or not for some time
116 MakeRequest<int, AssetBase>("GET", uri, 0, m_maxAssetRequestConcurrency); 121 // as m_maxAssetRequestConcurrency was being passed as the timeout, not a concurrency limiting option.
122 // Wasn't noticed before because timeout wasn't actually used.
123 // Not attempting concurrency setting for now as this omission was discovered in release candidate
124 // phase for OpenSimulator 0.8. Need to revisit afterwards.
125// asset
126// = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>(
127// "GET", uri, 0, m_maxAssetRequestConcurrency);
128
129 asset = SynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0, m_Auth);
117 130
118 if (m_Cache != null) 131 if (m_Cache != null)
119 m_Cache.Cache(asset); 132 m_Cache.Cache(asset);
@@ -143,8 +156,7 @@ namespace OpenSim.Services.Connectors
143 156
144 string uri = m_ServerURI + "/assets/" + id + "/metadata"; 157 string uri = m_ServerURI + "/assets/" + id + "/metadata";
145 158
146 AssetMetadata asset = SynchronousRestObjectRequester. 159 AssetMetadata asset = SynchronousRestObjectRequester.MakeRequest<int, AssetMetadata>("GET", uri, 0, m_Auth);
147 MakeRequest<int, AssetMetadata>("GET", uri, 0);
148 return asset; 160 return asset;
149 } 161 }
150 162
@@ -158,27 +170,29 @@ namespace OpenSim.Services.Connectors
158 return fullAsset.Data; 170 return fullAsset.Data;
159 } 171 }
160 172
161 RestClient rc = new RestClient(m_ServerURI); 173 using (RestClient rc = new RestClient(m_ServerURI))
162 rc.AddResourcePath("assets"); 174 {
163 rc.AddResourcePath(id); 175 rc.AddResourcePath("assets");
164 rc.AddResourcePath("data"); 176 rc.AddResourcePath(id);
177 rc.AddResourcePath("data");
165 178
166 rc.RequestMethod = "GET"; 179 rc.RequestMethod = "GET";
167 180
168 Stream s = rc.Request(); 181 Stream s = rc.Request(m_Auth);
169 182
170 if (s == null) 183 if (s == null)
171 return null; 184 return null;
172 185
173 if (s.Length > 0) 186 if (s.Length > 0)
174 { 187 {
175 byte[] ret = new byte[s.Length]; 188 byte[] ret = new byte[s.Length];
176 s.Read(ret, 0, (int)s.Length); 189 s.Read(ret, 0, (int)s.Length);
177 190
178 return ret; 191 return ret;
179 } 192 }
180 193
181 return null; 194 return null;
195 }
182 } 196 }
183 197
184 public bool Get(string id, Object sender, AssetRetrieved handler) 198 public bool Get(string id, Object sender, AssetRetrieved handler)
@@ -216,7 +230,7 @@ namespace OpenSim.Services.Connectors
216 AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0, 230 AsynchronousRestObjectRequester.MakeRequest<int, AssetBase>("GET", uri, 0,
217 delegate(AssetBase a) 231 delegate(AssetBase a)
218 { 232 {
219 if (m_Cache != null) 233 if (a != null && m_Cache != null)
220 m_Cache.Cache(a); 234 m_Cache.Cache(a);
221 235
222 AssetRetrievedEx handlers; 236 AssetRetrievedEx handlers;
@@ -226,7 +240,7 @@ namespace OpenSim.Services.Connectors
226 m_AssetHandlers.Remove(id); 240 m_AssetHandlers.Remove(id);
227 } 241 }
228 handlers.Invoke(a); 242 handlers.Invoke(a);
229 }, m_maxAssetRequestConcurrency); 243 }, m_maxAssetRequestConcurrency, m_Auth);
230 244
231 success = true; 245 success = true;
232 } 246 }
@@ -249,9 +263,30 @@ namespace OpenSim.Services.Connectors
249 return true; 263 return true;
250 } 264 }
251 265
266 public virtual bool[] AssetsExist(string[] ids)
267 {
268 string uri = m_ServerURI + "/get_assets_exist";
269
270 bool[] exist = null;
271 try
272 {
273 exist = SynchronousRestObjectRequester.MakeRequest<string[], bool[]>("POST", uri, ids, m_Auth);
274 }
275 catch (Exception)
276 {
277 // This is most likely to happen because the server doesn't support this function,
278 // so just silently return "doesn't exist" for all the assets.
279 }
280
281 if (exist == null)
282 exist = new bool[ids.Length];
283
284 return exist;
285 }
286
252 public string Store(AssetBase asset) 287 public string Store(AssetBase asset)
253 { 288 {
254 if (asset.Temporary || asset.Local) 289 if (asset.Local)
255 { 290 {
256 if (m_Cache != null) 291 if (m_Cache != null)
257 m_Cache.Cache(asset); 292 m_Cache.Cache(asset);
@@ -261,27 +296,32 @@ namespace OpenSim.Services.Connectors
261 296
262 string uri = m_ServerURI + "/assets/"; 297 string uri = m_ServerURI + "/assets/";
263 298
264 string newID = string.Empty; 299 string newID;
265 try 300 try
266 { 301 {
267 newID = SynchronousRestObjectRequester. 302 newID = SynchronousRestObjectRequester.MakeRequest<AssetBase, string>("POST", uri, asset, m_Auth);
268 MakeRequest<AssetBase, string>("POST", uri, asset);
269 } 303 }
270 catch (Exception e) 304 catch (Exception e)
271 { 305 {
272 m_log.WarnFormat("[ASSET CONNECTOR]: Unable to send asset {0} to asset server. Reason: {1}", asset.ID, e.Message); 306 m_log.Warn(string.Format("[ASSET CONNECTOR]: Unable to send asset {0} to asset server. Reason: {1} ", asset.ID, e.Message), e);
307 return string.Empty;
273 } 308 }
274 309
275 if (newID != String.Empty) 310 // TEMPORARY: SRAS returns 'null' when it's asked to store existing assets
311 if (newID == null)
276 { 312 {
277 // Placing this here, so that this work with old asset servers that don't send any reply back 313 m_log.DebugFormat("[ASSET CONNECTOR]: Storing of asset {0} returned null; assuming the asset already exists", asset.ID);
278 // SynchronousRestObjectRequester returns somethins that is not an empty string 314 return asset.ID;
279 if (newID != null)
280 asset.ID = newID;
281
282 if (m_Cache != null)
283 m_Cache.Cache(asset);
284 } 315 }
316
317 if (string.IsNullOrEmpty(newID))
318 return string.Empty;
319
320 asset.ID = newID;
321
322 if (m_Cache != null)
323 m_Cache.Cache(asset);
324
285 return newID; 325 return newID;
286 } 326 }
287 327
@@ -305,8 +345,7 @@ namespace OpenSim.Services.Connectors
305 345
306 string uri = m_ServerURI + "/assets/" + id; 346 string uri = m_ServerURI + "/assets/" + id;
307 347
308 if (SynchronousRestObjectRequester. 348 if (SynchronousRestObjectRequester.MakeRequest<AssetBase, bool>("POST", uri, asset, m_Auth))
309 MakeRequest<AssetBase, bool>("POST", uri, asset))
310 { 349 {
311 if (m_Cache != null) 350 if (m_Cache != null)
312 m_Cache.Cache(asset); 351 m_Cache.Cache(asset);
@@ -320,8 +359,7 @@ namespace OpenSim.Services.Connectors
320 { 359 {
321 string uri = m_ServerURI + "/assets/" + id; 360 string uri = m_ServerURI + "/assets/" + id;
322 361
323 if (SynchronousRestObjectRequester. 362 if (SynchronousRestObjectRequester.MakeRequest<int, bool>("DELETE", uri, 0, m_Auth))
324 MakeRequest<int, bool>("DELETE", uri, 0))
325 { 363 {
326 if (m_Cache != null) 364 if (m_Cache != null)
327 m_Cache.Expire(id); 365 m_Cache.Expire(id);
diff --git a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
index c395178..3710c86 100644
--- a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
@@ -36,6 +36,7 @@ using OpenSim.Framework;
36using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
37using OpenSim.Services.Connectors.Hypergrid; 37using OpenSim.Services.Connectors.Hypergrid;
38using OpenSim.Services.Connectors.SimianGrid; 38using OpenSim.Services.Connectors.SimianGrid;
39using OpenMetaverse;
39 40
40namespace OpenSim.Services.Connectors 41namespace OpenSim.Services.Connectors
41{ 42{
@@ -83,39 +84,6 @@ namespace OpenSim.Services.Connectors
83 } 84 }
84 } 85 }
85 86
86 private bool StringToUrlAndAssetID(string id, out string url, out string assetID)
87 {
88 url = String.Empty;
89 assetID = String.Empty;
90
91 Uri assetUri;
92
93 if (Uri.TryCreate(id, UriKind.Absolute, out assetUri) &&
94 assetUri.Scheme == Uri.UriSchemeHttp)
95 {
96 // Simian
97 if (assetUri.Query != string.Empty)
98 {
99 NameValueCollection qscoll = HttpUtility.ParseQueryString(assetUri.Query);
100 assetID = qscoll["id"];
101 if (assetID != null)
102 url = id.Replace(assetID, ""); // Malformed again, as simian expects
103 else
104 url = id; // !!! best effort
105 }
106 else // robust
107 {
108 url = "http://" + assetUri.Authority;
109 assetID = assetUri.LocalPath.Trim(new char[] { '/' });
110 }
111
112 return true;
113 }
114
115 m_log.DebugFormat("[HG ASSET SERVICE]: Malformed URL {0}", id);
116 return false;
117 }
118
119 private IAssetService GetConnector(string url) 87 private IAssetService GetConnector(string url)
120 { 88 {
121 IAssetService connector = null; 89 IAssetService connector = null;
@@ -149,7 +117,7 @@ namespace OpenSim.Services.Connectors
149 string url = string.Empty; 117 string url = string.Empty;
150 string assetID = string.Empty; 118 string assetID = string.Empty;
151 119
152 if (StringToUrlAndAssetID(id, out url, out assetID)) 120 if (Util.ParseForeignAssetID(id, out url, out assetID))
153 { 121 {
154 IAssetService connector = GetConnector(url); 122 IAssetService connector = GetConnector(url);
155 return connector.Get(assetID); 123 return connector.Get(assetID);
@@ -163,7 +131,7 @@ namespace OpenSim.Services.Connectors
163 string url = string.Empty; 131 string url = string.Empty;
164 string assetID = string.Empty; 132 string assetID = string.Empty;
165 133
166 if (StringToUrlAndAssetID(id, out url, out assetID)) 134 if (Util.ParseForeignAssetID(id, out url, out assetID))
167 { 135 {
168 IAssetService connector = GetConnector(url); 136 IAssetService connector = GetConnector(url);
169 return connector.GetCached(assetID); 137 return connector.GetCached(assetID);
@@ -177,7 +145,7 @@ namespace OpenSim.Services.Connectors
177 string url = string.Empty; 145 string url = string.Empty;
178 string assetID = string.Empty; 146 string assetID = string.Empty;
179 147
180 if (StringToUrlAndAssetID(id, out url, out assetID)) 148 if (Util.ParseForeignAssetID(id, out url, out assetID))
181 { 149 {
182 IAssetService connector = GetConnector(url); 150 IAssetService connector = GetConnector(url);
183 return connector.GetMetadata(assetID); 151 return connector.GetMetadata(assetID);
@@ -196,7 +164,7 @@ namespace OpenSim.Services.Connectors
196 string url = string.Empty; 164 string url = string.Empty;
197 string assetID = string.Empty; 165 string assetID = string.Empty;
198 166
199 if (StringToUrlAndAssetID(id, out url, out assetID)) 167 if (Util.ParseForeignAssetID(id, out url, out assetID))
200 { 168 {
201 IAssetService connector = GetConnector(url); 169 IAssetService connector = GetConnector(url);
202 return connector.Get(assetID, sender, handler); 170 return connector.Get(assetID, sender, handler);
@@ -205,12 +173,72 @@ namespace OpenSim.Services.Connectors
205 return false; 173 return false;
206 } 174 }
207 175
176
177 private struct AssetAndIndex
178 {
179 public UUID assetID;
180 public int index;
181
182 public AssetAndIndex(UUID assetID, int index)
183 {
184 this.assetID = assetID;
185 this.index = index;
186 }
187 }
188
189 public virtual bool[] AssetsExist(string[] ids)
190 {
191 // This method is a bit complicated because it works even if the assets belong to different
192 // servers; that requires sending separate requests to each server.
193
194 // Group the assets by the server they belong to
195
196 var url2assets = new Dictionary<string, List<AssetAndIndex>>();
197
198 for (int i = 0; i < ids.Length; i++)
199 {
200 string url = string.Empty;
201 string assetID = string.Empty;
202
203 if (Util.ParseForeignAssetID(ids[i], out url, out assetID))
204 {
205 if (!url2assets.ContainsKey(url))
206 url2assets.Add(url, new List<AssetAndIndex>());
207 url2assets[url].Add(new AssetAndIndex(UUID.Parse(assetID), i));
208 }
209 }
210
211 // Query each of the servers in turn
212
213 bool[] exist = new bool[ids.Length];
214
215 foreach (string url in url2assets.Keys)
216 {
217 IAssetService connector = GetConnector(url);
218 lock (EndPointLock(connector))
219 {
220 List<AssetAndIndex> curAssets = url2assets[url];
221 string[] assetIDs = curAssets.ConvertAll(a => a.assetID.ToString()).ToArray();
222 bool[] curExist = connector.AssetsExist(assetIDs);
223
224 int i = 0;
225 foreach (AssetAndIndex ai in curAssets)
226 {
227 exist[ai.index] = curExist[i];
228 ++i;
229 }
230 }
231 }
232
233 return exist;
234 }
235
208 public string Store(AssetBase asset) 236 public string Store(AssetBase asset)
209 { 237 {
210 string url = string.Empty; 238 string url = string.Empty;
211 string assetID = string.Empty; 239 string assetID = string.Empty;
212 240
213 if (StringToUrlAndAssetID(asset.ID, out url, out assetID)) 241 if (Util.ParseForeignAssetID(asset.ID, out url, out assetID))
214 { 242 {
215 IAssetService connector = GetConnector(url); 243 IAssetService connector = GetConnector(url);
216 // Restore the assetID to a simple UUID 244 // Restore the assetID to a simple UUID
diff --git a/OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs b/OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs
index 2b77154..c8a4912 100644
--- a/OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Authentication/AuthenticationServicesConnector.cs
@@ -32,14 +32,14 @@ using System.IO;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35using OpenSim.Framework.ServiceAuth;
36using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
37using OpenSim.Server.Base; 37using OpenSim.Server.Base;
38using OpenMetaverse; 38using OpenMetaverse;
39 39
40namespace OpenSim.Services.Connectors 40namespace OpenSim.Services.Connectors
41{ 41{
42 public class AuthenticationServicesConnector : IAuthenticationService 42 public class AuthenticationServicesConnector : BaseServiceConnector, IAuthenticationService
43 { 43 {
44 private static readonly ILog m_log = 44 private static readonly ILog m_log =
45 LogManager.GetLogger( 45 LogManager.GetLogger(
@@ -57,6 +57,7 @@ namespace OpenSim.Services.Connectors
57 } 57 }
58 58
59 public AuthenticationServicesConnector(IConfigSource source) 59 public AuthenticationServicesConnector(IConfigSource source)
60 : base(source, "AuthenticationService")
60 { 61 {
61 Initialise(source); 62 Initialise(source);
62 } 63 }
@@ -79,6 +80,8 @@ namespace OpenSim.Services.Connectors
79 throw new Exception("Authentication connector init error"); 80 throw new Exception("Authentication connector init error");
80 } 81 }
81 m_ServerURI = serviceURI; 82 m_ServerURI = serviceURI;
83
84 base.Initialise(source, "AuthenticationService");
82 } 85 }
83 86
84 public string Authenticate(UUID principalID, string password, int lifetime) 87 public string Authenticate(UUID principalID, string password, int lifetime)
@@ -92,7 +95,7 @@ namespace OpenSim.Services.Connectors
92 95
93 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 96 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
94 m_ServerURI + "/auth/plain", 97 m_ServerURI + "/auth/plain",
95 ServerUtils.BuildQueryString(sendData)); 98 ServerUtils.BuildQueryString(sendData), m_Auth);
96 99
97 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( 100 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
98 reply); 101 reply);
@@ -105,6 +108,7 @@ namespace OpenSim.Services.Connectors
105 108
106 public bool Verify(UUID principalID, string token, int lifetime) 109 public bool Verify(UUID principalID, string token, int lifetime)
107 { 110 {
111// m_log.Error("[XXX]: Verify");
108 Dictionary<string, object> sendData = new Dictionary<string, object>(); 112 Dictionary<string, object> sendData = new Dictionary<string, object>();
109 sendData["LIFETIME"] = lifetime.ToString(); 113 sendData["LIFETIME"] = lifetime.ToString();
110 sendData["PRINCIPAL"] = principalID.ToString(); 114 sendData["PRINCIPAL"] = principalID.ToString();
@@ -114,7 +118,7 @@ namespace OpenSim.Services.Connectors
114 118
115 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 119 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
116 m_ServerURI + "/auth/plain", 120 m_ServerURI + "/auth/plain",
117 ServerUtils.BuildQueryString(sendData)); 121 ServerUtils.BuildQueryString(sendData), m_Auth);
118 122
119 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( 123 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
120 reply); 124 reply);
@@ -135,7 +139,7 @@ namespace OpenSim.Services.Connectors
135 139
136 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 140 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
137 m_ServerURI + "/auth/plain", 141 m_ServerURI + "/auth/plain",
138 ServerUtils.BuildQueryString(sendData)); 142 ServerUtils.BuildQueryString(sendData), m_Auth);
139 143
140 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( 144 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
141 reply); 145 reply);
diff --git a/OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs b/OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs
index 35b7109..d2da85f 100644
--- a/OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Authorization/AuthorizationServicesConnector.cs
@@ -32,7 +32,6 @@ using System.IO;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications;
36using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
37using OpenMetaverse; 36using OpenMetaverse;
38 37
@@ -105,7 +104,7 @@ namespace OpenSim.Services.Connectors
105 catch (Exception e) 104 catch (Exception e)
106 { 105 {
107 m_log.WarnFormat("[AUTHORIZATION CONNECTOR]: Unable to send authorize {0} for region {1} error thrown during comms with remote server. Reason: {2}", userID, regionID, e.Message); 106 m_log.WarnFormat("[AUTHORIZATION CONNECTOR]: Unable to send authorize {0} for region {1} error thrown during comms with remote server. Reason: {2}", userID, regionID, e.Message);
108 message = ""; 107 message = e.Message;
109 return m_ResponseOnFailure; 108 return m_ResponseOnFailure;
110 } 109 }
111 if (response == null) 110 if (response == null)
diff --git a/OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs b/OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs
index ddfca57..3f44efa 100644
--- a/OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Avatar/AvatarServicesConnector.cs
@@ -32,7 +32,7 @@ using System.IO;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35using OpenSim.Framework.ServiceAuth;
36using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion; 37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38using IAvatarService = OpenSim.Services.Interfaces.IAvatarService; 38using IAvatarService = OpenSim.Services.Interfaces.IAvatarService;
@@ -41,7 +41,7 @@ using OpenMetaverse;
41 41
42namespace OpenSim.Services.Connectors 42namespace OpenSim.Services.Connectors
43{ 43{
44 public class AvatarServicesConnector : IAvatarService 44 public class AvatarServicesConnector : BaseServiceConnector, IAvatarService
45 { 45 {
46 private static readonly ILog m_log = 46 private static readonly ILog m_log =
47 LogManager.GetLogger( 47 LogManager.GetLogger(
@@ -59,6 +59,7 @@ namespace OpenSim.Services.Connectors
59 } 59 }
60 60
61 public AvatarServicesConnector(IConfigSource source) 61 public AvatarServicesConnector(IConfigSource source)
62 : base(source, "AvatarService")
62 { 63 {
63 Initialise(source); 64 Initialise(source);
64 } 65 }
@@ -81,6 +82,8 @@ namespace OpenSim.Services.Connectors
81 throw new Exception("Avatar connector init error"); 82 throw new Exception("Avatar connector init error");
82 } 83 }
83 m_ServerURI = serviceURI; 84 m_ServerURI = serviceURI;
85
86 base.Initialise(source, "AvatarService");
84 } 87 }
85 88
86 89
@@ -114,7 +117,7 @@ namespace OpenSim.Services.Connectors
114 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); 117 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
115 try 118 try
116 { 119 {
117 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); 120 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
118 if (reply == null || (reply != null && reply == string.Empty)) 121 if (reply == null || (reply != null && reply == string.Empty))
119 { 122 {
120 m_log.DebugFormat("[AVATAR CONNECTOR]: GetAgent received null or empty reply"); 123 m_log.DebugFormat("[AVATAR CONNECTOR]: GetAgent received null or empty reply");
@@ -162,7 +165,7 @@ namespace OpenSim.Services.Connectors
162 //m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); 165 //m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
163 try 166 try
164 { 167 {
165 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); 168 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
166 if (reply != string.Empty) 169 if (reply != string.Empty)
167 { 170 {
168 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 171 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -207,7 +210,7 @@ namespace OpenSim.Services.Connectors
207 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); 210 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
208 try 211 try
209 { 212 {
210 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); 213 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
211 if (reply != string.Empty) 214 if (reply != string.Empty)
212 { 215 {
213 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 216 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -250,7 +253,7 @@ namespace OpenSim.Services.Connectors
250 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); 253 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
251 try 254 try
252 { 255 {
253 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); 256 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
254 if (reply != string.Empty) 257 if (reply != string.Empty)
255 { 258 {
256 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 259 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -293,7 +296,7 @@ namespace OpenSim.Services.Connectors
293 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString); 296 // m_log.DebugFormat("[AVATAR CONNECTOR]: queryString = {0}", reqString);
294 try 297 try
295 { 298 {
296 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); 299 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
297 if (reply != string.Empty) 300 if (reply != string.Empty)
298 { 301 {
299 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 302 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
diff --git a/OpenSim/Services/Connectors/BaseServiceConnector.cs b/OpenSim/Services/Connectors/BaseServiceConnector.cs
new file mode 100644
index 0000000..98cd489
--- /dev/null
+++ b/OpenSim/Services/Connectors/BaseServiceConnector.cs
@@ -0,0 +1,33 @@
1using System;
2using OpenSim.Framework;
3using OpenSim.Framework.ServiceAuth;
4
5using Nini.Config;
6
7namespace OpenSim.Services.Connectors
8{
9 public class BaseServiceConnector
10 {
11 protected IServiceAuth m_Auth;
12
13 public BaseServiceConnector() { }
14
15 public BaseServiceConnector(IConfigSource config, string section)
16 {
17 Initialise(config, section);
18 }
19
20 public void Initialise(IConfigSource config, string section)
21 {
22 string authType = Util.GetConfigVarFromSections<string>(config, "AuthType", new string[] { "Network", section }, "None");
23
24 switch (authType)
25 {
26 case "BasicHttpAuthentication":
27 m_Auth = new BasicHttpAuthentication(config, section);
28 break;
29 }
30
31 }
32 }
33}
diff --git a/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs b/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs
new file mode 100644
index 0000000..6412bcd
--- /dev/null
+++ b/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs
@@ -0,0 +1,338 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29using System.Net;
30using System.Reflection;
31
32using log4net;
33
34using OpenMetaverse;
35using Nini.Config;
36
37using OpenSim.Framework;
38using OpenSim.Framework.ServiceAuth;
39using OpenSim.Services.Connectors;
40using OpenSim.Services.Interfaces;
41using OpenSim.Server.Base;
42
43namespace OpenSim.Services.Connectors
44{
45 public class EstateDataRemoteConnector : BaseServiceConnector, IEstateDataService
46 {
47 private static readonly ILog m_log =
48 LogManager.GetLogger(
49 MethodBase.GetCurrentMethod().DeclaringType);
50
51 private string m_ServerURI = String.Empty;
52 private ExpiringCache<string, List<EstateSettings>> m_EstateCache = new ExpiringCache<string, List<EstateSettings>>();
53 private const int EXPIRATION = 5 * 60; // 5 minutes in secs
54
55 public EstateDataRemoteConnector(IConfigSource source)
56 {
57 Initialise(source);
58 }
59
60 public virtual void Initialise(IConfigSource source)
61 {
62 IConfig gridConfig = source.Configs["EstateService"];
63 if (gridConfig == null)
64 {
65 m_log.Error("[ESTATE CONNECTOR]: EstateService missing from OpenSim.ini");
66 throw new Exception("Estate connector init error");
67 }
68
69 string serviceURI = gridConfig.GetString("EstateServerURI",
70 String.Empty);
71
72 if (serviceURI == String.Empty)
73 {
74 m_log.Error("[ESTATE CONNECTOR]: No Server URI named in section EstateService");
75 throw new Exception("Estate connector init error");
76 }
77 m_ServerURI = serviceURI;
78
79 base.Initialise(source, "EstateService");
80 }
81
82 #region IEstateDataService
83
84 public List<EstateSettings> LoadEstateSettingsAll()
85 {
86 string reply = string.Empty;
87 string uri = m_ServerURI + "/estates";
88
89 reply = MakeRequest("GET", uri, string.Empty);
90 if (String.IsNullOrEmpty(reply))
91 return new List<EstateSettings>();
92
93 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
94
95 List<EstateSettings> estates = new List<EstateSettings>();
96 if (replyData != null && replyData.Count > 0)
97 {
98 m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettingsAll returned {0} elements", replyData.Count);
99 Dictionary<string, object>.ValueCollection estateData = replyData.Values;
100 foreach (object r in estateData)
101 {
102 if (r is Dictionary<string, object>)
103 {
104 EstateSettings es = new EstateSettings((Dictionary<string, object>)r);
105 estates.Add(es);
106 }
107 }
108 m_EstateCache.AddOrUpdate("estates", estates, EXPIRATION);
109 }
110 else
111 m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettingsAll from {0} received null or zero response", uri);
112
113 return estates;
114
115 }
116
117 public List<int> GetEstatesAll()
118 {
119 List<int> eids = new List<int>();
120 // If we don't have them, load them from the server
121 List<EstateSettings> estates = null;
122 if (!m_EstateCache.TryGetValue("estates", out estates))
123 LoadEstateSettingsAll();
124
125 foreach (EstateSettings es in estates)
126 eids.Add((int)es.EstateID);
127
128 return eids;
129 }
130
131 public List<int> GetEstates(string search)
132 {
133 // If we don't have them, load them from the server
134 List<EstateSettings> estates = null;
135 if (!m_EstateCache.TryGetValue("estates", out estates))
136 LoadEstateSettingsAll();
137
138 List<int> eids = new List<int>();
139 foreach (EstateSettings es in estates)
140 if (es.EstateName == search)
141 eids.Add((int)es.EstateID);
142
143 return eids;
144 }
145
146 public List<int> GetEstatesByOwner(UUID ownerID)
147 {
148 // If we don't have them, load them from the server
149 List<EstateSettings> estates = null;
150 if (!m_EstateCache.TryGetValue("estates", out estates))
151 LoadEstateSettingsAll();
152
153 List<int> eids = new List<int>();
154 foreach (EstateSettings es in estates)
155 if (es.EstateOwner == ownerID)
156 eids.Add((int)es.EstateID);
157
158 return eids;
159 }
160
161 public List<UUID> GetRegions(int estateID)
162 {
163 string reply = string.Empty;
164 // /estates/regions/?eid=int
165 string uri = m_ServerURI + "/estates/regions/?eid=" + estateID.ToString();
166
167 reply = MakeRequest("GET", uri, string.Empty);
168 if (String.IsNullOrEmpty(reply))
169 return new List<UUID>();
170
171 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
172
173 List<UUID> regions = new List<UUID>();
174 if (replyData != null && replyData.Count > 0)
175 {
176 m_log.DebugFormat("[ESTATE CONNECTOR]: GetRegions for estate {0} returned {1} elements", estateID, replyData.Count);
177 Dictionary<string, object>.ValueCollection data = replyData.Values;
178 foreach (object r in data)
179 {
180 UUID uuid = UUID.Zero;
181 if (UUID.TryParse(r.ToString(), out uuid))
182 regions.Add(uuid);
183 }
184 }
185 else
186 m_log.DebugFormat("[ESTATE CONNECTOR]: GetRegions from {0} received null or zero response", uri);
187
188 return regions;
189 }
190
191 public EstateSettings LoadEstateSettings(UUID regionID, bool create)
192 {
193 string reply = string.Empty;
194 // /estates/estate/?region=uuid&create=[t|f]
195 string uri = m_ServerURI + string.Format("/estates/estate/?region={0}&create={1}", regionID, create);
196
197 reply = MakeRequest("GET", uri, string.Empty);
198 if (String.IsNullOrEmpty(reply))
199 return null;
200
201 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
202
203 if (replyData != null && replyData.Count > 0)
204 {
205 m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings({0}) returned {1} elements", regionID, replyData.Count);
206 EstateSettings es = new EstateSettings(replyData);
207 return es;
208 }
209 else
210 m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings(regionID) from {0} received null or zero response", uri);
211
212 return null;
213 }
214
215 public EstateSettings LoadEstateSettings(int estateID)
216 {
217 string reply = string.Empty;
218 // /estates/estate/?eid=int
219 string uri = m_ServerURI + string.Format("/estates/estate/?eid={0}", estateID);
220
221 reply = MakeRequest("GET", uri, string.Empty);
222 if (String.IsNullOrEmpty(reply))
223 return null;
224
225 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
226
227 if (replyData != null && replyData.Count > 0)
228 {
229 m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings({0}) returned {1} elements", estateID, replyData.Count);
230 EstateSettings es = new EstateSettings(replyData);
231 return es;
232 }
233 else
234 m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings(estateID) from {0} received null or zero response", uri);
235
236 return null;
237 }
238
239 /// <summary>
240 /// Forbidden operation
241 /// </summary>
242 /// <returns></returns>
243 public EstateSettings CreateNewEstate()
244 {
245 // No can do
246 return null;
247 }
248
249 public void StoreEstateSettings(EstateSettings es)
250 {
251 // /estates/estate/
252 string uri = m_ServerURI + ("/estates/estate");
253
254 Dictionary<string, object> formdata = es.ToMap();
255 formdata["OP"] = "STORE";
256
257 PostRequest(uri, formdata);
258 }
259
260 public bool LinkRegion(UUID regionID, int estateID)
261 {
262 // /estates/estate/?eid=int&region=uuid
263 string uri = m_ServerURI + String.Format("/estates/estate/?eid={0}&region={1}", estateID, regionID);
264
265 Dictionary<string, object> formdata = new Dictionary<string, object>();
266 formdata["OP"] = "LINK";
267 return PostRequest(uri, formdata);
268 }
269
270 private bool PostRequest(string uri, Dictionary<string, object> sendData)
271 {
272 string reqString = ServerUtils.BuildQueryString(sendData);
273
274 string reply = MakeRequest("POST", uri, reqString);
275 if (String.IsNullOrEmpty(reply))
276 return false;
277
278 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
279
280 bool result = false;
281 if (replyData != null && replyData.Count > 0)
282 {
283 if (replyData.ContainsKey("Result"))
284 {
285 if (Boolean.TryParse(replyData["Result"].ToString(), out result))
286 m_log.DebugFormat("[ESTATE CONNECTOR]: PostRequest {0} returned {1}", uri, result);
287 }
288 }
289 else
290 m_log.DebugFormat("[ESTATE CONNECTOR]: PostRequest {0} received null or zero response", uri);
291
292 return result;
293 }
294
295 /// <summary>
296 /// Forbidden operation
297 /// </summary>
298 /// <returns></returns>
299 public bool DeleteEstate(int estateID)
300 {
301 return false;
302 }
303
304 #endregion
305
306 private string MakeRequest(string verb, string uri, string formdata)
307 {
308 string reply = string.Empty;
309 try
310 {
311 reply = SynchronousRestFormsRequester.MakeRequest(verb, uri, formdata, m_Auth);
312 }
313 catch (WebException e)
314 {
315 using (HttpWebResponse hwr = (HttpWebResponse)e.Response)
316 {
317 if (hwr != null)
318 {
319 if (hwr.StatusCode == HttpStatusCode.NotFound)
320 m_log.Error(string.Format("[ESTATE CONNECTOR]: Resource {0} not found ", uri));
321 if (hwr.StatusCode == HttpStatusCode.Unauthorized)
322 m_log.Error(string.Format("[ESTATE CONNECTOR]: Web request {0} requires authentication ", uri));
323 }
324 else
325 m_log.Error(string.Format(
326 "[ESTATE CONNECTOR]: WebException for {0} {1} {2} ",
327 verb, uri, formdata, e));
328 }
329 }
330 catch (Exception e)
331 {
332 m_log.DebugFormat("[ESTATE CONNECTOR]: Exception when contacting estate server at {0}: {1}", uri, e.Message);
333 }
334
335 return reply;
336 }
337 }
338}
diff --git a/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs
index d688299..20dc1cc 100644
--- a/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs
+++ b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs
@@ -32,7 +32,7 @@ using System.Collections;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35
36using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
37using OpenSim.Server.Base; 37using OpenSim.Server.Base;
38using OpenMetaverse; 38using OpenMetaverse;
diff --git a/OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs
index b1dd84e..b7702a8 100644
--- a/OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Friends/FriendsServicesConnector.cs
@@ -32,7 +32,8 @@ using System.IO;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35using OpenSim.Framework.ServiceAuth;
36
36using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
37using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; 38using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38using OpenSim.Server.Base; 39using OpenSim.Server.Base;
@@ -40,7 +41,7 @@ using OpenMetaverse;
40 41
41namespace OpenSim.Services.Connectors.Friends 42namespace OpenSim.Services.Connectors.Friends
42{ 43{
43 public class FriendsServicesConnector : IFriendsService 44 public class FriendsServicesConnector : BaseServiceConnector, IFriendsService
44 { 45 {
45 private static readonly ILog m_log = 46 private static readonly ILog m_log =
46 LogManager.GetLogger( 47 LogManager.GetLogger(
@@ -80,6 +81,7 @@ namespace OpenSim.Services.Connectors.Friends
80 throw new Exception("Friends connector init error"); 81 throw new Exception("Friends connector init error");
81 } 82 }
82 m_ServerURI = serviceURI; 83 m_ServerURI = serviceURI;
84 base.Initialise(source, "FriendsService");
83 } 85 }
84 86
85 87
@@ -112,7 +114,7 @@ namespace OpenSim.Services.Connectors.Friends
112 114
113 try 115 try
114 { 116 {
115 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); 117 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
116 if (reply != string.Empty) 118 if (reply != string.Empty)
117 { 119 {
118 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 120 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -168,7 +170,7 @@ namespace OpenSim.Services.Connectors.Friends
168 string uri = m_ServerURI + "/friends"; 170 string uri = m_ServerURI + "/friends";
169 try 171 try
170 { 172 {
171 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); 173 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData), m_Auth);
172 } 174 }
173 catch (Exception e) 175 catch (Exception e)
174 { 176 {
@@ -223,7 +225,7 @@ namespace OpenSim.Services.Connectors.Friends
223 string uri = m_ServerURI + "/friends"; 225 string uri = m_ServerURI + "/friends";
224 try 226 try
225 { 227 {
226 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); 228 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData), m_Auth);
227 } 229 }
228 catch (Exception e) 230 catch (Exception e)
229 { 231 {
diff --git a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs
index 34ed0d7..596f867 100644
--- a/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Grid/GridServicesConnector.cs
@@ -32,7 +32,8 @@ using System.IO;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35
36using OpenSim.Framework.ServiceAuth;
36using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion; 38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38using OpenSim.Server.Base; 39using OpenSim.Server.Base;
@@ -40,7 +41,7 @@ using OpenMetaverse;
40 41
41namespace OpenSim.Services.Connectors 42namespace OpenSim.Services.Connectors
42{ 43{
43 public class GridServicesConnector : IGridService 44 public class GridServicesConnector : BaseServiceConnector, IGridService
44 { 45 {
45 private static readonly ILog m_log = 46 private static readonly ILog m_log =
46 LogManager.GetLogger( 47 LogManager.GetLogger(
@@ -80,6 +81,8 @@ namespace OpenSim.Services.Connectors
80 throw new Exception("Grid connector init error"); 81 throw new Exception("Grid connector init error");
81 } 82 }
82 m_ServerURI = serviceURI; 83 m_ServerURI = serviceURI;
84
85 base.Initialise(source, "GridService");
83 } 86 }
84 87
85 88
@@ -102,7 +105,7 @@ namespace OpenSim.Services.Connectors
102 // m_log.DebugFormat("[GRID CONNECTOR]: queryString = {0}", reqString); 105 // m_log.DebugFormat("[GRID CONNECTOR]: queryString = {0}", reqString);
103 try 106 try
104 { 107 {
105 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); 108 string reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
106 if (reply != string.Empty) 109 if (reply != string.Empty)
107 { 110 {
108 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 111 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -158,7 +161,7 @@ namespace OpenSim.Services.Connectors
158 try 161 try
159 { 162 {
160 string reply 163 string reply
161 = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); 164 = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData), m_Auth);
162 165
163 if (reply != string.Empty) 166 if (reply != string.Empty)
164 { 167 {
@@ -195,7 +198,7 @@ namespace OpenSim.Services.Connectors
195 198
196 try 199 try
197 { 200 {
198 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString); 201 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, reqString, m_Auth);
199 } 202 }
200 catch (Exception e) 203 catch (Exception e)
201 { 204 {
@@ -238,7 +241,7 @@ namespace OpenSim.Services.Connectors
238 string uri = m_ServerURI + "/grid"; 241 string uri = m_ServerURI + "/grid";
239 try 242 try
240 { 243 {
241 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData)); 244 reply = SynchronousRestFormsRequester.MakeRequest("POST", uri, ServerUtils.BuildQueryString(sendData), m_Auth);
242 } 245 }
243 catch (Exception e) 246 catch (Exception e)
244 { 247 {
@@ -285,7 +288,7 @@ namespace OpenSim.Services.Connectors
285 { 288 {
286 reply = SynchronousRestFormsRequester.MakeRequest("POST", 289 reply = SynchronousRestFormsRequester.MakeRequest("POST",
287 uri, 290 uri,
288 ServerUtils.BuildQueryString(sendData)); 291 ServerUtils.BuildQueryString(sendData), m_Auth);
289 } 292 }
290 catch (Exception e) 293 catch (Exception e)
291 { 294 {
@@ -330,7 +333,7 @@ namespace OpenSim.Services.Connectors
330 { 333 {
331 reply = SynchronousRestFormsRequester.MakeRequest("POST", 334 reply = SynchronousRestFormsRequester.MakeRequest("POST",
332 uri, 335 uri,
333 ServerUtils.BuildQueryString(sendData)); 336 ServerUtils.BuildQueryString(sendData), m_Auth);
334 } 337 }
335 catch (Exception e) 338 catch (Exception e)
336 { 339 {
@@ -374,7 +377,7 @@ namespace OpenSim.Services.Connectors
374 { 377 {
375 reply = SynchronousRestFormsRequester.MakeRequest("POST", 378 reply = SynchronousRestFormsRequester.MakeRequest("POST",
376 uri, 379 uri,
377 ServerUtils.BuildQueryString(sendData)); 380 ServerUtils.BuildQueryString(sendData), m_Auth);
378 } 381 }
379 catch (Exception e) 382 catch (Exception e)
380 { 383 {
@@ -428,7 +431,7 @@ namespace OpenSim.Services.Connectors
428 { 431 {
429 reply = SynchronousRestFormsRequester.MakeRequest("POST", 432 reply = SynchronousRestFormsRequester.MakeRequest("POST",
430 uri, 433 uri,
431 ServerUtils.BuildQueryString(sendData)); 434 ServerUtils.BuildQueryString(sendData), m_Auth);
432 435
433 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); 436 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
434 } 437 }
@@ -479,7 +482,7 @@ namespace OpenSim.Services.Connectors
479 { 482 {
480 reply = SynchronousRestFormsRequester.MakeRequest("POST", 483 reply = SynchronousRestFormsRequester.MakeRequest("POST",
481 uri, 484 uri,
482 ServerUtils.BuildQueryString(sendData)); 485 ServerUtils.BuildQueryString(sendData), m_Auth);
483 486
484 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); 487 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
485 } 488 }
@@ -515,6 +518,57 @@ namespace OpenSim.Services.Connectors
515 return rinfos; 518 return rinfos;
516 } 519 }
517 520
521 public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
522 {
523 Dictionary<string, object> sendData = new Dictionary<string, object>();
524
525 sendData["SCOPEID"] = scopeID.ToString();
526
527 sendData["METHOD"] = "get_default_hypergrid_regions";
528
529 List<GridRegion> rinfos = new List<GridRegion>();
530 string reply = string.Empty;
531 string uri = m_ServerURI + "/grid";
532 try
533 {
534 reply = SynchronousRestFormsRequester.MakeRequest("POST",
535 uri,
536 ServerUtils.BuildQueryString(sendData), m_Auth);
537
538 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
539 }
540 catch (Exception e)
541 {
542 m_log.DebugFormat("[GRID CONNECTOR]: Exception when contacting grid server at {0}: {1}", uri, e.Message);
543 return rinfos;
544 }
545
546 if (reply != string.Empty)
547 {
548 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
549
550 if (replyData != null)
551 {
552 Dictionary<string, object>.ValueCollection rinfosList = replyData.Values;
553 foreach (object r in rinfosList)
554 {
555 if (r is Dictionary<string, object>)
556 {
557 GridRegion rinfo = new GridRegion((Dictionary<string, object>)r);
558 rinfos.Add(rinfo);
559 }
560 }
561 }
562 else
563 m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultHypergridRegions {0} received null response",
564 scopeID);
565 }
566 else
567 m_log.DebugFormat("[GRID CONNECTOR]: GetDefaultHypergridRegions received null reply");
568
569 return rinfos;
570 }
571
518 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) 572 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
519 { 573 {
520 Dictionary<string, object> sendData = new Dictionary<string, object>(); 574 Dictionary<string, object> sendData = new Dictionary<string, object>();
@@ -532,7 +586,7 @@ namespace OpenSim.Services.Connectors
532 { 586 {
533 reply = SynchronousRestFormsRequester.MakeRequest("POST", 587 reply = SynchronousRestFormsRequester.MakeRequest("POST",
534 uri, 588 uri,
535 ServerUtils.BuildQueryString(sendData)); 589 ServerUtils.BuildQueryString(sendData), m_Auth);
536 590
537 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); 591 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
538 } 592 }
@@ -583,7 +637,7 @@ namespace OpenSim.Services.Connectors
583 { 637 {
584 reply = SynchronousRestFormsRequester.MakeRequest("POST", 638 reply = SynchronousRestFormsRequester.MakeRequest("POST",
585 uri, 639 uri,
586 ServerUtils.BuildQueryString(sendData)); 640 ServerUtils.BuildQueryString(sendData), m_Auth);
587 641
588 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply); 642 //m_log.DebugFormat("[GRID CONNECTOR]: reply was {0}", reply);
589 } 643 }
@@ -634,7 +688,7 @@ namespace OpenSim.Services.Connectors
634 { 688 {
635 reply = SynchronousRestFormsRequester.MakeRequest("POST", 689 reply = SynchronousRestFormsRequester.MakeRequest("POST",
636 uri, 690 uri,
637 ServerUtils.BuildQueryString(sendData)); 691 ServerUtils.BuildQueryString(sendData), m_Auth);
638 } 692 }
639 catch (Exception e) 693 catch (Exception e)
640 { 694 {
@@ -665,6 +719,45 @@ namespace OpenSim.Services.Connectors
665 return flags; 719 return flags;
666 } 720 }
667 721
722 public Dictionary<string, object> GetExtraFeatures()
723 {
724 Dictionary<string, object> sendData = new Dictionary<string, object>();
725 Dictionary<string, object> extraFeatures = new Dictionary<string, object>();
726
727 sendData["METHOD"] = "get_grid_extra_features";
728
729 string reply = string.Empty;
730 string uri = m_ServerURI + "/grid";
731
732 try
733 {
734 reply = SynchronousRestFormsRequester.MakeRequest("POST",
735 uri,
736 ServerUtils.BuildQueryString(sendData), m_Auth);
737 }
738 catch (Exception e)
739 {
740 m_log.DebugFormat("[GRID CONNECTOR]: GetExtraFeatures - Exception when contacting grid server at {0}: {1}", uri, e.Message);
741 return extraFeatures;
742 }
743
744 if (reply != string.Empty)
745 {
746 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
747
748 if ((replyData != null) && replyData.Count > 0)
749 {
750 foreach (string key in replyData.Keys)
751 {
752 extraFeatures[key] = replyData[key].ToString();
753 }
754 }
755 }
756 else
757 m_log.DebugFormat("[GRID CONNECTOR]: GetExtraServiceURLs received null reply");
758
759 return extraFeatures;
760 }
668 #endregion 761 #endregion
669 762
670 } 763 }
diff --git a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs
index 94bda82..b5ca1ad 100644
--- a/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs
+++ b/OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs
@@ -32,7 +32,8 @@ using System.IO;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35
36using OpenSim.Framework.ServiceAuth;
36using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion; 38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38using OpenSim.Server.Base; 39using OpenSim.Server.Base;
@@ -40,7 +41,7 @@ using OpenMetaverse;
40 41
41namespace OpenSim.Services.Connectors 42namespace OpenSim.Services.Connectors
42{ 43{
43 public class GridUserServicesConnector : IGridUserService 44 public class GridUserServicesConnector : BaseServiceConnector, IGridUserService
44 { 45 {
45 private static readonly ILog m_log = 46 private static readonly ILog m_log =
46 LogManager.GetLogger( 47 LogManager.GetLogger(
@@ -80,6 +81,7 @@ namespace OpenSim.Services.Connectors
80 throw new Exception("GridUser connector init error"); 81 throw new Exception("GridUser connector init error");
81 } 82 }
82 m_ServerURI = serviceURI; 83 m_ServerURI = serviceURI;
84 base.Initialise(source, "GridUserService");
83 } 85 }
84 86
85 87
@@ -162,7 +164,8 @@ namespace OpenSim.Services.Connectors
162 { 164 {
163 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 165 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
164 uri, 166 uri,
165 reqString); 167 reqString,
168 m_Auth);
166 if (reply != string.Empty) 169 if (reply != string.Empty)
167 { 170 {
168 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 171 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -198,7 +201,8 @@ namespace OpenSim.Services.Connectors
198 { 201 {
199 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 202 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
200 uri, 203 uri,
201 reqString); 204 reqString,
205 m_Auth);
202 if (reply != string.Empty) 206 if (reply != string.Empty)
203 { 207 {
204 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 208 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -214,7 +218,7 @@ namespace OpenSim.Services.Connectors
214 218
215 } 219 }
216 else 220 else
217 m_log.DebugFormat("[GRID USER CONNECTOR]: Loggedin received empty reply"); 221 m_log.DebugFormat("[GRID USER CONNECTOR]: Get received empty reply");
218 } 222 }
219 catch (Exception e) 223 catch (Exception e)
220 { 224 {
@@ -243,7 +247,8 @@ namespace OpenSim.Services.Connectors
243 { 247 {
244 reply = SynchronousRestFormsRequester.MakeRequest("POST", 248 reply = SynchronousRestFormsRequester.MakeRequest("POST",
245 uri, 249 uri,
246 reqString); 250 reqString,
251 m_Auth);
247 if (reply == null || (reply != null && reply == string.Empty)) 252 if (reply == null || (reply != null && reply == string.Empty))
248 { 253 {
249 m_log.DebugFormat("[GRID USER CONNECTOR]: GetGridUserInfo received null or empty reply"); 254 m_log.DebugFormat("[GRID USER CONNECTOR]: GetGridUserInfo received null or empty reply");
diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
index 5bcff48..b1663ee 100644
--- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
@@ -53,7 +53,8 @@ namespace OpenSim.Services.Connectors.Hypergrid
53 53
54 private IAssetService m_AssetService; 54 private IAssetService m_AssetService;
55 55
56 public GatekeeperServiceConnector() : base() 56 public GatekeeperServiceConnector()
57 : base()
57 { 58 {
58 } 59 }
59 60
@@ -123,11 +124,13 @@ namespace OpenSim.Services.Connectors.Hypergrid
123 realHandle = Convert.ToUInt64((string)hash["handle"]); 124 realHandle = Convert.ToUInt64((string)hash["handle"]);
124 //m_log.Debug(">> HERE, realHandle: " + realHandle); 125 //m_log.Debug(">> HERE, realHandle: " + realHandle);
125 } 126 }
126 if (hash["region_image"] != null) { 127 if (hash["region_image"] != null)
128 {
127 imageURL = (string)hash["region_image"]; 129 imageURL = (string)hash["region_image"];
128 //m_log.Debug(">> HERE, imageURL: " + imageURL); 130 //m_log.Debug(">> HERE, imageURL: " + imageURL);
129 } 131 }
130 if (hash["external_name"] != null) { 132 if (hash["external_name"] != null)
133 {
131 externalName = (string)hash["external_name"]; 134 externalName = (string)hash["external_name"];
132 //m_log.Debug(">> HERE, externalName: " + externalName); 135 //m_log.Debug(">> HERE, externalName: " + externalName);
133 } 136 }
@@ -178,7 +181,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
178 //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); 181 //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width);
179 imageData = OpenJPEG.EncodeFromImage(bitmap, true); 182 imageData = OpenJPEG.EncodeFromImage(bitmap, true);
180 } 183 }
181 184
182 AssetBase ass = new AssetBase(UUID.Random(), "region " + name, (sbyte)AssetType.Texture, regionID.ToString()); 185 AssetBase ass = new AssetBase(UUID.Random(), "region " + name, (sbyte)AssetType.Texture, regionID.ToString());
183 186
184 // !!! for now 187 // !!! for now
@@ -199,10 +202,16 @@ namespace OpenSim.Services.Connectors.Hypergrid
199 return mapTile; 202 return mapTile;
200 } 203 }
201 204
202 public GridRegion GetHyperlinkRegion(GridRegion gatekeeper, UUID regionID) 205 public GridRegion GetHyperlinkRegion(GridRegion gatekeeper, UUID regionID, UUID agentID, string agentHomeURI, out string message)
203 { 206 {
204 Hashtable hash = new Hashtable(); 207 Hashtable hash = new Hashtable();
205 hash["region_uuid"] = regionID.ToString(); 208 hash["region_uuid"] = regionID.ToString();
209 if (agentID != UUID.Zero)
210 {
211 hash["agent_id"] = agentID.ToString();
212 if (agentHomeURI != null)
213 hash["agent_home_uri"] = agentHomeURI;
214 }
206 215
207 IList paramList = new ArrayList(); 216 IList paramList = new ArrayList();
208 paramList.Add(hash); 217 paramList.Add(hash);
@@ -216,12 +225,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
216 } 225 }
217 catch (Exception e) 226 catch (Exception e)
218 { 227 {
228 message = "Error contacting grid.";
219 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Exception " + e.Message); 229 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Exception " + e.Message);
220 return null; 230 return null;
221 } 231 }
222 232
223 if (response.IsFault) 233 if (response.IsFault)
224 { 234 {
235 message = "Error contacting grid.";
225 m_log.ErrorFormat("[GATEKEEPER SERVICE CONNECTOR]: remote call returned an error: {0}", response.FaultString); 236 m_log.ErrorFormat("[GATEKEEPER SERVICE CONNECTOR]: remote call returned an error: {0}", response.FaultString);
226 return null; 237 return null;
227 } 238 }
@@ -233,6 +244,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
233 { 244 {
234 bool success = false; 245 bool success = false;
235 Boolean.TryParse((string)hash["result"], out success); 246 Boolean.TryParse((string)hash["result"], out success);
247
248 if (hash["message"] != null)
249 message = (string)hash["message"];
250 else if (success)
251 message = null;
252 else
253 message = "The teleport destination could not be found."; // probably the dest grid is old and doesn't send 'message', but the most common problem is that the region is unavailable
254
236 if (success) 255 if (success)
237 { 256 {
238 GridRegion region = new GridRegion(); 257 GridRegion region = new GridRegion();
@@ -252,12 +271,25 @@ namespace OpenSim.Services.Connectors.Hypergrid
252 region.RegionLocY = n; 271 region.RegionLocY = n;
253 //m_log.Debug(">> HERE, y: " + region.RegionLocY); 272 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
254 } 273 }
274 if (hash["size_x"] != null)
275 {
276 Int32.TryParse((string)hash["size_x"], out n);
277 region.RegionSizeX = n;
278 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
279 }
280 if (hash["size_y"] != null)
281 {
282 Int32.TryParse((string)hash["size_y"], out n);
283 region.RegionSizeY = n;
284 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
285 }
255 if (hash["region_name"] != null) 286 if (hash["region_name"] != null)
256 { 287 {
257 region.RegionName = (string)hash["region_name"]; 288 region.RegionName = (string)hash["region_name"];
258 //m_log.Debug(">> HERE, region_name: " + region.RegionName); 289 //m_log.Debug(">> HERE, region_name: " + region.RegionName);
259 } 290 }
260 if (hash["hostname"] != null) { 291 if (hash["hostname"] != null)
292 {
261 region.ExternalHostName = (string)hash["hostname"]; 293 region.ExternalHostName = (string)hash["hostname"];
262 //m_log.Debug(">> HERE, hostname: " + region.ExternalHostName); 294 //m_log.Debug(">> HERE, hostname: " + region.ExternalHostName);
263 } 295 }
@@ -275,10 +307,10 @@ namespace OpenSim.Services.Connectors.Hypergrid
275 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p); 307 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
276 //m_log.Debug(">> HERE, internal_port: " + region.InternalEndPoint); 308 //m_log.Debug(">> HERE, internal_port: " + region.InternalEndPoint);
277 } 309 }
278 310
279 if (hash["server_uri"] != null) 311 if (hash["server_uri"] != null)
280 { 312 {
281 region.ServerURI = (string) hash["server_uri"]; 313 region.ServerURI = (string)hash["server_uri"];
282 //m_log.Debug(">> HERE, server_uri: " + region.ServerURI); 314 //m_log.Debug(">> HERE, server_uri: " + region.ServerURI);
283 } 315 }
284 316
@@ -289,61 +321,12 @@ namespace OpenSim.Services.Connectors.Hypergrid
289 } 321 }
290 catch (Exception e) 322 catch (Exception e)
291 { 323 {
324 message = "Error parsing response from grid.";
292 m_log.Error("[GATEKEEPER SERVICE CONNECTOR]: Got exception while parsing hyperlink response " + e.StackTrace); 325 m_log.Error("[GATEKEEPER SERVICE CONNECTOR]: Got exception while parsing hyperlink response " + e.StackTrace);
293 return null; 326 return null;
294 } 327 }
295 328
296 return null; 329 return null;
297 } 330 }
298
299 public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string myipaddress, out string reason)
300 {
301 // m_log.DebugFormat("[GATEKEEPER SERVICE CONNECTOR]: CreateAgent start");
302
303 myipaddress = String.Empty;
304 reason = String.Empty;
305
306 if (destination == null)
307 {
308 m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Given destination is null");
309 return false;
310 }
311
312 string uri = destination.ServerURI + AgentPath() + aCircuit.AgentID + "/";
313
314 try
315 {
316 OSDMap args = aCircuit.PackAgentCircuitData();
317
318 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
319 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
320 args["destination_name"] = OSD.FromString(destination.RegionName);
321 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
322 args["teleport_flags"] = OSD.FromString(flags.ToString());
323
324 OSDMap result = WebUtil.PostToService(uri, args, 80000);
325 if (result["Success"].AsBoolean())
326 {
327 OSDMap unpacked = (OSDMap)result["_Result"];
328
329 if (unpacked != null)
330 {
331 reason = unpacked["reason"].AsString();
332 myipaddress = unpacked["your_ip"].AsString();
333 return unpacked["success"].AsBoolean();
334 }
335 }
336
337 reason = result["Message"] != null ? result["Message"].AsString() : "error";
338 return false;
339 }
340 catch (Exception e)
341 {
342 m_log.Warn("[REMOTE SIMULATION CONNECTOR]: CreateAgent failed with exception: " + e.ToString());
343 reason = e.Message;
344 }
345
346 return false;
347 }
348 } 331 }
349} 332}
diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs
index e984a54..622d4e1 100644
--- a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServicesConnector.cs
@@ -277,7 +277,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
277 { 277 {
278 reply = SynchronousRestFormsRequester.MakeRequest("POST", 278 reply = SynchronousRestFormsRequester.MakeRequest("POST",
279 uri, 279 uri,
280 ServerUtils.BuildQueryString(sendData)); 280 ServerUtils.BuildQueryString(sendData), 15);
281 } 281 }
282 catch (Exception e) 282 catch (Exception e)
283 { 283 {
diff --git a/OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs
index 5c50936..b5e6d69 100644
--- a/OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/HeloServicesConnector.cs
@@ -47,16 +47,22 @@ namespace OpenSim.Services.Connectors
47 47
48 public HeloServicesConnector(string serverURI) 48 public HeloServicesConnector(string serverURI)
49 { 49 {
50 if (!serverURI.EndsWith("=")) 50 try
51 m_ServerURI = serverURI.TrimEnd('/') + "/helo/";
52 else
53 { 51 {
54 // Simian sends malformed urls like this: 52 Uri uri;
55 // http://valley.virtualportland.org/simtest/Grid/?id= 53
56 // 54 if (!serverURI.EndsWith("="))
57 try 55 {
56 // Let's check if this is a valid URI, because it may not be
57 uri = new Uri(serverURI);
58 m_ServerURI = serverURI.TrimEnd('/') + "/helo/";
59 }
60 else
58 { 61 {
59 Uri uri = new Uri(serverURI + "xxx"); 62 // Simian sends malformed urls like this:
63 // http://valley.virtualportland.org/simtest/Grid/?id=
64 //
65 uri = new Uri(serverURI + "xxx");
60 if (uri.Query == string.Empty) 66 if (uri.Query == string.Empty)
61 m_ServerURI = serverURI.TrimEnd('/') + "/helo/"; 67 m_ServerURI = serverURI.TrimEnd('/') + "/helo/";
62 else 68 else
@@ -66,26 +72,34 @@ namespace OpenSim.Services.Connectors
66 m_ServerURI = m_ServerURI.TrimEnd('/') + "/helo/"; 72 m_ServerURI = m_ServerURI.TrimEnd('/') + "/helo/";
67 } 73 }
68 } 74 }
69 catch (UriFormatException) 75
70 { 76 }
71 m_log.WarnFormat("[HELO SERVICE]: Malformed URL {0}", serverURI); 77 catch (UriFormatException)
72 } 78 {
79 m_log.WarnFormat("[HELO SERVICE]: Malformed URL {0}", serverURI);
73 } 80 }
74 } 81 }
75 82
76
77 public virtual string Helo() 83 public virtual string Helo()
78 { 84 {
79 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(m_ServerURI); 85 if (String.IsNullOrEmpty(m_ServerURI))
80 // Eventually we need to switch to HEAD 86 {
81 /* req.Method = "HEAD"; */ 87 m_log.WarnFormat("[HELO SERVICE]: Unable to invoke HELO due to empty URL");
88 return String.Empty;
89 }
82 90
83 try 91 try
84 { 92 {
85 WebResponse response = req.GetResponse(); 93 HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(m_ServerURI);
86 if (response.Headers.Get("X-Handlers-Provided") == null) // just in case this ever returns a null 94 // Eventually we need to switch to HEAD
87 return string.Empty; 95 /* req.Method = "HEAD"; */
88 return response.Headers.Get("X-Handlers-Provided"); 96
97 using (WebResponse response = req.GetResponse())
98 {
99 if (response.Headers.Get("X-Handlers-Provided") == null) // just in case this ever returns a null
100 return string.Empty;
101 return response.Headers.Get("X-Handlers-Provided");
102 }
89 } 103 }
90 catch (Exception e) 104 catch (Exception e)
91 { 105 {
@@ -95,6 +109,5 @@ namespace OpenSim.Services.Connectors
95 // fail 109 // fail
96 return string.Empty; 110 return string.Empty;
97 } 111 }
98
99 } 112 }
100} 113} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index 2f263ae..8abd046 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -44,13 +44,15 @@ using Nini.Config;
44 44
45namespace OpenSim.Services.Connectors.Hypergrid 45namespace OpenSim.Services.Connectors.Hypergrid
46{ 46{
47 public class UserAgentServiceConnector : IUserAgentService 47 public class UserAgentServiceConnector : SimulationServiceConnector, IUserAgentService
48 { 48 {
49 private static readonly ILog m_log = 49 private static readonly ILog m_log =
50 LogManager.GetLogger( 50 LogManager.GetLogger(
51 MethodBase.GetCurrentMethod().DeclaringType); 51 MethodBase.GetCurrentMethod().DeclaringType);
52 52
53 string m_ServerURL; 53 private string m_ServerURLHost;
54 private string m_ServerURL;
55 private GridRegion m_Gatekeeper;
54 56
55 public UserAgentServiceConnector(string url) : this(url, true) 57 public UserAgentServiceConnector(string url) : this(url, true)
56 { 58 {
@@ -58,7 +60,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
58 60
59 public UserAgentServiceConnector(string url, bool dnsLookup) 61 public UserAgentServiceConnector(string url, bool dnsLookup)
60 { 62 {
61 m_ServerURL = url; 63 m_ServerURL = m_ServerURLHost = url;
62 64
63 if (dnsLookup) 65 if (dnsLookup)
64 { 66 {
@@ -74,10 +76,11 @@ namespace OpenSim.Services.Connectors.Hypergrid
74 } 76 }
75 catch (Exception e) 77 catch (Exception e)
76 { 78 {
77 m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", m_ServerURL, e.Message); 79 m_log.DebugFormat("[USER AGENT CONNECTOR]: Malformed Uri {0}: {1}", url, e.Message);
78 } 80 }
79 } 81 }
80 m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL); 82
83 //m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0} ({1})", url, m_ServerURL);
81 } 84 }
82 85
83 public UserAgentServiceConnector(IConfigSource config) 86 public UserAgentServiceConnector(IConfigSource config)
@@ -97,16 +100,23 @@ namespace OpenSim.Services.Connectors.Hypergrid
97 m_log.Error("[USER AGENT CONNECTOR]: No Server URI named in section UserAgentService"); 100 m_log.Error("[USER AGENT CONNECTOR]: No Server URI named in section UserAgentService");
98 throw new Exception("UserAgent connector init error"); 101 throw new Exception("UserAgent connector init error");
99 } 102 }
100 m_ServerURL = serviceURI; 103
104 m_ServerURL = m_ServerURLHost = serviceURI;
101 if (!m_ServerURL.EndsWith("/")) 105 if (!m_ServerURL.EndsWith("/"))
102 m_ServerURL += "/"; 106 m_ServerURL += "/";
103 107
104 m_log.DebugFormat("[USER AGENT CONNECTOR]: UserAgentServiceConnector started for {0}", m_ServerURL); 108 //m_log.DebugFormat("[USER AGENT CONNECTOR]: new connector to {0}", m_ServerURL);
105 } 109 }
106 110
111 protected override string AgentPath()
112 {
113 return "homeagent/";
114 }
107 115
108 // The Login service calls this interface with a non-null [client] ipaddress 116 // The Login service calls this interface with fromLogin=true
109 public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, IPEndPoint ipaddress, out string reason) 117 // Sims call it with fromLogin=false
118 // Either way, this is verified by the handler
119 public bool LoginAgentToGrid(GridRegion source, AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, bool fromLogin, out string reason)
110 { 120 {
111 reason = String.Empty; 121 reason = String.Empty;
112 122
@@ -117,151 +127,34 @@ namespace OpenSim.Services.Connectors.Hypergrid
117 return false; 127 return false;
118 } 128 }
119 129
120 string uri = m_ServerURL + "homeagent/" + aCircuit.AgentID + "/"; 130 GridRegion home = new GridRegion();
121 131 home.ServerURI = m_ServerURL;
122 Console.WriteLine(" >>> LoginAgentToGrid <<< " + uri); 132 home.RegionID = destination.RegionID;
123 133 home.RegionLocX = destination.RegionLocX;
124 HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri); 134 home.RegionLocY = destination.RegionLocY;
125 AgentCreateRequest.Method = "POST";
126 AgentCreateRequest.ContentType = "application/json";
127 AgentCreateRequest.Timeout = 10000;
128 //AgentCreateRequest.KeepAlive = false;
129 //AgentCreateRequest.Headers.Add("Authorization", authKey);
130
131 // Fill it in
132 OSDMap args = PackCreateAgentArguments(aCircuit, gatekeeper, destination, ipaddress);
133
134 string strBuffer = "";
135 byte[] buffer = new byte[1];
136 try
137 {
138 strBuffer = OSDParser.SerializeJsonString(args);
139 Encoding str = Util.UTF8;
140 buffer = str.GetBytes(strBuffer);
141
142 }
143 catch (Exception e)
144 {
145 m_log.WarnFormat("[USER AGENT CONNECTOR]: Exception thrown on serialization of ChildCreate: {0}", e.Message);
146 // ignore. buffer will be empty, caller should check.
147 }
148
149 Stream os = null;
150 try
151 { // send the Post
152 AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send
153 os = AgentCreateRequest.GetRequestStream();
154 os.Write(buffer, 0, strBuffer.Length); //Send it
155 m_log.InfoFormat("[USER AGENT CONNECTOR]: Posted CreateAgent request to remote sim {0}, region {1}, x={2} y={3}",
156 uri, destination.RegionName, destination.RegionLocX, destination.RegionLocY);
157 }
158 //catch (WebException ex)
159 catch
160 {
161 //m_log.InfoFormat("[USER AGENT CONNECTOR]: Bad send on ChildAgentUpdate {0}", ex.Message);
162 reason = "cannot contact remote region";
163 return false;
164 }
165 finally
166 {
167 if (os != null)
168 os.Close();
169 }
170
171 // Let's wait for the response
172 //m_log.Info("[USER AGENT CONNECTOR]: Waiting for a reply after DoCreateChildAgentCall");
173 135
174 WebResponse webResponse = null; 136 m_Gatekeeper = gatekeeper;
175 StreamReader sr = null;
176 try
177 {
178 webResponse = AgentCreateRequest.GetResponse();
179 if (webResponse == null)
180 {
181 m_log.Info("[USER AGENT CONNECTOR]: Null reply on DoCreateChildAgentCall post");
182 }
183 else
184 {
185 137
186 sr = new StreamReader(webResponse.GetResponseStream()); 138 Console.WriteLine(" >>> LoginAgentToGrid <<< " + home.ServerURI);
187 string response = sr.ReadToEnd().Trim();
188 m_log.InfoFormat("[USER AGENT CONNECTOR]: DoCreateChildAgentCall reply was {0} ", response);
189
190 if (!String.IsNullOrEmpty(response))
191 {
192 try
193 {
194 // we assume we got an OSDMap back
195 OSDMap r = Util.GetOSDMap(response);
196 bool success = r["success"].AsBoolean();
197 reason = r["reason"].AsString();
198 return success;
199 }
200 catch (NullReferenceException e)
201 {
202 m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", e.Message);
203
204 // check for old style response
205 if (response.ToLower().StartsWith("true"))
206 return true;
207
208 return false;
209 }
210 }
211 }
212 }
213 catch (WebException ex)
214 {
215 m_log.InfoFormat("[USER AGENT CONNECTOR]: exception on reply of DoCreateChildAgentCall {0}", ex.Message);
216 reason = "Destination did not reply";
217 return false;
218 }
219 finally
220 {
221 if (sr != null)
222 sr.Close();
223 }
224
225 return true;
226 139
140 uint flags = fromLogin ? (uint)TeleportFlags.ViaLogin : (uint)TeleportFlags.ViaHome;
141 return CreateAgent(source, home, aCircuit, flags, out reason);
227 } 142 }
228 143
229 144
230 // The simulators call this interface 145 // The simulators call this interface
231 public bool LoginAgentToGrid(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason) 146 public bool LoginAgentToGrid(GridRegion source, AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, out string reason)
232 { 147 {
233 return LoginAgentToGrid(aCircuit, gatekeeper, destination, null, out reason); 148 return LoginAgentToGrid(source, aCircuit, gatekeeper, destination, false, out reason);
234 } 149 }
235 150
236 protected OSDMap PackCreateAgentArguments(AgentCircuitData aCircuit, GridRegion gatekeeper, GridRegion destination, IPEndPoint ipaddress) 151 protected override void PackData(OSDMap args, GridRegion source, AgentCircuitData aCircuit, GridRegion destination, uint flags)
237 { 152 {
238 OSDMap args = null; 153 base.PackData(args, source, aCircuit, destination, flags);
239 try 154 args["gatekeeper_serveruri"] = OSD.FromString(m_Gatekeeper.ServerURI);
240 { 155 args["gatekeeper_host"] = OSD.FromString(m_Gatekeeper.ExternalHostName);
241 args = aCircuit.PackAgentCircuitData(); 156 args["gatekeeper_port"] = OSD.FromString(m_Gatekeeper.HttpPort.ToString());
242 }
243 catch (Exception e)
244 {
245 m_log.Debug("[USER AGENT CONNECTOR]: PackAgentCircuitData failed with exception: " + e.Message);
246 }
247
248 // Add the input arguments
249 args["gatekeeper_serveruri"] = OSD.FromString(gatekeeper.ServerURI);
250 args["gatekeeper_host"] = OSD.FromString(gatekeeper.ExternalHostName);
251 args["gatekeeper_port"] = OSD.FromString(gatekeeper.HttpPort.ToString());
252 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
253 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
254 args["destination_name"] = OSD.FromString(destination.RegionName);
255 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
256 args["destination_serveruri"] = OSD.FromString(destination.ServerURI); 157 args["destination_serveruri"] = OSD.FromString(destination.ServerURI);
257
258 // 10/3/2010
259 // I added the client_ip up to the regular AgentCircuitData, so this doesn't need to be here.
260 // This need cleaning elsewhere...
261 //if (ipaddress != null)
262 // args["client_ip"] = OSD.FromString(ipaddress.Address.ToString());
263
264 return args;
265 } 158 }
266 159
267 public void SetClientToken(UUID sessionID, string token) 160 public void SetClientToken(UUID sessionID, string token)
@@ -269,96 +162,111 @@ namespace OpenSim.Services.Connectors.Hypergrid
269 // no-op 162 // no-op
270 } 163 }
271 164
272 public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt) 165 private Hashtable CallServer(string methodName, Hashtable hash)
273 { 166 {
274 position = Vector3.UnitY; lookAt = Vector3.UnitY;
275
276 Hashtable hash = new Hashtable();
277 hash["userID"] = userID.ToString();
278
279 IList paramList = new ArrayList(); 167 IList paramList = new ArrayList();
280 paramList.Add(hash); 168 paramList.Add(hash);
281 169
282 XmlRpcRequest request = new XmlRpcRequest("get_home_region", paramList); 170 XmlRpcRequest request = new XmlRpcRequest(methodName, paramList);
171
172 // Send and get reply
283 XmlRpcResponse response = null; 173 XmlRpcResponse response = null;
284 try 174 try
285 { 175 {
286 response = request.Send(m_ServerURL, 10000); 176 response = request.Send(m_ServerURL, 10000);
287 } 177 }
288 catch (Exception) 178 catch (Exception e)
289 { 179 {
290 return null; 180 m_log.DebugFormat("[USER AGENT CONNECTOR]: {0} call to {1} failed: {2}", methodName, m_ServerURLHost, e.Message);
181 throw;
291 } 182 }
292 183
293 if (response.IsFault) 184 if (response.IsFault)
294 { 185 {
295 return null; 186 throw new Exception(string.Format("[USER AGENT CONNECTOR]: {0} call to {1} returned an error: {2}", methodName, m_ServerURLHost, response.FaultString));
296 } 187 }
297 188
298 hash = (Hashtable)response.Value; 189 hash = (Hashtable)response.Value;
299 //foreach (Object o in hash) 190
300 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); 191 if (hash == null)
301 try
302 { 192 {
303 bool success = false; 193 throw new Exception(string.Format("[USER AGENT CONNECTOR]: {0} call to {1} returned null", methodName, m_ServerURLHost));
304 Boolean.TryParse((string)hash["result"], out success); 194 }
305 if (success)
306 {
307 GridRegion region = new GridRegion();
308 195
309 UUID.TryParse((string)hash["uuid"], out region.RegionID); 196 return hash;
310 //m_log.Debug(">> HERE, uuid: " + region.RegionID); 197 }
311 int n = 0;
312 if (hash["x"] != null)
313 {
314 Int32.TryParse((string)hash["x"], out n);
315 region.RegionLocX = n;
316 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
317 }
318 if (hash["y"] != null)
319 {
320 Int32.TryParse((string)hash["y"], out n);
321 region.RegionLocY = n;
322 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
323 }
324 if (hash["region_name"] != null)
325 {
326 region.RegionName = (string)hash["region_name"];
327 //m_log.Debug(">> HERE, name: " + region.RegionName);
328 }
329 if (hash["hostname"] != null)
330 region.ExternalHostName = (string)hash["hostname"];
331 if (hash["http_port"] != null)
332 {
333 uint p = 0;
334 UInt32.TryParse((string)hash["http_port"], out p);
335 region.HttpPort = p;
336 }
337 if (hash.ContainsKey("server_uri") && hash["server_uri"] != null)
338 region.ServerURI = (string)hash["server_uri"];
339 198
340 if (hash["internal_port"] != null) 199 public GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt)
341 { 200 {
342 int p = 0; 201 position = Vector3.UnitY; lookAt = Vector3.UnitY;
343 Int32.TryParse((string)hash["internal_port"], out p);
344 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
345 }
346 if (hash["position"] != null)
347 Vector3.TryParse((string)hash["position"], out position);
348 if (hash["lookAt"] != null)
349 Vector3.TryParse((string)hash["lookAt"], out lookAt);
350 202
351 // Successful return 203 Hashtable hash = new Hashtable();
352 return region; 204 hash["userID"] = userID.ToString();
353 } 205
206 hash = CallServer("get_home_region", hash);
207
208 bool success;
209 if (!Boolean.TryParse((string)hash["result"], out success) || !success)
210 return null;
211
212 GridRegion region = new GridRegion();
354 213
214 UUID.TryParse((string)hash["uuid"], out region.RegionID);
215 //m_log.Debug(">> HERE, uuid: " + region.RegionID);
216 int n = 0;
217 if (hash["x"] != null)
218 {
219 Int32.TryParse((string)hash["x"], out n);
220 region.RegionLocX = n;
221 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
355 } 222 }
356 catch (Exception) 223 if (hash["y"] != null)
357 { 224 {
358 return null; 225 Int32.TryParse((string)hash["y"], out n);
226 region.RegionLocY = n;
227 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
228 }
229 if (hash["size_x"] != null)
230 {
231 Int32.TryParse((string)hash["size_x"], out n);
232 region.RegionSizeX = n;
233 //m_log.Debug(">> HERE, x: " + region.RegionLocX);
359 } 234 }
235 if (hash["size_y"] != null)
236 {
237 Int32.TryParse((string)hash["size_y"], out n);
238 region.RegionSizeY = n;
239 //m_log.Debug(">> HERE, y: " + region.RegionLocY);
240 }
241 if (hash["region_name"] != null)
242 {
243 region.RegionName = (string)hash["region_name"];
244 //m_log.Debug(">> HERE, name: " + region.RegionName);
245 }
246 if (hash["hostname"] != null)
247 region.ExternalHostName = (string)hash["hostname"];
248 if (hash["http_port"] != null)
249 {
250 uint p = 0;
251 UInt32.TryParse((string)hash["http_port"], out p);
252 region.HttpPort = p;
253 }
254 if (hash.ContainsKey("server_uri") && hash["server_uri"] != null)
255 region.ServerURI = (string)hash["server_uri"];
360 256
361 return null; 257 if (hash["internal_port"] != null)
258 {
259 int p = 0;
260 Int32.TryParse((string)hash["internal_port"], out p);
261 region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p);
262 }
263 if (hash["position"] != null)
264 Vector3.TryParse((string)hash["position"], out position);
265 if (hash["lookAt"] != null)
266 Vector3.TryParse((string)hash["lookAt"], out lookAt);
267
268 // Successful return
269 return region;
362 } 270 }
363 271
364 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName) 272 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
@@ -445,14 +353,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
445 } 353 }
446 catch 354 catch
447 { 355 {
448 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for StatusNotification", m_ServerURL); 356 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for StatusNotification", m_ServerURLHost);
449// reason = "Exception: " + e.Message; 357// reason = "Exception: " + e.Message;
450 return friendsOnline; 358 return friendsOnline;
451 } 359 }
452 360
453 if (response.IsFault) 361 if (response.IsFault)
454 { 362 {
455 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for StatusNotification returned an error: {1}", m_ServerURL, response.FaultString); 363 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for StatusNotification returned an error: {1}", m_ServerURLHost, response.FaultString);
456// reason = "XMLRPC Fault"; 364// reason = "XMLRPC Fault";
457 return friendsOnline; 365 return friendsOnline;
458 } 366 }
@@ -464,7 +372,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
464 { 372 {
465 if (hash == null) 373 if (hash == null)
466 { 374 {
467 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 375 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURLHost);
468// reason = "Internal error 1"; 376// reason = "Internal error 1";
469 return friendsOnline; 377 return friendsOnline;
470 } 378 }
@@ -517,14 +425,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
517 } 425 }
518 catch 426 catch
519 { 427 {
520 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetOnlineFriends", m_ServerURL); 428 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetOnlineFriends", m_ServerURLHost);
521// reason = "Exception: " + e.Message; 429// reason = "Exception: " + e.Message;
522 return online; 430 return online;
523 } 431 }
524 432
525 if (response.IsFault) 433 if (response.IsFault)
526 { 434 {
527 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetOnlineFriends returned an error: {1}", m_ServerURL, response.FaultString); 435 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetOnlineFriends returned an error: {1}", m_ServerURLHost, response.FaultString);
528// reason = "XMLRPC Fault"; 436// reason = "XMLRPC Fault";
529 return online; 437 return online;
530 } 438 }
@@ -536,7 +444,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
536 { 444 {
537 if (hash == null) 445 if (hash == null)
538 { 446 {
539 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 447 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetOnlineFriends Got null response from {0}! THIS IS BAAAAD", m_ServerURLHost);
540// reason = "Internal error 1"; 448// reason = "Internal error 1";
541 return online; 449 return online;
542 } 450 }
@@ -567,51 +475,17 @@ namespace OpenSim.Services.Connectors.Hypergrid
567 Hashtable hash = new Hashtable(); 475 Hashtable hash = new Hashtable();
568 hash["userID"] = userID.ToString(); 476 hash["userID"] = userID.ToString();
569 477
570 IList paramList = new ArrayList(); 478 hash = CallServer("get_user_info", hash);
571 paramList.Add(hash);
572
573 XmlRpcRequest request = new XmlRpcRequest("get_user_info", paramList);
574 479
575 Dictionary<string, object> info = new Dictionary<string, object>(); 480 Dictionary<string, object> info = new Dictionary<string, object>();
576 XmlRpcResponse response = null;
577 try
578 {
579 response = request.Send(m_ServerURL, 10000);
580 }
581 catch
582 {
583 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUserInfo", m_ServerURL);
584 return info;
585 }
586 481
587 if (response.IsFault) 482 foreach (object key in hash.Keys)
588 { 483 {
589 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetServerURLs returned an error: {1}", m_ServerURL, response.FaultString); 484 if (hash[key] != null)
590 return info;
591 }
592
593 hash = (Hashtable)response.Value;
594 try
595 {
596 if (hash == null)
597 {
598 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUserInfo Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
599 return info;
600 }
601
602 // Here is the actual response
603 foreach (object key in hash.Keys)
604 { 485 {
605 if (hash[key] != null) 486 info.Add(key.ToString(), hash[key]);
606 {
607 info.Add(key.ToString(), hash[key]);
608 }
609 } 487 }
610 } 488 }
611 catch
612 {
613 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
614 }
615 489
616 return info; 490 return info;
617 } 491 }
@@ -621,60 +495,16 @@ namespace OpenSim.Services.Connectors.Hypergrid
621 Hashtable hash = new Hashtable(); 495 Hashtable hash = new Hashtable();
622 hash["userID"] = userID.ToString(); 496 hash["userID"] = userID.ToString();
623 497
624 IList paramList = new ArrayList(); 498 hash = CallServer("get_server_urls", hash);
625 paramList.Add(hash); 499
626 500 Dictionary<string, object> serverURLs = new Dictionary<string, object>();
627 XmlRpcRequest request = new XmlRpcRequest("get_server_urls", paramList); 501 foreach (object key in hash.Keys)
628// string reason = string.Empty;
629
630 // Send and get reply
631 Dictionary<string, object> serverURLs = new Dictionary<string,object>();
632 XmlRpcResponse response = null;
633 try
634 {
635 response = request.Send(m_ServerURL, 10000);
636 }
637 catch
638 {
639 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetServerURLs", m_ServerURL);
640// reason = "Exception: " + e.Message;
641 return serverURLs;
642 }
643
644 if (response.IsFault)
645 {
646 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetServerURLs returned an error: {1}", m_ServerURL, response.FaultString);
647// reason = "XMLRPC Fault";
648 return serverURLs;
649 }
650
651 hash = (Hashtable)response.Value;
652 //foreach (Object o in hash)
653 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
654 try
655 { 502 {
656 if (hash == null) 503 if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null)
657 { 504 {
658 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetServerURLs Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 505 string serverType = key.ToString().Substring(4); // remove "SRV_"
659// reason = "Internal error 1"; 506 serverURLs.Add(serverType, hash[key].ToString());
660 return serverURLs;
661 } 507 }
662
663 // Here is the actual response
664 foreach (object key in hash.Keys)
665 {
666 if (key is string && ((string)key).StartsWith("SRV_") && hash[key] != null)
667 {
668 string serverType = key.ToString().Substring(4); // remove "SRV_"
669 serverURLs.Add(serverType, hash[key].ToString());
670 }
671 }
672
673 }
674 catch
675 {
676 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetOnlineFriends response.");
677// reason = "Exception: " + e.Message;
678 } 508 }
679 509
680 return serverURLs; 510 return serverURLs;
@@ -685,55 +515,13 @@ namespace OpenSim.Services.Connectors.Hypergrid
685 Hashtable hash = new Hashtable(); 515 Hashtable hash = new Hashtable();
686 hash["userID"] = userID.ToString(); 516 hash["userID"] = userID.ToString();
687 517
688 IList paramList = new ArrayList(); 518 hash = CallServer("locate_user", hash);
689 paramList.Add(hash);
690 519
691 XmlRpcRequest request = new XmlRpcRequest("locate_user", paramList);
692// string reason = string.Empty;
693
694 // Send and get reply
695 string url = string.Empty; 520 string url = string.Empty;
696 XmlRpcResponse response = null;
697 try
698 {
699 response = request.Send(m_ServerURL, 10000);
700 }
701 catch
702 {
703 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for LocateUser", m_ServerURL);
704// reason = "Exception: " + e.Message;
705 return url;
706 }
707 521
708 if (response.IsFault) 522 // Here's the actual response
709 { 523 if (hash.ContainsKey("URL"))
710 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for LocateUser returned an error: {1}", m_ServerURL, response.FaultString); 524 url = hash["URL"].ToString();
711// reason = "XMLRPC Fault";
712 return url;
713 }
714
715 hash = (Hashtable)response.Value;
716 //foreach (Object o in hash)
717 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
718 try
719 {
720 if (hash == null)
721 {
722 m_log.ErrorFormat("[USER AGENT CONNECTOR]: LocateUser Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
723// reason = "Internal error 1";
724 return url;
725 }
726
727 // Here's the actual response
728 if (hash.ContainsKey("URL"))
729 url = hash["URL"].ToString();
730
731 }
732 catch
733 {
734 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
735// reason = "Exception: " + e.Message;
736 }
737 525
738 return url; 526 return url;
739 } 527 }
@@ -744,55 +532,13 @@ namespace OpenSim.Services.Connectors.Hypergrid
744 hash["userID"] = userID.ToString(); 532 hash["userID"] = userID.ToString();
745 hash["targetUserID"] = targetUserID.ToString(); 533 hash["targetUserID"] = targetUserID.ToString();
746 534
747 IList paramList = new ArrayList(); 535 hash = CallServer("get_uui", hash);
748 paramList.Add(hash);
749
750 XmlRpcRequest request = new XmlRpcRequest("get_uui", paramList);
751// string reason = string.Empty;
752 536
753 // Send and get reply
754 string uui = string.Empty; 537 string uui = string.Empty;
755 XmlRpcResponse response = null;
756 try
757 {
758 response = request.Send(m_ServerURL, 10000);
759 }
760 catch
761 {
762 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUI", m_ServerURL);
763// reason = "Exception: " + e.Message;
764 return uui;
765 }
766
767 if (response.IsFault)
768 {
769 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUI returned an error: {1}", m_ServerURL, response.FaultString);
770// reason = "XMLRPC Fault";
771 return uui;
772 }
773
774 hash = (Hashtable)response.Value;
775 //foreach (Object o in hash)
776 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
777 try
778 {
779 if (hash == null)
780 {
781 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
782// reason = "Internal error 1";
783 return uui;
784 }
785 538
786 // Here's the actual response 539 // Here's the actual response
787 if (hash.ContainsKey("UUI")) 540 if (hash.ContainsKey("UUI"))
788 uui = hash["UUI"].ToString(); 541 uui = hash["UUI"].ToString();
789
790 }
791 catch
792 {
793 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetUUI response.");
794// reason = "Exception: " + e.Message;
795 }
796 542
797 return uui; 543 return uui;
798 } 544 }
@@ -803,54 +549,17 @@ namespace OpenSim.Services.Connectors.Hypergrid
803 hash["first"] = first; 549 hash["first"] = first;
804 hash["last"] = last; 550 hash["last"] = last;
805 551
806 IList paramList = new ArrayList(); 552 hash = CallServer("get_uuid", hash);
807 paramList.Add(hash);
808 553
809 XmlRpcRequest request = new XmlRpcRequest("get_uuid", paramList); 554 if (!hash.ContainsKey("UUID"))
810 // string reason = string.Empty;
811
812 // Send and get reply
813 UUID uuid = UUID.Zero;
814 XmlRpcResponse response = null;
815 try
816 {
817 response = request.Send(m_ServerURL, 10000);
818 }
819 catch
820 { 555 {
821 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUID", m_ServerURL); 556 throw new Exception(string.Format("[USER AGENT CONNECTOR]: get_uuid call to {0} didn't return a UUID", m_ServerURLHost));
822 // reason = "Exception: " + e.Message;
823 return uuid;
824 } 557 }
825 558
826 if (response.IsFault) 559 UUID uuid;
827 { 560 if (!UUID.TryParse(hash["UUID"].ToString(), out uuid))
828 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUID returned an error: {1}", m_ServerURL, response.FaultString);
829 // reason = "XMLRPC Fault";
830 return uuid;
831 }
832
833 hash = (Hashtable)response.Value;
834 //foreach (Object o in hash)
835 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
836 try
837 {
838 if (hash == null)
839 {
840 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUDI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
841 // reason = "Internal error 1";
842 return uuid;
843 }
844
845 // Here's the actual response
846 if (hash.ContainsKey("UUID"))
847 UUID.TryParse(hash["UUID"].ToString(), out uuid);
848
849 }
850 catch
851 { 561 {
852 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on UUID response."); 562 throw new Exception(string.Format("[USER AGENT CONNECTOR]: get_uuid call to {0} returned an invalid UUID: {1}", m_ServerURLHost, hash["UUID"].ToString()));
853 // reason = "Exception: " + e.Message;
854 } 563 }
855 564
856 return uuid; 565 return uuid;
@@ -858,7 +567,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
858 567
859 private bool GetBoolResponse(XmlRpcRequest request, out string reason) 568 private bool GetBoolResponse(XmlRpcRequest request, out string reason)
860 { 569 {
861 //m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL); 570 //m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURLHost);
862 XmlRpcResponse response = null; 571 XmlRpcResponse response = null;
863 try 572 try
864 { 573 {
@@ -866,14 +575,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
866 } 575 }
867 catch (Exception e) 576 catch (Exception e)
868 { 577 {
869 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetBoolResponse", m_ServerURL); 578 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetBoolResponse", m_ServerURLHost);
870 reason = "Exception: " + e.Message; 579 reason = "Exception: " + e.Message;
871 return false; 580 return false;
872 } 581 }
873 582
874 if (response.IsFault) 583 if (response.IsFault)
875 { 584 {
876 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetBoolResponse returned an error: {1}", m_ServerURL, response.FaultString); 585 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetBoolResponse returned an error: {1}", m_ServerURLHost, response.FaultString);
877 reason = "XMLRPC Fault"; 586 reason = "XMLRPC Fault";
878 return false; 587 return false;
879 } 588 }
@@ -885,7 +594,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
885 { 594 {
886 if (hash == null) 595 if (hash == null)
887 { 596 {
888 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got null response from {0}! THIS IS BAAAAD", m_ServerURL); 597 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got null response from {0}! THIS IS BAAAAD", m_ServerURLHost);
889 reason = "Internal error 1"; 598 reason = "Internal error 1";
890 return false; 599 return false;
891 } 600 }
@@ -896,7 +605,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
896 else 605 else
897 { 606 {
898 reason = "Internal error 2"; 607 reason = "Internal error 2";
899 m_log.WarnFormat("[USER AGENT CONNECTOR]: response from {0} does not have expected key 'result'", m_ServerURL); 608 m_log.WarnFormat("[USER AGENT CONNECTOR]: response from {0} does not have expected key 'result'", m_ServerURLHost);
900 } 609 }
901 610
902 return success; 611 return success;
diff --git a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
index dbce9f6..e19c23d 100644
--- a/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
+++ b/OpenSim/Services/Connectors/InstantMessage/InstantMessageServiceConnector.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Services.Connectors.InstantMessage
123 gim["position_z"] = msg.Position.Z.ToString(); 123 gim["position_z"] = msg.Position.Z.ToString();
124 gim["region_id"] = msg.RegionID.ToString(); 124 gim["region_id"] = msg.RegionID.ToString();
125 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None); 125 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket, Base64FormattingOptions.None);
126 gim["region_id"] = new UUID(msg.RegionID).ToString();
126 127
127 return gim; 128 return gim;
128 } 129 }
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
index 44f5e01..7cecd93 100644
--- a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs
@@ -33,22 +33,37 @@ using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Console; 35using OpenSim.Framework.Console;
36using OpenSim.Framework.Communications; 36
37using OpenSim.Framework.Monitoring;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
38using OpenSim.Server.Base; 39using OpenSim.Server.Base;
39using OpenMetaverse; 40using OpenMetaverse;
40 41
41namespace OpenSim.Services.Connectors 42namespace OpenSim.Services.Connectors
42{ 43{
43 public class XInventoryServicesConnector : IInventoryService 44 public class XInventoryServicesConnector : BaseServiceConnector, IInventoryService
44 { 45 {
45 private static readonly ILog m_log = 46 private static readonly ILog m_log =
46 LogManager.GetLogger( 47 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType); 48 MethodBase.GetCurrentMethod().DeclaringType);
48 49
50 /// <summary>
51 /// Number of requests made to the remote inventory service.
52 /// </summary>
53 public int RequestsMade { get; private set; }
54
49 private string m_ServerURI = String.Empty; 55 private string m_ServerURI = String.Empty;
50 56
51 private object m_Lock = new object(); 57 /// <summary>
58 /// Timeout for remote requests.
59 /// </summary>
60 /// <remarks>
61 /// In this case, -1 is default timeout (100 seconds), not infinite.
62 /// </remarks>
63 private int m_requestTimeoutSecs = -1;
64
65 private const double CACHE_EXPIRATION_SECONDS = 20.0;
66 private static ExpiringCache<UUID, InventoryItemBase> m_ItemCache = new ExpiringCache<UUID,InventoryItemBase>();
52 67
53 public XInventoryServicesConnector() 68 public XInventoryServicesConnector()
54 { 69 {
@@ -60,20 +75,21 @@ namespace OpenSim.Services.Connectors
60 } 75 }
61 76
62 public XInventoryServicesConnector(IConfigSource source) 77 public XInventoryServicesConnector(IConfigSource source)
78 : base(source, "InventoryService")
63 { 79 {
64 Initialise(source); 80 Initialise(source);
65 } 81 }
66 82
67 public virtual void Initialise(IConfigSource source) 83 public virtual void Initialise(IConfigSource source)
68 { 84 {
69 IConfig assetConfig = source.Configs["InventoryService"]; 85 IConfig config = source.Configs["InventoryService"];
70 if (assetConfig == null) 86 if (config == null)
71 { 87 {
72 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini"); 88 m_log.Error("[INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
73 throw new Exception("Inventory connector init error"); 89 throw new Exception("Inventory connector init error");
74 } 90 }
75 91
76 string serviceURI = assetConfig.GetString("InventoryServerURI", 92 string serviceURI = config.GetString("InventoryServerURI",
77 String.Empty); 93 String.Empty);
78 94
79 if (serviceURI == String.Empty) 95 if (serviceURI == String.Empty)
@@ -82,6 +98,45 @@ namespace OpenSim.Services.Connectors
82 throw new Exception("Inventory connector init error"); 98 throw new Exception("Inventory connector init error");
83 } 99 }
84 m_ServerURI = serviceURI; 100 m_ServerURI = serviceURI;
101
102 m_requestTimeoutSecs = config.GetInt("RemoteRequestTimeout", m_requestTimeoutSecs);
103
104 StatsManager.RegisterStat(
105 new Stat(
106 "RequestsMade",
107 "Requests made",
108 "Number of requests made to the remove inventory service",
109 "requests",
110 "inventory",
111 serviceURI,
112 StatType.Pull,
113 MeasuresOfInterest.AverageChangeOverTime,
114 s => s.Value = RequestsMade,
115 StatVerbosity.Debug));
116 }
117
118 private bool CheckReturn(Dictionary<string, object> ret)
119 {
120 if (ret == null)
121 return false;
122
123 if (ret.Count == 0)
124 return false;
125
126 if (ret.ContainsKey("RESULT"))
127 {
128 if (ret["RESULT"] is string)
129 {
130 bool result;
131
132 if (bool.TryParse((string)ret["RESULT"], out result))
133 return result;
134
135 return false;
136 }
137 }
138
139 return true;
85 } 140 }
86 141
87 public bool CreateUserInventory(UUID principalID) 142 public bool CreateUserInventory(UUID principalID)
@@ -91,12 +146,7 @@ namespace OpenSim.Services.Connectors
91 { "PRINCIPAL", principalID.ToString() } 146 { "PRINCIPAL", principalID.ToString() }
92 }); 147 });
93 148
94 if (ret == null) 149 return CheckReturn(ret);
95 return false;
96 if (ret.Count == 0)
97 return false;
98
99 return bool.Parse(ret["RESULT"].ToString());
100 } 150 }
101 151
102 public List<InventoryFolderBase> GetInventorySkeleton(UUID principalID) 152 public List<InventoryFolderBase> GetInventorySkeleton(UUID principalID)
@@ -106,9 +156,7 @@ namespace OpenSim.Services.Connectors
106 { "PRINCIPAL", principalID.ToString() } 156 { "PRINCIPAL", principalID.ToString() }
107 }); 157 });
108 158
109 if (ret == null) 159 if (!CheckReturn(ret))
110 return null;
111 if (ret.Count == 0)
112 return null; 160 return null;
113 161
114 Dictionary<string, object> folders = (Dictionary<string, object>)ret["FOLDERS"]; 162 Dictionary<string, object> folders = (Dictionary<string, object>)ret["FOLDERS"];
@@ -135,15 +183,13 @@ namespace OpenSim.Services.Connectors
135 { "PRINCIPAL", principalID.ToString() } 183 { "PRINCIPAL", principalID.ToString() }
136 }); 184 });
137 185
138 if (ret == null) 186 if (!CheckReturn(ret))
139 return null;
140 if (ret.Count == 0)
141 return null; 187 return null;
142 188
143 return BuildFolder((Dictionary<string, object>)ret["folder"]); 189 return BuildFolder((Dictionary<string, object>)ret["folder"]);
144 } 190 }
145 191
146 public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 192 public InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
147 { 193 {
148 Dictionary<string,object> ret = MakeRequest("GETFOLDERFORTYPE", 194 Dictionary<string,object> ret = MakeRequest("GETFOLDERFORTYPE",
149 new Dictionary<string,object> { 195 new Dictionary<string,object> {
@@ -151,9 +197,7 @@ namespace OpenSim.Services.Connectors
151 { "TYPE", ((int)type).ToString() } 197 { "TYPE", ((int)type).ToString() }
152 }); 198 });
153 199
154 if (ret == null) 200 if (!CheckReturn(ret))
155 return null;
156 if (ret.Count == 0)
157 return null; 201 return null;
158 202
159 return BuildFolder((Dictionary<string, object>)ret["folder"]); 203 return BuildFolder((Dictionary<string, object>)ret["folder"]);
@@ -164,7 +208,7 @@ namespace OpenSim.Services.Connectors
164 InventoryCollection inventory = new InventoryCollection(); 208 InventoryCollection inventory = new InventoryCollection();
165 inventory.Folders = new List<InventoryFolderBase>(); 209 inventory.Folders = new List<InventoryFolderBase>();
166 inventory.Items = new List<InventoryItemBase>(); 210 inventory.Items = new List<InventoryItemBase>();
167 inventory.UserID = principalID; 211 inventory.OwnerID = principalID;
168 212
169 try 213 try
170 { 214 {
@@ -174,20 +218,20 @@ namespace OpenSim.Services.Connectors
174 { "FOLDER", folderID.ToString() } 218 { "FOLDER", folderID.ToString() }
175 }); 219 });
176 220
177 if (ret == null) 221 if (!CheckReturn(ret))
178 return null;
179 if (ret.Count == 0)
180 return null; 222 return null;
181 223
182 Dictionary<string,object> folders = 224 Dictionary<string,object> folders = ret.ContainsKey("FOLDERS") ?
183 (Dictionary<string,object>)ret["FOLDERS"]; 225 (Dictionary<string,object>)ret["FOLDERS"] : null;
184 Dictionary<string,object> items = 226 Dictionary<string,object> items = ret.ContainsKey("ITEMS") ?
185 (Dictionary<string,object>)ret["ITEMS"]; 227 (Dictionary<string, object>)ret["ITEMS"] : null;
186 228
187 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i 229 if (folders != null)
188 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o)); 230 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
189 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i 231 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o));
190 inventory.Items.Add(BuildItem((Dictionary<string, object>)o)); 232 if (items != null)
233 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
234 inventory.Items.Add(BuildItem((Dictionary<string, object>)o));
191 } 235 }
192 catch (Exception e) 236 catch (Exception e)
193 { 237 {
@@ -196,6 +240,87 @@ namespace OpenSim.Services.Connectors
196 240
197 return inventory; 241 return inventory;
198 } 242 }
243
244 public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
245 {
246 InventoryCollection[] inventoryArr = new InventoryCollection[folderIDs.Length];
247 // m_log.DebugFormat("[XXX]: In GetMultipleFoldersContent {0}", String.Join(",", folderIDs));
248 try
249 {
250 Dictionary<string, object> resultSet = MakeRequest("GETMULTIPLEFOLDERSCONTENT",
251 new Dictionary<string, object> {
252 { "PRINCIPAL", principalID.ToString() },
253 { "FOLDERS", String.Join(",", folderIDs) },
254 { "COUNT", folderIDs.Length.ToString() }
255 });
256
257 if (!CheckReturn(resultSet))
258 return null;
259
260 int i = 0;
261 foreach (KeyValuePair<string, object> kvp in resultSet)
262 {
263 InventoryCollection inventory = new InventoryCollection();
264 if (kvp.Key.StartsWith("F_"))
265 {
266 UUID fid = UUID.Zero;
267 if (UUID.TryParse(kvp.Key.Substring(2), out fid) && fid == folderIDs[i])
268 {
269 inventory.Folders = new List<InventoryFolderBase>();
270 inventory.Items = new List<InventoryItemBase>();
271
272 Dictionary<string, object> ret = (Dictionary<string, object>)kvp.Value;
273
274 if (ret.ContainsKey("FID"))
275 {
276 if (!UUID.TryParse(ret["FID"].ToString(), out inventory.FolderID))
277 m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Could not parse folder id {0}", ret["FID"].ToString());
278 }
279 else
280 m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: FID key not present in response");
281
282 inventory.Version = -1;
283 if (ret.ContainsKey("VERSION"))
284 Int32.TryParse(ret["VERSION"].ToString(), out inventory.Version);
285 if (ret.ContainsKey("OWNER"))
286 UUID.TryParse(ret["OWNER"].ToString(), out inventory.OwnerID);
287
288 //m_log.DebugFormat("[XXX]: Received {0} ({1}) {2} {3}", inventory.FolderID, fid, inventory.Version, inventory.OwnerID);
289
290 Dictionary<string, object> folders =
291 (Dictionary<string, object>)ret["FOLDERS"];
292 Dictionary<string, object> items =
293 (Dictionary<string, object>)ret["ITEMS"];
294
295 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
296 {
297 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o));
298 }
299 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
300 {
301 inventory.Items.Add(BuildItem((Dictionary<string, object>)o));
302 }
303
304 inventoryArr[i] = inventory;
305 }
306 else
307 {
308 m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Folder id does not match. Expected {0} got {1}",
309 folderIDs[i], fid);
310 m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: {0} {1}", String.Join(",", folderIDs), String.Join(",", resultSet.Keys));
311 }
312
313 i += 1;
314 }
315 }
316 }
317 catch (Exception e)
318 {
319 m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleFoldersContent: {0}", e.Message);
320 }
321
322 return inventoryArr;
323 }
199 324
200 public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) 325 public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
201 { 326 {
@@ -205,9 +330,7 @@ namespace OpenSim.Services.Connectors
205 { "FOLDER", folderID.ToString() } 330 { "FOLDER", folderID.ToString() }
206 }); 331 });
207 332
208 if (ret == null) 333 if (!CheckReturn(ret))
209 return null;
210 if (ret.Count == 0)
211 return null; 334 return null;
212 335
213 Dictionary<string, object> items = (Dictionary<string, object>)ret["ITEMS"]; 336 Dictionary<string, object> items = (Dictionary<string, object>)ret["ITEMS"];
@@ -230,10 +353,7 @@ namespace OpenSim.Services.Connectors
230 { "ID", folder.ID.ToString() } 353 { "ID", folder.ID.ToString() }
231 }); 354 });
232 355
233 if (ret == null) 356 return CheckReturn(ret);
234 return false;
235
236 return bool.Parse(ret["RESULT"].ToString());
237 } 357 }
238 358
239 public bool UpdateFolder(InventoryFolderBase folder) 359 public bool UpdateFolder(InventoryFolderBase folder)
@@ -248,10 +368,7 @@ namespace OpenSim.Services.Connectors
248 { "ID", folder.ID.ToString() } 368 { "ID", folder.ID.ToString() }
249 }); 369 });
250 370
251 if (ret == null) 371 return CheckReturn(ret);
252 return false;
253
254 return bool.Parse(ret["RESULT"].ToString());
255 } 372 }
256 373
257 public bool MoveFolder(InventoryFolderBase folder) 374 public bool MoveFolder(InventoryFolderBase folder)
@@ -263,10 +380,7 @@ namespace OpenSim.Services.Connectors
263 { "PRINCIPAL", folder.Owner.ToString() } 380 { "PRINCIPAL", folder.Owner.ToString() }
264 }); 381 });
265 382
266 if (ret == null) 383 return CheckReturn(ret);
267 return false;
268
269 return bool.Parse(ret["RESULT"].ToString());
270 } 384 }
271 385
272 public bool DeleteFolders(UUID principalID, List<UUID> folderIDs) 386 public bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
@@ -282,10 +396,7 @@ namespace OpenSim.Services.Connectors
282 { "FOLDERS", slist } 396 { "FOLDERS", slist }
283 }); 397 });
284 398
285 if (ret == null) 399 return CheckReturn(ret);
286 return false;
287
288 return bool.Parse(ret["RESULT"].ToString());
289 } 400 }
290 401
291 public bool PurgeFolder(InventoryFolderBase folder) 402 public bool PurgeFolder(InventoryFolderBase folder)
@@ -295,17 +406,18 @@ namespace OpenSim.Services.Connectors
295 { "ID", folder.ID.ToString() } 406 { "ID", folder.ID.ToString() }
296 }); 407 });
297 408
298 if (ret == null) 409 return CheckReturn(ret);
299 return false;
300
301 return bool.Parse(ret["RESULT"].ToString());
302 } 410 }
303 411
304 public bool AddItem(InventoryItemBase item) 412 public bool AddItem(InventoryItemBase item)
305 { 413 {
414 if (item.Description == null)
415 item.Description = String.Empty;
306 if (item.CreatorData == null) 416 if (item.CreatorData == null)
307 item.CreatorData = String.Empty; 417 item.CreatorData = String.Empty;
308 Dictionary<string,object> ret = MakeRequest("ADDITEM", 418 if (item.CreatorId == null)
419 item.CreatorId = String.Empty;
420 Dictionary<string, object> ret = MakeRequest("ADDITEM",
309 new Dictionary<string,object> { 421 new Dictionary<string,object> {
310 { "AssetID", item.AssetID.ToString() }, 422 { "AssetID", item.AssetID.ToString() },
311 { "AssetType", item.AssetType.ToString() }, 423 { "AssetType", item.AssetType.ToString() },
@@ -330,10 +442,7 @@ namespace OpenSim.Services.Connectors
330 { "CreationDate", item.CreationDate.ToString() } 442 { "CreationDate", item.CreationDate.ToString() }
331 }); 443 });
332 444
333 if (ret == null) 445 return CheckReturn(ret);
334 return false;
335
336 return bool.Parse(ret["RESULT"].ToString());
337 } 446 }
338 447
339 public bool UpdateItem(InventoryItemBase item) 448 public bool UpdateItem(InventoryItemBase item)
@@ -365,10 +474,13 @@ namespace OpenSim.Services.Connectors
365 { "CreationDate", item.CreationDate.ToString() } 474 { "CreationDate", item.CreationDate.ToString() }
366 }); 475 });
367 476
368 if (ret == null) 477 bool result = CheckReturn(ret);
369 return false; 478 if (result)
479 {
480 m_ItemCache.AddOrUpdate(item.ID, item, CACHE_EXPIRATION_SECONDS);
481 }
370 482
371 return bool.Parse(ret["RESULT"].ToString()); 483 return result;
372 } 484 }
373 485
374 public bool MoveItems(UUID principalID, List<InventoryItemBase> items) 486 public bool MoveItems(UUID principalID, List<InventoryItemBase> items)
@@ -389,10 +501,7 @@ namespace OpenSim.Services.Connectors
389 { "DESTLIST", destlist } 501 { "DESTLIST", destlist }
390 }); 502 });
391 503
392 if (ret == null) 504 return CheckReturn(ret);
393 return false;
394
395 return bool.Parse(ret["RESULT"].ToString());
396 } 505 }
397 506
398 public bool DeleteItems(UUID principalID, List<UUID> itemIDs) 507 public bool DeleteItems(UUID principalID, List<UUID> itemIDs)
@@ -408,14 +517,17 @@ namespace OpenSim.Services.Connectors
408 { "ITEMS", slist } 517 { "ITEMS", slist }
409 }); 518 });
410 519
411 if (ret == null) 520 return CheckReturn(ret);
412 return false;
413
414 return bool.Parse(ret["RESULT"].ToString());
415 } 521 }
416 522
417 public InventoryItemBase GetItem(InventoryItemBase item) 523 public InventoryItemBase GetItem(InventoryItemBase item)
418 { 524 {
525 InventoryItemBase retrieved = null;
526 if (m_ItemCache.TryGetValue(item.ID, out retrieved))
527 {
528 return retrieved;
529 }
530
419 try 531 try
420 { 532 {
421 Dictionary<string, object> ret = MakeRequest("GETITEM", 533 Dictionary<string, object> ret = MakeRequest("GETITEM",
@@ -423,19 +535,81 @@ namespace OpenSim.Services.Connectors
423 { "ID", item.ID.ToString() } 535 { "ID", item.ID.ToString() }
424 }); 536 });
425 537
426 if (ret == null) 538 if (!CheckReturn(ret))
427 return null;
428 if (ret.Count == 0)
429 return null; 539 return null;
430 540
431 return BuildItem((Dictionary<string, object>)ret["item"]); 541 retrieved = BuildItem((Dictionary<string, object>)ret["item"]);
432 } 542 }
433 catch (Exception e) 543 catch (Exception e)
434 { 544 {
435 m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception in GetItem: ", e); 545 m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception in GetItem: ", e);
436 } 546 }
437 547
438 return null; 548 m_ItemCache.AddOrUpdate(item.ID, retrieved, CACHE_EXPIRATION_SECONDS);
549
550 return retrieved;
551 }
552
553 public virtual InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs)
554 {
555 //m_log.DebugFormat("[XXX]: In GetMultipleItems {0}", String.Join(",", itemIDs));
556
557 InventoryItemBase[] itemArr = new InventoryItemBase[itemIDs.Length];
558 // Try to get them from the cache
559 List<UUID> pending = new List<UUID>();
560 InventoryItemBase item = null;
561 int i = 0;
562 foreach (UUID id in itemIDs)
563 {
564 if (m_ItemCache.TryGetValue(id, out item))
565 itemArr[i++] = item;
566 else
567 pending.Add(id);
568 }
569
570 if (pending.Count == 0) // we're done, everything was in the cache
571 return itemArr;
572
573 try
574 {
575 Dictionary<string, object> resultSet = MakeRequest("GETMULTIPLEITEMS",
576 new Dictionary<string, object> {
577 { "PRINCIPAL", principalID.ToString() },
578 { "ITEMS", String.Join(",", pending.ToArray()) },
579 { "COUNT", pending.Count.ToString() }
580 });
581
582 if (!CheckReturn(resultSet))
583 {
584 if (i == 0)
585 return null;
586 else
587 return itemArr;
588 }
589
590 // carry over index i where we left above
591 foreach (KeyValuePair<string, object> kvp in resultSet)
592 {
593 InventoryCollection inventory = new InventoryCollection();
594 if (kvp.Key.StartsWith("item_"))
595 {
596 if (kvp.Value is Dictionary<string, object>)
597 {
598 item = BuildItem((Dictionary<string, object>)kvp.Value);
599 m_ItemCache.AddOrUpdate(item.ID, item, CACHE_EXPIRATION_SECONDS);
600 itemArr[i++] = item;
601 }
602 else
603 itemArr[i++] = null;
604 }
605 }
606 }
607 catch (Exception e)
608 {
609 m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleItems: {0}", e.Message);
610 }
611
612 return itemArr;
439 } 613 }
440 614
441 public InventoryFolderBase GetFolder(InventoryFolderBase folder) 615 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
@@ -447,9 +621,7 @@ namespace OpenSim.Services.Connectors
447 { "ID", folder.ID.ToString() } 621 { "ID", folder.ID.ToString() }
448 }); 622 });
449 623
450 if (ret == null) 624 if (!CheckReturn(ret))
451 return null;
452 if (ret.Count == 0)
453 return null; 625 return null;
454 626
455 return BuildFolder((Dictionary<string, object>)ret["folder"]); 627 return BuildFolder((Dictionary<string, object>)ret["folder"]);
@@ -469,7 +641,7 @@ namespace OpenSim.Services.Connectors
469 { "PRINCIPAL", principalID.ToString() } 641 { "PRINCIPAL", principalID.ToString() }
470 }); 642 });
471 643
472 if (ret == null) 644 if (!CheckReturn(ret))
473 return null; 645 return null;
474 646
475 List<InventoryItemBase> items = new List<InventoryItemBase>(); 647 List<InventoryItemBase> items = new List<InventoryItemBase>();
@@ -488,51 +660,22 @@ namespace OpenSim.Services.Connectors
488 { "ASSET", assetID.ToString() } 660 { "ASSET", assetID.ToString() }
489 }); 661 });
490 662
663 // We cannot use CheckReturn() here because valid values for RESULT are "false" (in the case of request failure) or an int
491 if (ret == null) 664 if (ret == null)
492 return 0; 665 return 0;
493 666
494 return int.Parse(ret["RESULT"].ToString()); 667 if (ret.ContainsKey("RESULT"))
495 }
496
497 public InventoryCollection GetUserInventory(UUID principalID)
498 {
499 InventoryCollection inventory = new InventoryCollection();
500 inventory.Folders = new List<InventoryFolderBase>();
501 inventory.Items = new List<InventoryItemBase>();
502 inventory.UserID = principalID;
503
504 try
505 { 668 {
506 Dictionary<string, object> ret = MakeRequest("GETUSERINVENTORY", 669 if (ret["RESULT"] is string)
507 new Dictionary<string, object> { 670 {
508 { "PRINCIPAL", principalID.ToString() } 671 int intResult;
509 });
510
511 if (ret == null)
512 return null;
513 if (ret.Count == 0)
514 return null;
515
516 Dictionary<string, object> folders =
517 (Dictionary<string, object>)ret["FOLDERS"];
518 Dictionary<string, object> items =
519 (Dictionary<string, object>)ret["ITEMS"];
520 672
521 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i 673 if (int.TryParse ((string)ret["RESULT"], out intResult))
522 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o)); 674 return intResult;
523 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i 675 }
524 inventory.Items.Add(BuildItem((Dictionary<string, object>)o));
525 } 676 }
526 catch (Exception e)
527 {
528 m_log.Error("[XINVENTORY SERVICES CONNECTOR]: Exception in GetUserInventory: ", e);
529 }
530
531 return inventory;
532 }
533 677
534 public void GetUserInventory(UUID principalID, InventoryReceiptCallback callback) 678 return 0;
535 {
536 } 679 }
537 680
538 public bool HasInventoryForUser(UUID principalID) 681 public bool HasInventoryForUser(UUID principalID)
@@ -545,13 +688,19 @@ namespace OpenSim.Services.Connectors
545 private Dictionary<string,object> MakeRequest(string method, 688 private Dictionary<string,object> MakeRequest(string method,
546 Dictionary<string,object> sendData) 689 Dictionary<string,object> sendData)
547 { 690 {
548 sendData["METHOD"] = method; 691 // Add "METHOD" as the first key in the dictionary. This ensures that it will be
692 // visible even when using partial logging ("debug http all 5").
693 Dictionary<string, object> temp = sendData;
694 sendData = new Dictionary<string,object>{ { "METHOD", method } };
695 foreach (KeyValuePair<string, object> kvp in temp)
696 sendData.Add(kvp.Key, kvp.Value);
697
698 RequestsMade++;
549 699
550 string reply = string.Empty; 700 string reply
551 lock (m_Lock) 701 = SynchronousRestFormsRequester.MakeRequest(
552 reply = SynchronousRestFormsRequester.MakeRequest("POST", 702 "POST", m_ServerURI + "/xinventory",
553 m_ServerURI + "/xinventory", 703 ServerUtils.BuildQueryString(sendData), m_requestTimeoutSecs, m_Auth);
554 ServerUtils.BuildQueryString(sendData));
555 704
556 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse( 705 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(
557 reply); 706 reply);
@@ -619,4 +768,4 @@ namespace OpenSim.Services.Connectors
619 return item; 768 return item;
620 } 769 }
621 } 770 }
622} \ No newline at end of file 771}
diff --git a/OpenSim/Services/Connectors/Land/LandServicesConnector.cs b/OpenSim/Services/Connectors/Land/LandServicesConnector.cs
index 30a73a4..034c42e 100644
--- a/OpenSim/Services/Connectors/Land/LandServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Land/LandServicesConnector.cs
@@ -33,7 +33,7 @@ using System.IO;
33using System.Reflection; 33using System.Reflection;
34using Nini.Config; 34using Nini.Config;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Framework.Communications; 36
37using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
38using OpenMetaverse; 38using OpenMetaverse;
39using Nwc.XmlRpc; 39using Nwc.XmlRpc;
@@ -78,7 +78,7 @@ namespace OpenSim.Services.Connectors
78 try 78 try
79 { 79 {
80 uint xpos = 0, ypos = 0; 80 uint xpos = 0, ypos = 0;
81 Utils.LongToUInts(regionHandle, out xpos, out ypos); 81 Util.RegionHandleToWorldLoc(regionHandle, out xpos, out ypos);
82 GridRegion info = m_GridService.GetRegionByPosition(scopeID, (int)xpos, (int)ypos); 82 GridRegion info = m_GridService.GetRegionByPosition(scopeID, (int)xpos, (int)ypos);
83 if (info != null) // just to be sure 83 if (info != null) // just to be sure
84 { 84 {
diff --git a/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs b/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs
index 30bfb70..c91ed84 100644
--- a/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs
+++ b/OpenSim/Services/Connectors/MapImage/MapImageServicesConnector.cs
@@ -35,7 +35,8 @@ using System.Reflection;
35using Nini.Config; 35using Nini.Config;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Framework.Console; 37using OpenSim.Framework.Console;
38using OpenSim.Framework.Communications; 38
39using OpenSim.Framework.ServiceAuth;
39using OpenSim.Server.Base; 40using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces; 41using OpenSim.Services.Interfaces;
41using OpenMetaverse; 42using OpenMetaverse;
@@ -43,7 +44,7 @@ using OpenMetaverse.StructuredData;
43 44
44namespace OpenSim.Services.Connectors 45namespace OpenSim.Services.Connectors
45{ 46{
46 public class MapImageServicesConnector : IMapImageService 47 public class MapImageServicesConnector : BaseServiceConnector, IMapImageService
47 { 48 {
48 private static readonly ILog m_log = 49 private static readonly ILog m_log =
49 LogManager.GetLogger( 50 LogManager.GetLogger(
@@ -84,26 +85,26 @@ namespace OpenSim.Services.Connectors
84 } 85 }
85 m_ServerURI = serviceURI; 86 m_ServerURI = serviceURI;
86 m_ServerURI = serviceURI.TrimEnd('/'); 87 m_ServerURI = serviceURI.TrimEnd('/');
88 base.Initialise(source, "MapImageService");
87 } 89 }
88 90
89 public bool AddMapTile(int x, int y, byte[] jpgData, out string reason) 91 public bool RemoveMapTile(int x, int y, out string reason)
90 { 92 {
91 reason = string.Empty; 93 reason = string.Empty;
92 int tickstart = Util.EnvironmentTickCount(); 94 int tickstart = Util.EnvironmentTickCount();
93 Dictionary<string, object> sendData = new Dictionary<string, object>(); 95 Dictionary<string, object> sendData = new Dictionary<string, object>();
94 sendData["X"] = x.ToString(); 96 sendData["X"] = x.ToString();
95 sendData["Y"] = y.ToString(); 97 sendData["Y"] = y.ToString();
96 sendData["TYPE"] = "image/jpeg";
97 sendData["DATA"] = Convert.ToBase64String(jpgData);
98 98
99 string reqString = ServerUtils.BuildQueryString(sendData); 99 string reqString = ServerUtils.BuildQueryString(sendData);
100 string uri = m_ServerURI + "/map"; 100 string uri = m_ServerURI + "/removemap";
101 101
102 try 102 try
103 { 103 {
104 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 104 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
105 uri, 105 uri,
106 reqString); 106 reqString,
107 m_Auth);
107 if (reply != string.Empty) 108 if (reply != string.Empty)
108 { 109 {
109 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 110 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -114,7 +115,7 @@ namespace OpenSim.Services.Connectors
114 } 115 }
115 else if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "failure")) 116 else if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "failure"))
116 { 117 {
117 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Registration failed: {0}", replyData["Message"].ToString()); 118 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: Delete failed: {0}", replyData["Message"].ToString());
118 reason = replyData["Message"].ToString(); 119 reason = replyData["Message"].ToString();
119 return false; 120 return false;
120 } 121 }
@@ -142,6 +143,72 @@ namespace OpenSim.Services.Connectors
142 { 143 {
143 // This just dumps a warning for any operation that takes more than 100 ms 144 // This just dumps a warning for any operation that takes more than 100 ms
144 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart); 145 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
146 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile deleted in {0}ms", tickdiff);
147 }
148
149 return false;
150 }
151
152 public bool AddMapTile(int x, int y, byte[] jpgData, out string reason)
153 {
154 reason = string.Empty;
155 int tickstart = Util.EnvironmentTickCount();
156 Dictionary<string, object> sendData = new Dictionary<string, object>();
157 sendData["X"] = x.ToString();
158 sendData["Y"] = y.ToString();
159 sendData["TYPE"] = "image/jpeg";
160 sendData["DATA"] = Convert.ToBase64String(jpgData);
161
162 string reqString = ServerUtils.BuildQueryString(sendData);
163 string uri = m_ServerURI + "/map";
164
165 try
166 {
167 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
168 uri,
169 reqString,
170 m_Auth);
171 if (reply != string.Empty)
172 {
173 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
174
175 if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "success"))
176 {
177 return true;
178 }
179 else if (replyData.ContainsKey("Result") && (replyData["Result"].ToString().ToLower() == "failure"))
180 {
181 reason = string.Format("Map post to {0} failed: {1}", uri, replyData["Message"].ToString());
182 m_log.WarnFormat("[MAP IMAGE CONNECTOR]: {0}", reason);
183
184 return false;
185 }
186 else if (!replyData.ContainsKey("Result"))
187 {
188 reason = string.Format("Reply data from {0} does not contain result field", uri);
189 m_log.WarnFormat("[MAP IMAGE CONNECTOR]: {0}", reason);
190 }
191 else
192 {
193 reason = string.Format("Unexpected result {0} from {1}" + replyData["Result"].ToString(), uri);
194 m_log.WarnFormat("[MAP IMAGE CONNECTOR]: {0}", reason);
195 }
196 }
197 else
198 {
199 reason = string.Format("Map post received null reply from {0}", uri);
200 m_log.WarnFormat("[MAP IMAGE CONNECTOR]: {0}", reason);
201 }
202 }
203 catch (Exception e)
204 {
205 reason = string.Format("Exception when posting to map server at {0}: {1}", uri, e.Message);
206 m_log.WarnFormat("[MAP IMAGE CONNECTOR]: {0}", reason);
207 }
208 finally
209 {
210 // This just dumps a warning for any operation that takes more than 100 ms
211 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
145 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff); 212 m_log.DebugFormat("[MAP IMAGE CONNECTOR]: map tile uploaded in {0}ms", tickdiff);
146 } 213 }
147 214
diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs
index 7429293..925364a 100644
--- a/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServicesConnector.cs
@@ -35,7 +35,7 @@ using System.Reflection;
35using System.Text; 35using System.Text;
36using Nini.Config; 36using Nini.Config;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Communications; 38
39using OpenSim.Services.Interfaces; 39using OpenSim.Services.Interfaces;
40using OpenMetaverse; 40using OpenMetaverse;
41using OpenMetaverse.StructuredData; 41using OpenMetaverse.StructuredData;
@@ -69,7 +69,7 @@ namespace OpenSim.Services.Connectors
69 public virtual GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion) 69 public virtual GridRegion HelloNeighbour(ulong regionHandle, RegionInfo thisRegion)
70 { 70 {
71 uint x = 0, y = 0; 71 uint x = 0, y = 0;
72 Utils.LongToUInts(regionHandle, out x, out y); 72 Util.RegionHandleToWorldLoc(regionHandle, out x, out y);
73 GridRegion regInfo = m_GridService.GetRegionByPosition(thisRegion.ScopeID, (int)x, (int)y); 73 GridRegion regInfo = m_GridService.GetRegionByPosition(thisRegion.ScopeID, (int)x, (int)y);
74 if ((regInfo != null) && 74 if ((regInfo != null) &&
75 // Don't remote-call this instance; that's a startup hickup 75 // Don't remote-call this instance; that's a startup hickup
@@ -97,9 +97,9 @@ namespace OpenSim.Services.Connectors
97 } 97 }
98 catch (Exception e) 98 catch (Exception e)
99 { 99 {
100 m_log.WarnFormat( 100 m_log.Warn(string.Format(
101 "[NEIGHBOUR SERVICE CONNCTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}", 101 "[NEIGHBOUR SERVICES CONNECTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3} ",
102 uri, thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); 102 uri, thisRegion.RegionName, region.RegionName, e.Message), e);
103 103
104 return false; 104 return false;
105 } 105 }
@@ -116,9 +116,9 @@ namespace OpenSim.Services.Connectors
116 } 116 }
117 catch (Exception e) 117 catch (Exception e)
118 { 118 {
119 m_log.WarnFormat( 119 m_log.Warn(string.Format(
120 "[NEIGHBOUR SERVICE CONNCTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}", 120 "[NEIGHBOUR SERVICES CONNECTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2} ",
121 thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); 121 thisRegion.RegionName, region.RegionName, e.Message), e);
122 122
123 return false; 123 return false;
124 } 124 }
@@ -136,9 +136,9 @@ namespace OpenSim.Services.Connectors
136 } 136 }
137 catch (Exception e) 137 catch (Exception e)
138 { 138 {
139 m_log.WarnFormat( 139 m_log.Warn(string.Format(
140 "[NEIGHBOUR SERVICE CONNCTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}", 140 "[NEIGHBOUR SERVICES CONNECTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2} ",
141 thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); 141 thisRegion.RegionName, region.RegionName, e.Message), e);
142 142
143 return false; 143 return false;
144 } 144 }
@@ -153,53 +153,53 @@ namespace OpenSim.Services.Connectors
153 } 153 }
154 catch (Exception e) 154 catch (Exception e)
155 { 155 {
156 m_log.WarnFormat( 156 m_log.Warn(string.Format(
157 "[NEIGHBOUR SERVICE CONNCTOR]: Unable to send HelloNeighbour from {0} to {1}. Exception {2}{3}", 157 "[NEIGHBOUR SERVICES CONNECTOR]: Unable to send HelloNeighbour from {0} to {1} (uri {2}). Exception {3} ",
158 thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace); 158 thisRegion.RegionName, region.RegionName, uri, e.Message), e);
159 159
160 return false; 160 return false;
161 } 161 }
162 finally 162 finally
163 { 163 {
164 if (os != null) 164 if (os != null)
165 os.Close(); 165 os.Dispose();
166 } 166 }
167 167
168 // Let's wait for the response 168 // Let's wait for the response
169 //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall"); 169 //m_log.Info("[REST COMMS]: Waiting for a reply after DoHelloNeighbourCall");
170 170
171 StreamReader sr = null;
172 try 171 try
173 { 172 {
174 WebResponse webResponse = helloNeighbourRequest.GetResponse(); 173 using (WebResponse webResponse = helloNeighbourRequest.GetResponse())
175 if (webResponse == null)
176 { 174 {
177 m_log.DebugFormat( 175 if (webResponse == null)
178 "[REST COMMS]: Null reply on DoHelloNeighbourCall post from {0} to {1}", 176 {
179 thisRegion.RegionName, region.RegionName); 177 m_log.DebugFormat(
178 "[NEIGHBOUR SERVICES CONNECTOR]: Null reply on DoHelloNeighbourCall post from {0} to {1}",
179 thisRegion.RegionName, region.RegionName);
180 }
181
182 using (Stream s = webResponse.GetResponseStream())
183 {
184 using (StreamReader sr = new StreamReader(s))
185 {
186 //reply = sr.ReadToEnd().Trim();
187 sr.ReadToEnd().Trim();
188 //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply);
189 }
190 }
180 } 191 }
181
182 sr = new StreamReader(webResponse.GetResponseStream());
183 //reply = sr.ReadToEnd().Trim();
184 sr.ReadToEnd().Trim();
185 //m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply);
186
187 } 192 }
188 catch (Exception e) 193 catch (Exception e)
189 { 194 {
190 m_log.WarnFormat( 195 m_log.Warn(string.Format(
191 "[NEIGHBOUR SERVICE CONNCTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}", 196 "[NEIGHBOUR SERVICES CONNECTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2} ",
192 region.RegionName, thisRegion.RegionName, e.Message, e.StackTrace); 197 region.RegionName, thisRegion.RegionName, e.Message), e);
193 198
194 return false; 199 return false;
195 } 200 }
196 finally
197 {
198 if (sr != null)
199 sr.Close();
200 }
201 201
202 return true; 202 return true;
203 } 203 }
204 } 204 }
205} \ No newline at end of file 205}
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs
index f7d8c53..b7e95c4 100644
--- a/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs
+++ b/OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs
@@ -32,7 +32,8 @@ using System.IO;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35
36using OpenSim.Framework.ServiceAuth;
36using OpenSim.Services.Interfaces; 37using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion; 38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38using OpenSim.Server.Base; 39using OpenSim.Server.Base;
@@ -40,7 +41,7 @@ using OpenMetaverse;
40 41
41namespace OpenSim.Services.Connectors 42namespace OpenSim.Services.Connectors
42{ 43{
43 public class PresenceServicesConnector : IPresenceService 44 public class PresenceServicesConnector : BaseServiceConnector, IPresenceService
44 { 45 {
45 private static readonly ILog m_log = 46 private static readonly ILog m_log =
46 LogManager.GetLogger( 47 LogManager.GetLogger(
@@ -80,6 +81,8 @@ namespace OpenSim.Services.Connectors
80 throw new Exception("Presence connector init error"); 81 throw new Exception("Presence connector init error");
81 } 82 }
82 m_ServerURI = serviceURI; 83 m_ServerURI = serviceURI;
84
85 base.Initialise(source, "PresenceService");
83 } 86 }
84 87
85 88
@@ -104,7 +107,8 @@ namespace OpenSim.Services.Connectors
104 { 107 {
105 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 108 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
106 uri, 109 uri,
107 reqString); 110 reqString,
111 m_Auth);
108 if (reply != string.Empty) 112 if (reply != string.Empty)
109 { 113 {
110 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 114 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -149,7 +153,8 @@ namespace OpenSim.Services.Connectors
149 { 153 {
150 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 154 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
151 uri, 155 uri,
152 reqString); 156 reqString,
157 m_Auth);
153 if (reply != string.Empty) 158 if (reply != string.Empty)
154 { 159 {
155 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 160 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -193,7 +198,8 @@ namespace OpenSim.Services.Connectors
193 { 198 {
194 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 199 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
195 uri, 200 uri,
196 reqString); 201 reqString,
202 m_Auth);
197 if (reply != string.Empty) 203 if (reply != string.Empty)
198 { 204 {
199 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 205 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -238,7 +244,8 @@ namespace OpenSim.Services.Connectors
238 { 244 {
239 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 245 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
240 uri, 246 uri,
241 reqString); 247 reqString,
248 m_Auth);
242 if (reply != string.Empty) 249 if (reply != string.Empty)
243 { 250 {
244 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 251 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -283,7 +290,8 @@ namespace OpenSim.Services.Connectors
283 { 290 {
284 reply = SynchronousRestFormsRequester.MakeRequest("POST", 291 reply = SynchronousRestFormsRequester.MakeRequest("POST",
285 uri, 292 uri,
286 reqString); 293 reqString,
294 m_Auth);
287 if (reply == null || (reply != null && reply == string.Empty)) 295 if (reply == null || (reply != null && reply == string.Empty))
288 { 296 {
289 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply"); 297 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply");
@@ -293,6 +301,7 @@ namespace OpenSim.Services.Connectors
293 catch (Exception e) 301 catch (Exception e)
294 { 302 {
295 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message); 303 m_log.DebugFormat("[PRESENCE CONNECTOR]: Exception when contacting presence server at {0}: {1}", uri, e.Message);
304 return null;
296 } 305 }
297 306
298 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 307 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
@@ -327,7 +336,8 @@ namespace OpenSim.Services.Connectors
327 { 336 {
328 reply = SynchronousRestFormsRequester.MakeRequest("POST", 337 reply = SynchronousRestFormsRequester.MakeRequest("POST",
329 uri, 338 uri,
330 reqString); 339 reqString,
340 m_Auth);
331 if (reply == null || (reply != null && reply == string.Empty)) 341 if (reply == null || (reply != null && reply == string.Empty))
332 { 342 {
333 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null or empty reply"); 343 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null or empty reply");
diff --git a/OpenSim/Services/Connectors/Properties/AssemblyInfo.cs b/OpenSim/Services/Connectors/Properties/AssemblyInfo.cs
index bfb681b..c581a59 100644
--- a/OpenSim/Services/Connectors/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/Connectors/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
index 95e4bab..cd4781d 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianActivityDetector.cs
@@ -69,7 +69,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
69 Util.FireAndForget(delegate(object o) 69 Util.FireAndForget(delegate(object o)
70 { 70 {
71 m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); 71 m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
72 }); 72 }, null, "SimianActivityDetector.SetLastPositionOnMakeRootAgent");
73 } 73 }
74 74
75 public void OnNewClient(IClientAPI client) 75 public void OnNewClient(IClientAPI client)
@@ -94,7 +94,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
94 Util.FireAndForget(delegate(object o) 94 Util.FireAndForget(delegate(object o)
95 { 95 {
96 m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat); 96 m_GridUserService.SetLastPosition(sp.UUID.ToString(), sp.ControllingClient.SessionId, sp.Scene.RegionInfo.RegionID, sp.AbsolutePosition, sp.Lookat);
97 }); 97 }, null, "SimianActivityDetector.SetLastPositionOnEnteringNewParcel");
98 } 98 }
99 } 99 }
100} \ No newline at end of file 100} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
index 63a32e7..9ad4a7a 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Collections.Specialized;
30using System.IO; 31using System.IO;
31using System.Net; 32using System.Net;
32using System.Reflection; 33using System.Reflection;
@@ -122,7 +123,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
122 m_Enabled = true; 123 m_Enabled = true;
123 } 124 }
124 125
125 #region IAssetService 126#region IAssetService
126 127
127 public AssetBase Get(string id) 128 public AssetBase Get(string id)
128 { 129 {
@@ -140,8 +141,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
140 return asset; 141 return asset;
141 } 142 }
142 143
143 return GetRemote(id); 144 return SimianGetOperation(id);
144 } 145 }
146
145 147
146 public AssetBase GetCached(string id) 148 public AssetBase GetCached(string id)
147 { 149 {
@@ -164,8 +166,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
164 throw new InvalidOperationException(); 166 throw new InvalidOperationException();
165 } 167 }
166 168
167 AssetMetadata metadata = null;
168
169 // Cache fetch 169 // Cache fetch
170 if (m_cache != null) 170 if (m_cache != null)
171 { 171 {
@@ -174,50 +174,18 @@ namespace OpenSim.Services.Connectors.SimianGrid
174 return asset.Metadata; 174 return asset.Metadata;
175 } 175 }
176 176
177 Uri url; 177 // return GetRemoteMetadata(id);
178 178 return SimianGetMetadataOperation(id);
179 // Determine if id is an absolute URL or a grid-relative UUID
180 if (!Uri.TryCreate(id, UriKind.Absolute, out url))
181 url = new Uri(m_serverUrl + id);
182
183 try
184 {
185 HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
186 request.Method = "HEAD";
187
188 using (WebResponse response = request.GetResponse())
189 {
190 using (Stream responseStream = response.GetResponseStream())
191 {
192 // Create the metadata object
193 metadata = new AssetMetadata();
194 metadata.ContentType = response.ContentType;
195 metadata.ID = id;
196
197 UUID uuid;
198 if (UUID.TryParse(id, out uuid))
199 metadata.FullID = uuid;
200
201 string lastModifiedStr = response.Headers.Get("Last-Modified");
202 if (!String.IsNullOrEmpty(lastModifiedStr))
203 {
204 DateTime lastModified;
205 if (DateTime.TryParse(lastModifiedStr, out lastModified))
206 metadata.CreationDate = lastModified;
207 }
208 }
209 }
210 }
211 catch (Exception ex)
212 {
213 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset HEAD from " + url + " failed: " + ex.Message);
214 }
215
216 return metadata;
217 } 179 }
218 180
219 public byte[] GetData(string id) 181 public byte[] GetData(string id)
220 { 182 {
183 if (String.IsNullOrEmpty(m_serverUrl))
184 {
185 m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI configured");
186 throw new InvalidOperationException();
187 }
188
221 AssetBase asset = Get(id); 189 AssetBase asset = Get(id);
222 190
223 if (asset != null) 191 if (asset != null)
@@ -255,14 +223,34 @@ namespace OpenSim.Services.Connectors.SimianGrid
255 Util.FireAndForget( 223 Util.FireAndForget(
256 delegate(object o) 224 delegate(object o)
257 { 225 {
258 AssetBase asset = GetRemote(id); 226 AssetBase asset = SimianGetOperation(id);
259 handler(id, sender, asset); 227 handler(id, sender, asset);
260 } 228 }, null, "SimianAssetServiceConnector.GetFromService"
261 ); 229 );
262 230
263 return true; 231 return true;
264 } 232 }
265 233
234 public bool[] AssetsExist(string[] ids)
235 {
236 if (String.IsNullOrEmpty(m_serverUrl))
237 {
238 m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI configured");
239 throw new InvalidOperationException();
240 }
241
242 bool[] exist = new bool[ids.Length];
243
244 for (int i = 0; i < ids.Length; i++)
245 {
246 AssetMetadata metadata = GetMetadata(ids[i]);
247 if (metadata != null)
248 exist[i] = true;
249 }
250
251 return exist;
252 }
253
266 /// <summary> 254 /// <summary>
267 /// Creates a new asset 255 /// Creates a new asset
268 /// </summary> 256 /// </summary>
@@ -278,7 +266,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
278 } 266 }
279 267
280 bool storedInCache = false; 268 bool storedInCache = false;
281 string errorMessage = null;
282 269
283 // AssetID handling 270 // AssetID handling
284 if (String.IsNullOrEmpty(asset.ID) || asset.ID == ZeroID) 271 if (String.IsNullOrEmpty(asset.ID) || asset.ID == ZeroID)
@@ -307,80 +294,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
307 return asset.ID; 294 return asset.ID;
308 } 295 }
309 296
310 // Distinguish public and private assets 297 return SimianStoreOperation(asset);
311 bool isPublic = true;
312 switch ((AssetType)asset.Type)
313 {
314 case AssetType.CallingCard:
315 case AssetType.Gesture:
316 case AssetType.LSLBytecode:
317 case AssetType.LSLText:
318 isPublic = false;
319 break;
320 }
321
322 // Make sure ContentType is set
323 if (String.IsNullOrEmpty(asset.Metadata.ContentType))
324 asset.Metadata.ContentType = SLUtil.SLAssetTypeToContentType(asset.Type);
325
326 // Build the remote storage request
327 List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
328 {
329 new MultipartForm.Parameter("AssetID", asset.FullID.ToString()),
330 new MultipartForm.Parameter("CreatorID", asset.Metadata.CreatorID),
331 new MultipartForm.Parameter("Temporary", asset.Temporary ? "1" : "0"),
332 new MultipartForm.Parameter("Public", isPublic ? "1" : "0"),
333 new MultipartForm.File("Asset", asset.Name, asset.Metadata.ContentType, asset.Data)
334 };
335
336 // Make the remote storage request
337 try
338 {
339 // Simian does not require the asset ID to be in the URL because it's in the post data.
340 // By appending it to the URL also, we allow caching proxies (squid) to invalidate asset URLs
341 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl + asset.FullID.ToString());
342
343 HttpWebResponse response = MultipartForm.Post(request, postParameters);
344 using (Stream responseStream = response.GetResponseStream())
345 {
346 string responseStr = null;
347
348 try
349 {
350 responseStr = responseStream.GetStreamString();
351 OSD responseOSD = OSDParser.Deserialize(responseStr);
352 if (responseOSD.Type == OSDType.Map)
353 {
354 OSDMap responseMap = (OSDMap)responseOSD;
355 if (responseMap["Success"].AsBoolean())
356 return asset.ID;
357 else
358 errorMessage = "Upload failed: " + responseMap["Message"].AsString();
359 }
360 else
361 {
362 errorMessage = "Response format was invalid:\n" + responseStr;
363 }
364 }
365 catch (Exception ex)
366 {
367 if (!String.IsNullOrEmpty(responseStr))
368 errorMessage = "Failed to parse the response:\n" + responseStr;
369 else
370 errorMessage = "Failed to retrieve the response: " + ex.Message;
371 }
372 }
373 }
374 catch (WebException ex)
375 {
376 errorMessage = ex.Message;
377 }
378
379 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to store asset \"{0}\" ({1}, {2}): {3}",
380 asset.Name, asset.ID, asset.Metadata.ContentType, errorMessage);
381 return null;
382 } 298 }
383 299
384 /// <summary> 300 /// <summary>
385 /// Update an asset's content 301 /// Update an asset's content
386 /// </summary> 302 /// </summary>
@@ -390,11 +306,17 @@ namespace OpenSim.Services.Connectors.SimianGrid
390 /// <returns></returns> 306 /// <returns></returns>
391 public bool UpdateContent(string id, byte[] data) 307 public bool UpdateContent(string id, byte[] data)
392 { 308 {
309 if (String.IsNullOrEmpty(m_serverUrl))
310 {
311 m_log.Error("[SIMIAN ASSET CONNECTOR]: No AssetServerURI configured");
312 throw new InvalidOperationException();
313 }
314
393 AssetBase asset = Get(id); 315 AssetBase asset = Get(id);
394 316
395 if (asset == null) 317 if (asset == null)
396 { 318 {
397 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Failed to fetch asset " + id + " for updating"); 319 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to fetch asset {0} for updating", id);
398 return false; 320 return false;
399 } 321 }
400 322
@@ -417,83 +339,347 @@ namespace OpenSim.Services.Connectors.SimianGrid
417 throw new InvalidOperationException(); 339 throw new InvalidOperationException();
418 } 340 }
419 341
420 //string errorMessage = String.Empty;
421 string url = m_serverUrl + id;
422
423 if (m_cache != null) 342 if (m_cache != null)
424 m_cache.Expire(id); 343 m_cache.Expire(id);
425 344
345 return SimianDeleteOperation(id);
346 }
347
348#endregion IAssetService
349
350#region SimianOperations
351 /// <summary>
352 /// Invokes the xRemoveAsset operation on the simian server to delete an asset
353 /// </summary>
354 /// <param name="id"></param>
355 /// <returns></returns>
356 private bool SimianDeleteOperation(string id)
357 {
426 try 358 try
427 { 359 {
428 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); 360 NameValueCollection requestArgs = new NameValueCollection
429 request.Method = "DELETE"; 361 {
362 { "RequestMethod", "xRemoveAsset" },
363 { "AssetID", id }
364 };
430 365
431 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 366 OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs);
367 if (! response["Success"].AsBoolean())
432 { 368 {
433 if (response.StatusCode != HttpStatusCode.NoContent) 369 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: failed to delete asset; {0}",response["Message"].AsString());
434 { 370 return false;
435 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Unexpected response when deleting asset " + url + ": " +
436 response.StatusCode + " (" + response.StatusDescription + ")");
437 }
438 } 371 }
439 372
440 return true; 373 return true;
374
441 } 375 }
442 catch (Exception ex) 376 catch (Exception ex)
443 { 377 {
444 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Failed to delete asset " + id + " from the asset service: " + ex.Message); 378 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: failed to delete asset {0}; {1}", id, ex.Message);
445 return false;
446 } 379 }
447 }
448 380
449 #endregion IAssetService 381 return false;
382 }
450 383
451 private AssetBase GetRemote(string id) 384 /// <summary>
385 /// Invokes the xAddAsset operation on the simian server to create or update an asset
386 /// </summary>
387 /// <param name="id"></param>
388 /// <returns></returns>
389 private string SimianStoreOperation(AssetBase asset)
452 { 390 {
453 AssetBase asset = null; 391 try
454 Uri url; 392 {
393 NameValueCollection requestArgs = new NameValueCollection
394 {
395 { "RequestMethod", "xAddAsset" },
396 { "ContentType", asset.Metadata.ContentType },
397 { "EncodedData", Convert.ToBase64String(asset.Data) },
398 { "AssetID", asset.FullID.ToString() },
399 { "CreatorID", asset.Metadata.CreatorID },
400 { "Temporary", asset.Temporary ? "1" : "0" },
401 { "Name", asset.Name }
402 };
403
404 OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs);
405 if (! response["Success"].AsBoolean())
406 {
407 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR] failed to store asset; {0}",response["Message"].AsString());
408 return null;
409 }
455 410
456 // Determine if id is an absolute URL or a grid-relative UUID 411 // asset.ID is always set before calling this function
457 if (!Uri.TryCreate(id, UriKind.Absolute, out url)) 412 return asset.ID;
458 url = new Uri(m_serverUrl + id); 413
414 }
415 catch (Exception ex)
416 {
417 m_log.ErrorFormat("[SIMIAN ASSET CONNECTOR] failed to store asset; {0}",ex.Message);
418 }
419
420 return null;
421 }
459 422
460 try 423 /// <summary>
424 /// Invokes the xGetAsset operation on the simian server to get data associated with an asset
425 /// </summary>
426 /// <param name="id"></param>
427 /// <returns></returns>
428 private AssetBase SimianGetOperation(string id)
429 {
430 try
461 { 431 {
462 HttpWebRequest request = UntrustedHttpWebRequest.Create(url); 432 NameValueCollection requestArgs = new NameValueCollection
433 {
434 { "RequestMethod", "xGetAsset" },
435 { "ID", id }
436 };
463 437
464 using (WebResponse response = request.GetResponse()) 438 OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs);
439 if (! response["Success"].AsBoolean())
465 { 440 {
466 using (Stream responseStream = response.GetResponseStream()) 441 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR] Failed to get asset; {0}",response["Message"].AsString());
467 { 442 return null;
468 string creatorID = response.Headers.GetOne("X-Asset-Creator-Id") ?? String.Empty;
469
470 // Create the asset object
471 asset = new AssetBase(id, String.Empty, SLUtil.ContentTypeToSLAssetType(response.ContentType), creatorID);
472
473 UUID assetID;
474 if (UUID.TryParse(id, out assetID))
475 asset.FullID = assetID;
476
477 // Grab the asset data from the response stream
478 using (MemoryStream stream = new MemoryStream())
479 {
480 responseStream.CopyStream(stream, Int32.MaxValue);
481 asset.Data = stream.ToArray();
482 }
483 }
484 } 443 }
444
445 AssetBase asset = new AssetBase();
485 446
486 // Cache store 447 asset.ID = id;
487 if (m_cache != null && asset != null) 448 asset.Name = String.Empty;
488 m_cache.Cache(asset); 449 asset.Metadata.ContentType = response["ContentType"].AsString(); // this will also set the asset Type property
450 asset.CreatorID = response["CreatorID"].AsString();
451 asset.Data = System.Convert.FromBase64String(response["EncodedData"].AsString());
452 asset.Local = false;
453 asset.Temporary = response["Temporary"];
489 454
490 return asset; 455 return asset;
491 } 456 }
492 catch (Exception ex) 457 catch (Exception ex)
493 { 458 {
494 m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message); 459 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: failed to retrieve asset {0}; {1}", id, ex.Message);
495 return null; 460 }
461
462 return null;
463 }
464
465 /// <summary>
466 /// Invokes the xGetAssetMetadata operation on the simian server to retrieve metadata for an asset
467 /// This operation is generally used to determine if an asset exists in the database
468 /// </summary>
469 /// <param name="id"></param>
470 /// <returns></returns>
471 private AssetMetadata SimianGetMetadataOperation(string id)
472 {
473 try
474 {
475 NameValueCollection requestArgs = new NameValueCollection
476 {
477 { "RequestMethod", "xGetAssetMetadata" },
478 { "ID", id }
479 };
480
481 OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs);
482 if (! response["Success"].AsBoolean())
483 {
484 // this is not really an error, this call is used to test existence
485 // m_log.DebugFormat("[SIMIAN ASSET CONNECTOR] Failed to get asset metadata; {0}",response["Message"].AsString());
486 return null;
487 }
488
489 AssetMetadata metadata = new AssetMetadata();
490 metadata.ID = id;
491 metadata.ContentType = response["ContentType"].AsString();
492 metadata.CreatorID = response["CreatorID"].AsString();
493 metadata.Local = false;
494 metadata.Temporary = response["Temporary"];
495
496 string lastModifiedStr = response["Last-Modified"].AsString();
497 if (! String.IsNullOrEmpty(lastModifiedStr))
498 {
499 DateTime lastModified;
500 if (DateTime.TryParse(lastModifiedStr, out lastModified))
501 metadata.CreationDate = lastModified;
502 }
503
504 return metadata;
505 }
506 catch (Exception ex)
507 {
508 m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to get asset metadata; {0}", ex.Message);
496 } 509 }
510
511 return null;
497 } 512 }
513#endregion
514
515 // private AssetMetadata GetRemoteMetadata(string id)
516 // {
517 // Uri url;
518 // AssetMetadata metadata = null;
519
520 // // Determine if id is an absolute URL or a grid-relative UUID
521 // if (!Uri.TryCreate(id, UriKind.Absolute, out url))
522 // url = new Uri(m_serverUrl + id);
523
524 // try
525 // {
526 // HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
527 // request.Method = "HEAD";
528
529 // using (WebResponse response = request.GetResponse())
530 // {
531 // using (Stream responseStream = response.GetResponseStream())
532 // {
533 // // Create the metadata object
534 // metadata = new AssetMetadata();
535 // metadata.ContentType = response.ContentType;
536 // metadata.ID = id;
537
538 // UUID uuid;
539 // if (UUID.TryParse(id, out uuid))
540 // metadata.FullID = uuid;
541
542 // string lastModifiedStr = response.Headers.Get("Last-Modified");
543 // if (!String.IsNullOrEmpty(lastModifiedStr))
544 // {
545 // DateTime lastModified;
546 // if (DateTime.TryParse(lastModifiedStr, out lastModified))
547 // metadata.CreationDate = lastModified;
548 // }
549 // }
550 // }
551 // }
552 // catch (Exception ex)
553 // {
554 // m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset HEAD from " + url + " failed: " + ex.Message);
555 // }
556
557 // return metadata;
558 // }
559
560 // private AssetBase GetRemote(string id)
561 // {
562 // AssetBase asset = null;
563 // Uri url;
564
565 // // Determine if id is an absolute URL or a grid-relative UUID
566 // if (!Uri.TryCreate(id, UriKind.Absolute, out url))
567 // url = new Uri(m_serverUrl + id);
568
569 // try
570 // {
571 // HttpWebRequest request = UntrustedHttpWebRequest.Create(url);
572
573 // using (WebResponse response = request.GetResponse())
574 // {
575 // using (Stream responseStream = response.GetResponseStream())
576 // {
577 // string creatorID = response.Headers.GetOne("X-Asset-Creator-Id") ?? String.Empty;
578
579 // // Create the asset object
580 // asset = new AssetBase(id, String.Empty, SLUtil.ContentTypeToSLAssetType(response.ContentType), creatorID);
581
582 // UUID assetID;
583 // if (UUID.TryParse(id, out assetID))
584 // asset.FullID = assetID;
585
586 // // Grab the asset data from the response stream
587 // using (MemoryStream stream = new MemoryStream())
588 // {
589 // responseStream.CopyStream(stream, Int32.MaxValue);
590 // asset.Data = stream.ToArray();
591 // }
592 // }
593 // }
594
595 // // Cache store
596 // if (m_cache != null && asset != null)
597 // m_cache.Cache(asset);
598
599 // return asset;
600 // }
601 // catch (Exception ex)
602 // {
603 // m_log.Warn("[SIMIAN ASSET CONNECTOR]: Asset GET from " + url + " failed: " + ex.Message);
604 // return null;
605 // }
606 // }
607
608 // private string StoreRemote(AssetBase asset)
609 // {
610 // // Distinguish public and private assets
611 // bool isPublic = true;
612 // switch ((AssetType)asset.Type)
613 // {
614 // case AssetType.CallingCard:
615 // case AssetType.Gesture:
616 // case AssetType.LSLBytecode:
617 // case AssetType.LSLText:
618 // isPublic = false;
619 // break;
620 // }
621
622 // string errorMessage = null;
623
624 // // Build the remote storage request
625 // List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
626 // {
627 // new MultipartForm.Parameter("AssetID", asset.FullID.ToString()),
628 // new MultipartForm.Parameter("CreatorID", asset.Metadata.CreatorID),
629 // new MultipartForm.Parameter("Temporary", asset.Temporary ? "1" : "0"),
630 // new MultipartForm.Parameter("Public", isPublic ? "1" : "0"),
631 // new MultipartForm.File("Asset", asset.Name, asset.Metadata.ContentType, asset.Data)
632 // };
633
634 // // Make the remote storage request
635 // try
636 // {
637 // // Simian does not require the asset ID to be in the URL because it's in the post data.
638 // // By appending it to the URL also, we allow caching proxies (squid) to invalidate asset URLs
639 // HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl + asset.FullID.ToString());
640
641 // using (HttpWebResponse response = MultipartForm.Post(request, postParameters))
642 // {
643 // using (Stream responseStream = response.GetResponseStream())
644 // {
645 // string responseStr = null;
646
647 // try
648 // {
649 // responseStr = responseStream.GetStreamString();
650 // OSD responseOSD = OSDParser.Deserialize(responseStr);
651 // if (responseOSD.Type == OSDType.Map)
652 // {
653 // OSDMap responseMap = (OSDMap)responseOSD;
654 // if (responseMap["Success"].AsBoolean())
655 // return asset.ID;
656 // else
657 // errorMessage = "Upload failed: " + responseMap["Message"].AsString();
658 // }
659 // else
660 // {
661 // errorMessage = "Response format was invalid:\n" + responseStr;
662 // }
663 // }
664 // catch (Exception ex)
665 // {
666 // if (!String.IsNullOrEmpty(responseStr))
667 // errorMessage = "Failed to parse the response:\n" + responseStr;
668 // else
669 // errorMessage = "Failed to retrieve the response: " + ex.Message;
670 // }
671 // }
672 // }
673 // }
674 // catch (WebException ex)
675 // {
676 // errorMessage = ex.Message;
677 // }
678
679 // m_log.WarnFormat("[SIMIAN ASSET CONNECTOR]: Failed to store asset \"{0}\" ({1}, {2}): {3}",
680 // asset.Name, asset.ID, asset.Metadata.ContentType, errorMessage);
681
682 // return null;
683 // }
498 } 684 }
499} 685}
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
index 6603f6e..3bd11d9 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs
@@ -110,7 +110,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
110 { "UserID", principalID.ToString() } 110 { "UserID", principalID.ToString() }
111 }; 111 };
112 112
113 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 113 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
114 if (response["Success"].AsBoolean() && response["Identities"] is OSDArray) 114 if (response["Success"].AsBoolean() && response["Identities"] is OSDArray)
115 { 115 {
116 bool md5hashFound = false; 116 bool md5hashFound = false;
@@ -153,7 +153,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
153 { "SessionID", token } 153 { "SessionID", token }
154 }; 154 };
155 155
156 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 156 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
157 if (response["Success"].AsBoolean()) 157 if (response["Success"].AsBoolean())
158 { 158 {
159 return true; 159 return true;
@@ -175,7 +175,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
175 { "UserID", principalID.ToString() } 175 { "UserID", principalID.ToString() }
176 }; 176 };
177 177
178 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 178 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
179 if (response["Success"].AsBoolean()) 179 if (response["Success"].AsBoolean())
180 { 180 {
181 return true; 181 return true;
@@ -198,7 +198,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
198 { "UserID", principalID.ToString() } 198 { "UserID", principalID.ToString() }
199 }; 199 };
200 200
201 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 201 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
202 if (response["Success"].AsBoolean() && response["User"] is OSDMap) 202 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
203 { 203 {
204 OSDMap userMap = (OSDMap)response["User"]; 204 OSDMap userMap = (OSDMap)response["User"];
@@ -218,7 +218,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
218 { "UserID", principalID.ToString() } 218 { "UserID", principalID.ToString() }
219 }; 219 };
220 220
221 response = WebUtil.PostToService(m_serverUrl, requestArgs); 221 response = SimianGrid.PostToService(m_serverUrl, requestArgs);
222 bool success = response["Success"].AsBoolean(); 222 bool success = response["Success"].AsBoolean();
223 223
224 if (!success) 224 if (!success)
@@ -297,7 +297,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
297 { "UserID", userID.ToString() } 297 { "UserID", userID.ToString() }
298 }; 298 };
299 299
300 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 300 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
301 if (response["Success"].AsBoolean()) 301 if (response["Success"].AsBoolean())
302 return response["SessionID"].AsUUID().ToString(); 302 return response["SessionID"].AsUUID().ToString();
303 else 303 else
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
index 841bfa0..a397740 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs
@@ -122,7 +122,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
122 { "UserID", userID.ToString() } 122 { "UserID", userID.ToString() }
123 }; 123 };
124 124
125 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 125 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
126 if (response["Success"].AsBoolean()) 126 if (response["Success"].AsBoolean())
127 { 127 {
128 OSDMap map = null; 128 OSDMap map = null;
@@ -168,7 +168,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
168 { "LLPackedAppearance", OSDParser.SerializeJsonString(map) } 168 { "LLPackedAppearance", OSDParser.SerializeJsonString(map) }
169 }; 169 };
170 170
171 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 171 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
172 bool success = response["Success"].AsBoolean(); 172 bool success = response["Success"].AsBoolean();
173 173
174 if (! success) 174 if (! success)
@@ -189,7 +189,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
189 { "UserID", userID.ToString() } 189 { "UserID", userID.ToString() }
190 }; 190 };
191 191
192 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 192 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
193 if (response["Success"].AsBoolean()) 193 if (response["Success"].AsBoolean())
194 { 194 {
195 OSDMap map = null; 195 OSDMap map = null;
@@ -306,7 +306,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
306 { "LLAttachments", OSDParser.SerializeJsonString(items) } 306 { "LLAttachments", OSDParser.SerializeJsonString(items) }
307 }; 307 };
308 308
309 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 309 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
310 bool success = response["Success"].AsBoolean(); 310 bool success = response["Success"].AsBoolean();
311 311
312 if (!success) 312 if (!success)
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs
new file mode 100644
index 0000000..764e71f
--- /dev/null
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianExternalCapsModule.cs
@@ -0,0 +1,180 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using System.IO;
33using System.Web;
34
35using log4net;
36using Nini.Config;
37using Mono.Addins;
38
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41
42using OpenSim.Framework;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47
48namespace OpenSim.Services.Connectors.SimianGrid
49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianExternalCapsModule")]
51 public class SimianExternalCapsModule : INonSharedRegionModule, IExternalCapsModule
52 {
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54
55 private bool m_enabled = true;
56 private Scene m_scene;
57 private String m_simianURL;
58
59#region IRegionModule Members
60
61 public string Name
62 {
63 get { return this.GetType().Name; }
64 }
65
66 public void Initialise(IConfigSource config)
67 {
68 try
69 {
70 IConfig m_config;
71
72 if ((m_config = config.Configs["SimianExternalCaps"]) != null)
73 {
74 m_enabled = m_config.GetBoolean("Enabled", m_enabled);
75 if ((m_config = config.Configs["SimianGrid"]) != null)
76 {
77 m_simianURL = m_config.GetString("SimianServiceURL");
78 if (String.IsNullOrEmpty(m_simianURL))
79 {
80 //m_log.DebugFormat("[SimianGrid] service URL is not defined");
81 m_enabled = false;
82 return;
83 }
84 }
85 }
86 else
87 m_enabled = false;
88 }
89 catch (Exception e)
90 {
91 m_log.ErrorFormat("[SimianExternalCaps] initialization error: {0}",e.Message);
92 return;
93 }
94 }
95
96 public void PostInitialise() { }
97 public void Close() { }
98
99 public void AddRegion(Scene scene)
100 {
101 if (! m_enabled)
102 return;
103
104 m_scene = scene;
105 m_scene.RegisterModuleInterface<IExternalCapsModule>(this);
106 }
107
108 public void RemoveRegion(Scene scene)
109 {
110 if (! m_enabled)
111 return;
112
113 m_scene.EventManager.OnRegisterCaps -= RegisterCapsEventHandler;
114 m_scene.EventManager.OnDeregisterCaps -= DeregisterCapsEventHandler;
115 }
116
117 public void RegionLoaded(Scene scene)
118 {
119 if (! m_enabled)
120 return;
121
122 m_scene.EventManager.OnRegisterCaps += RegisterCapsEventHandler;
123 m_scene.EventManager.OnDeregisterCaps += DeregisterCapsEventHandler;
124 }
125
126 public Type ReplaceableInterface
127 {
128 get { return null; }
129 }
130
131#endregion
132
133#region IExternalCapsModule
134 // Eg http://grid.sciencesim.com/GridPublic/%CAP%/%OP%/"
135 public bool RegisterExternalUserCapsHandler(UUID agentID, Caps caps, String capName, String urlSkel)
136 {
137 UUID cap = UUID.Random();
138
139 // Call to simian to register the cap we generated
140 // NameValueCollection requestArgs = new NameValueCollection
141 // {
142 // { "RequestMethod", "AddCapability" },
143 // { "Resource", "user" },
144 // { "Expiration", 0 },
145 // { "OwnerID", agentID.ToString() },
146 // { "CapabilityID", cap.ToString() }
147 // };
148
149 // OSDMap response = SimianGrid.PostToService(m_simianURL, requestArgs);
150
151 Dictionary<String,String> subs = new Dictionary<String,String>();
152 subs["%OP%"] = capName;
153 subs["%USR%"] = agentID.ToString();
154 subs["%CAP%"] = cap.ToString();
155 subs["%SIM%"] = m_scene.RegionInfo.RegionID.ToString();
156
157 caps.RegisterHandler(capName,ExpandSkeletonURL(urlSkel,subs));
158 return true;
159 }
160
161#endregion
162
163#region EventHandlers
164 public void RegisterCapsEventHandler(UUID agentID, Caps caps) { }
165 public void DeregisterCapsEventHandler(UUID agentID, Caps caps) { }
166#endregion
167
168 private String ExpandSkeletonURL(String urlSkel, Dictionary<String,String> subs)
169 {
170 String result = urlSkel;
171
172 foreach (KeyValuePair<String,String> kvp in subs)
173 {
174 result = result.Replace(kvp.Key,kvp.Value);
175 }
176
177 return result;
178 }
179 }
180} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
index 7422d94..9a8164c 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
@@ -153,7 +153,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
153 { "Value", flags.ToString() } 153 { "Value", flags.ToString() }
154 }; 154 };
155 155
156 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 156 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
157 bool success = response["Success"].AsBoolean(); 157 bool success = response["Success"].AsBoolean();
158 158
159 if (!success) 159 if (!success)
@@ -180,7 +180,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
180 { "Key", friend } 180 { "Key", friend }
181 }; 181 };
182 182
183 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 183 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
184 bool success = response["Success"].AsBoolean(); 184 bool success = response["Success"].AsBoolean();
185 185
186 if (!success) 186 if (!success)
@@ -200,7 +200,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
200 { "Type", "Friend" } 200 { "Type", "Friend" }
201 }; 201 };
202 202
203 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 203 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
204 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) 204 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
205 { 205 {
206 return (OSDArray)response["Entries"]; 206 return (OSDArray)response["Entries"];
@@ -221,7 +221,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
221 { "Type", "Friend" } 221 { "Type", "Friend" }
222 }; 222 };
223 223
224 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 224 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
225 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) 225 if (response["Success"].AsBoolean() && response["Entries"] is OSDArray)
226 { 226 {
227 return (OSDArray)response["Entries"]; 227 return (OSDArray)response["Entries"];
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
index 847319c..a35d749 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGrid.cs
@@ -26,8 +26,122 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
30using System.Collections.Specialized;
31using System.Reflection;
32using log4net;
29using Mono.Addins; 33using Mono.Addins;
30using Nini.Config; 34using Nini.Config;
35using OpenSim.Framework;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
31 41
32[assembly: Addin("SimianGrid", "1.0")] 42[assembly: Addin("SimianGrid", OpenSim.VersionInfo.VersionNumber)]
33[assembly: AddinDependency("OpenSim", "0.5")] 43[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
44
45namespace OpenSim.Services.Connectors.SimianGrid
46{
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianExternalCapsModule")]
48 public class SimianGrid : ISharedRegionModule
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private IConfig m_config = null;
53
54 private String m_simianURL;
55
56#region IRegionModule Members
57
58 public string Name
59 {
60 get { return this.GetType().Name; }
61 }
62
63 public void Initialise(IConfigSource config)
64 {
65 try
66 {
67 m_config = config.Configs["SimianGrid"];
68
69 if (m_config != null)
70 {
71 m_simianURL = m_config.GetString("SimianServiceURL");
72 if (String.IsNullOrEmpty(m_simianURL))
73 {
74 // m_log.DebugFormat("[SimianGrid] service URL is not defined");
75 return;
76 }
77
78 InitialiseSimCap();
79 SimulatorCapability = SimulatorCapability.Trim();
80 m_log.InfoFormat("[SimianExternalCaps] using {0} as simulator capability",SimulatorCapability);
81 }
82 }
83 catch (Exception e)
84 {
85 m_log.ErrorFormat("[SimianExternalCaps] initialization error: {0}",e.Message);
86 return;
87 }
88 }
89
90 public void PostInitialise() { }
91 public void Close() { }
92 public void AddRegion(Scene scene) { }
93 public void RemoveRegion(Scene scene) { }
94 public void RegionLoaded(Scene scene) { }
95
96 public Type ReplaceableInterface
97 {
98 get { return null; }
99 }
100
101 ///<summary>
102 /// Try a variety of methods for finding the simian simulator capability; first check the
103 /// configuration itself, then look for a file that contains the cap, then finally look
104 /// for an environment variable that contains it.
105 ///</summary>
106 private void InitialiseSimCap()
107 {
108 if (m_config.Contains("SimulatorCapability"))
109 {
110 SimulatorCapability = m_config.GetString("SimulatorCapability");
111 return;
112 }
113
114 if (m_config.Contains("SimulatorCapabilityFile"))
115 {
116 String filename = m_config.GetString("SimulatorCapabilityFile");
117 if (System.IO.File.Exists(filename))
118 {
119 SimulatorCapability = System.IO.File.ReadAllText(filename);
120 return;
121 }
122 }
123
124 if (m_config.Contains("SimulatorCapabilityVariable"))
125 {
126 String envname = m_config.GetString("SimulatorCapabilityVariable");
127 String envvalue = System.Environment.GetEnvironmentVariable(envname);
128 if (envvalue != null)
129 {
130 SimulatorCapability = envvalue;
131 return;
132 }
133 }
134
135 m_log.WarnFormat("[SimianExternalCaps] no method specified for simulator capability");
136 }
137
138#endregion
139
140 public static String SimulatorCapability = UUID.Zero.ToString();
141 public static OSDMap PostToService(string url, NameValueCollection data)
142 {
143 data["cap"] = SimulatorCapability;
144 return WebUtil.PostToService(url, data);
145 }
146 }
147} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
index 93fdae3..8375c95 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridMaptileModule.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Collections.Specialized;
30using System.Reflection; 31using System.Reflection;
31using System.Net; 32using System.Net;
32using System.IO; 33using System.IO;
@@ -43,7 +44,8 @@ using OpenSim.Region.Framework.Scenes;
43using OpenMetaverse; 44using OpenMetaverse;
44using OpenMetaverse.StructuredData; 45using OpenMetaverse.StructuredData;
45 46
46namespace OpenSim.Region.OptionalModules.Simian 47//namespace OpenSim.Region.OptionalModules.Simian
48namespace OpenSim.Services.Connectors.SimianGrid
47{ 49{
48 /// <summary> 50 /// <summary>
49 /// </summary> 51 /// </summary>
@@ -179,7 +181,6 @@ namespace OpenSim.Region.OptionalModules.Simian
179 m_log.DebugFormat("[SIMIAN MAPTILE]: upload maptile for {0}",scene.RegionInfo.RegionName); 181 m_log.DebugFormat("[SIMIAN MAPTILE]: upload maptile for {0}",scene.RegionInfo.RegionName);
180 182
181 // Create a PNG map tile and upload it to the AddMapTile API 183 // Create a PNG map tile and upload it to the AddMapTile API
182 byte[] pngData = Utils.EmptyBytes;
183 IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>(); 184 IMapImageGenerator tileGenerator = scene.RequestModuleInterface<IMapImageGenerator>();
184 if (tileGenerator == null) 185 if (tileGenerator == null)
185 { 186 {
@@ -187,76 +188,79 @@ namespace OpenSim.Region.OptionalModules.Simian
187 return; 188 return;
188 } 189 }
189 190
190 using (Image mapTile = tileGenerator.CreateMapTile()) 191 using (Bitmap mapTile = tileGenerator.CreateMapTile())
191 {
192 using (MemoryStream stream = new MemoryStream())
193 {
194 mapTile.Save(stream, ImageFormat.Png);
195 pngData = stream.ToArray();
196 }
197 }
198
199 List<MultipartForm.Element> postParameters = new List<MultipartForm.Element>()
200 {
201 new MultipartForm.Parameter("X", scene.RegionInfo.RegionLocX.ToString()),
202 new MultipartForm.Parameter("Y", scene.RegionInfo.RegionLocY.ToString()),
203 new MultipartForm.File("Tile", "tile.png", "image/png", pngData)
204 };
205
206 string errorMessage = null;
207 int tickstart = Util.EnvironmentTickCount();
208
209 // Make the remote storage request
210 try
211 { 192 {
212 HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl); 193 if (mapTile != null)
213 request.Timeout = 20000;
214 request.ReadWriteTimeout = 5000;
215
216 using (HttpWebResponse response = MultipartForm.Post(request, postParameters))
217 { 194 {
218 using (Stream responseStream = response.GetResponseStream()) 195 // If the region/maptile is legacy sized, just upload the one tile like it has always been done
196 if (mapTile.Width == Constants.RegionSize && mapTile.Height == Constants.RegionSize)
219 { 197 {
220 string responseStr = responseStream.GetStreamString(); 198 ConvertAndUploadMaptile(mapTile, scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY);
221 OSD responseOSD = OSDParser.Deserialize(responseStr); 199 }
222 if (responseOSD.Type == OSDType.Map) 200 else
201 {
202 // For larger regions (varregion) we must cut the region image into legacy sized
203 // pieces since that is how the maptile system works.
204 // Note the assumption that varregions are always a multiple of legacy size.
205 for (uint xx = 0; xx < mapTile.Width; xx += Constants.RegionSize)
223 { 206 {
224 OSDMap responseMap = (OSDMap)responseOSD; 207 for (uint yy = 0; yy < mapTile.Height; yy += Constants.RegionSize)
225 if (responseMap["Success"].AsBoolean()) 208 {
226 return; 209 // Images are addressed from the upper left corner so have to do funny
210 // math to pick out the sub-tile since regions are numbered from
211 // the lower left.
212 Rectangle rect = new Rectangle(
213 (int)xx,
214 mapTile.Height - (int)yy - (int)Constants.RegionSize,
215 (int)Constants.RegionSize, (int)Constants.RegionSize);
227 216
228 errorMessage = "Upload failed: " + responseMap["Message"].AsString(); 217 using (Bitmap subMapTile = mapTile.Clone(rect, mapTile.PixelFormat))
229 } 218 {
230 else 219 uint locX = scene.RegionInfo.RegionLocX + (xx / Constants.RegionSize);
231 { 220 uint locY = scene.RegionInfo.RegionLocY + (yy / Constants.RegionSize);
232 errorMessage = "Response format was invalid:\n" + responseStr; 221
222 ConvertAndUploadMaptile(subMapTile, locX, locY);
223 }
224 }
233 } 225 }
234 } 226 }
235 } 227 }
236 } 228 else
237 catch (WebException we)
238 {
239 errorMessage = we.Message;
240 if (we.Status == WebExceptionStatus.ProtocolError)
241 { 229 {
242 HttpWebResponse webResponse = (HttpWebResponse)we.Response; 230 m_log.WarnFormat("[SIMIAN MAPTILE] Tile image generation failed");
243 errorMessage = String.Format("[{0}] {1}",
244 webResponse.StatusCode,webResponse.StatusDescription);
245 } 231 }
246 } 232 }
247 catch (Exception ex) 233
234 }
235
236 ///<summary>
237 ///
238 ///</summary>
239 private void ConvertAndUploadMaptile(Image mapTile, uint locX, uint locY)
240 {
241 //m_log.DebugFormat("[SIMIAN MAPTILE]: upload maptile for location {0}, {1}", locX, locY);
242
243 byte[] pngData = Utils.EmptyBytes;
244 using (MemoryStream stream = new MemoryStream())
248 { 245 {
249 errorMessage = ex.Message; 246 mapTile.Save(stream, ImageFormat.Png);
247 pngData = stream.ToArray();
250 } 248 }
251 finally 249
250 NameValueCollection requestArgs = new NameValueCollection
251 {
252 { "RequestMethod", "xAddMapTile" },
253 { "X", locX.ToString() },
254 { "Y", locY.ToString() },
255 { "ContentType", "image/png" },
256 { "EncodedData", System.Convert.ToBase64String(pngData) }
257 };
258
259 OSDMap response = SimianGrid.PostToService(m_serverUrl,requestArgs);
260 if (! response["Success"].AsBoolean())
252 { 261 {
253 // This just dumps a warning for any operation that takes more than 100 ms 262 m_log.WarnFormat("[SIMIAN MAPTILE] failed to store map tile; {0}",response["Message"].AsString());
254 int tickdiff = Util.EnvironmentTickCountSubtract(tickstart);
255 m_log.DebugFormat("[SIMIAN MAPTILE]: map tile uploaded in {0}ms",tickdiff);
256 } 263 }
257
258 m_log.WarnFormat("[SIMIAN MAPTILE]: Failed to store {0} byte tile for {1}: {2}",
259 pngData.Length, scene.RegionInfo.RegionName, errorMessage);
260 } 264 }
261 } 265 }
262} \ No newline at end of file 266} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
index 038a4bf..b031f21 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
@@ -101,7 +101,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
101 public string RegisterRegion(UUID scopeID, GridRegion regionInfo) 101 public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
102 { 102 {
103 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0); 103 Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0);
104 Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, Constants.RegionHeight); 104 Vector3d maxPosition = minPosition + new Vector3d(regionInfo.RegionSizeX, regionInfo.RegionSizeY, Constants.RegionHeight);
105 105
106 OSDMap extraData = new OSDMap 106 OSDMap extraData = new OSDMap
107 { 107 {
@@ -129,7 +129,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
129 { "ExtraData", OSDParser.SerializeJsonString(extraData) } 129 { "ExtraData", OSDParser.SerializeJsonString(extraData) }
130 }; 130 };
131 131
132 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 132 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
133 if (response["Success"].AsBoolean()) 133 if (response["Success"].AsBoolean())
134 return String.Empty; 134 return String.Empty;
135 else 135 else
@@ -145,7 +145,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
145 { "Enabled", "0" } 145 { "Enabled", "0" }
146 }; 146 };
147 147
148 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 148 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
149 bool success = response["Success"].AsBoolean(); 149 bool success = response["Success"].AsBoolean();
150 150
151 if (!success) 151 if (!success)
@@ -156,15 +156,15 @@ namespace OpenSim.Services.Connectors.SimianGrid
156 156
157 public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID) 157 public List<GridRegion> GetNeighbours(UUID scopeID, UUID regionID)
158 { 158 {
159 const int NEIGHBOR_RADIUS = 128;
160
161 GridRegion region = GetRegionByUUID(scopeID, regionID); 159 GridRegion region = GetRegionByUUID(scopeID, regionID);
162 160
161 int NEIGHBOR_RADIUS = Math.Max(region.RegionSizeX, region.RegionSizeY) / 2;
162
163 if (region != null) 163 if (region != null)
164 { 164 {
165 List<GridRegion> regions = GetRegionRange(scopeID, 165 List<GridRegion> regions = GetRegionRange(scopeID,
166 region.RegionLocX - NEIGHBOR_RADIUS, region.RegionLocX + (int)Constants.RegionSize + NEIGHBOR_RADIUS, 166 region.RegionLocX - NEIGHBOR_RADIUS, region.RegionLocX + region.RegionSizeX + NEIGHBOR_RADIUS,
167 region.RegionLocY - NEIGHBOR_RADIUS, region.RegionLocY + (int)Constants.RegionSize + NEIGHBOR_RADIUS); 167 region.RegionLocY - NEIGHBOR_RADIUS, region.RegionLocY + region.RegionSizeY + NEIGHBOR_RADIUS);
168 168
169 for (int i = 0; i < regions.Count; i++) 169 for (int i = 0; i < regions.Count; i++)
170 { 170 {
@@ -192,7 +192,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
192 192
193 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request region with uuid {0}",regionID.ToString()); 193 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request region with uuid {0}",regionID.ToString());
194 194
195 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 195 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
196 if (response["Success"].AsBoolean()) 196 if (response["Success"].AsBoolean())
197 { 197 {
198 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] uuid request successful {0}",response["Name"].AsString()); 198 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] uuid request successful {0}",response["Name"].AsString());
@@ -220,7 +220,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
220 220
221 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request grid at {0}",position.ToString()); 221 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request grid at {0}",position.ToString());
222 222
223 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 223 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
224 if (response["Success"].AsBoolean()) 224 if (response["Success"].AsBoolean())
225 { 225 {
226 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] position request successful {0}",response["Name"].AsString()); 226 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] position request successful {0}",response["Name"].AsString());
@@ -229,7 +229,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
229 else 229 else
230 { 230 {
231 // m_log.InfoFormat("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region at {0},{1}", 231 // m_log.InfoFormat("[SIMIAN GRID CONNECTOR]: Grid service did not find a match for region at {0},{1}",
232 // x / Constants.RegionSize, y / Constants.RegionSize); 232 // Util.WorldToRegionLoc(x), Util.WorldToRegionLoc(y));
233 return null; 233 return null;
234 } 234 }
235 } 235 }
@@ -261,7 +261,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
261 261
262 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request regions with name {0}",name); 262 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request regions with name {0}",name);
263 263
264 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 264 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
265 if (response["Success"].AsBoolean()) 265 if (response["Success"].AsBoolean())
266 { 266 {
267 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] found regions with name {0}",name); 267 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] found regions with name {0}",name);
@@ -299,7 +299,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
299 //m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request regions by range {0} to {1}",minPosition.ToString(),maxPosition.ToString()); 299 //m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request regions by range {0} to {1}",minPosition.ToString(),maxPosition.ToString());
300 300
301 301
302 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 302 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
303 if (response["Success"].AsBoolean()) 303 if (response["Success"].AsBoolean())
304 { 304 {
305 OSDArray array = response["Scenes"] as OSDArray; 305 OSDArray array = response["Scenes"] as OSDArray;
@@ -330,6 +330,12 @@ namespace OpenSim.Services.Connectors.SimianGrid
330 return new List<GridRegion>(0); 330 return new List<GridRegion>(0);
331 } 331 }
332 332
333 public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
334 {
335 // TODO: Allow specifying the default grid location
336 return GetDefaultRegions(scopeID);
337 }
338
333 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) 339 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
334 { 340 {
335 GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true); 341 GridRegion defRegion = GetNearestRegion(new Vector3d(x, y, 0.0), true);
@@ -350,7 +356,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
350 { "Enabled", "1" } 356 { "Enabled", "1" }
351 }; 357 };
352 358
353 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 359 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
354 if (response["Success"].AsBoolean()) 360 if (response["Success"].AsBoolean())
355 { 361 {
356 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] found regions with name {0}",name); 362 // m_log.DebugFormat("[SIMIAN GRID CONNECTOR] found regions with name {0}",name);
@@ -380,7 +386,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
380 386
381 m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request region flags for {0}",regionID.ToString()); 387 m_log.DebugFormat("[SIMIAN GRID CONNECTOR] request region flags for {0}",regionID.ToString());
382 388
383 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 389 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
384 if (response["Success"].AsBoolean()) 390 if (response["Success"].AsBoolean())
385 { 391 {
386 OSDMap extraData = response["ExtraData"] as OSDMap; 392 OSDMap extraData = response["ExtraData"] as OSDMap;
@@ -396,6 +402,13 @@ namespace OpenSim.Services.Connectors.SimianGrid
396 return -1; 402 return -1;
397 } 403 }
398 } 404 }
405
406 public Dictionary<string, object> GetExtraFeatures()
407 {
408 /// See SimulatorFeaturesModule - Need to get map, search and destination guide
409 Dictionary<string, object> extraFeatures = new Dictionary<string, object>();
410 return extraFeatures;
411 }
399 412
400 #endregion IGridService 413 #endregion IGridService
401 414
@@ -410,7 +423,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
410 if (onlyEnabled) 423 if (onlyEnabled)
411 requestArgs["Enabled"] = "1"; 424 requestArgs["Enabled"] = "1";
412 425
413 OSDMap response = WebUtil.PostToService(m_ServerURI, requestArgs); 426 OSDMap response = SimianGrid.PostToService(m_ServerURI, requestArgs);
414 if (response["Success"].AsBoolean()) 427 if (response["Success"].AsBoolean())
415 { 428 {
416 return ResponseToGridRegion(response); 429 return ResponseToGridRegion(response);
@@ -437,9 +450,13 @@ namespace OpenSim.Services.Connectors.SimianGrid
437 region.RegionName = response["Name"].AsString(); 450 region.RegionName = response["Name"].AsString();
438 451
439 Vector3d minPosition = response["MinPosition"].AsVector3d(); 452 Vector3d minPosition = response["MinPosition"].AsVector3d();
453 Vector3d maxPosition = response["MaxPosition"].AsVector3d();
440 region.RegionLocX = (int)minPosition.X; 454 region.RegionLocX = (int)minPosition.X;
441 region.RegionLocY = (int)minPosition.Y; 455 region.RegionLocY = (int)minPosition.Y;
442 456
457 region.RegionSizeX = (int)maxPosition.X - (int)minPosition.X;
458 region.RegionSizeY = (int)maxPosition.Y - (int)minPosition.Y;
459
443 if ( ! extraData["HyperGrid"] ) { 460 if ( ! extraData["HyperGrid"] ) {
444 Uri httpAddress = response["Address"].AsUri(); 461 Uri httpAddress = response["Address"].AsUri();
445 region.ExternalHostName = httpAddress.Host; 462 region.ExternalHostName = httpAddress.Host;
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
index a391275..e793420 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs
@@ -38,12 +38,14 @@ using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using PermissionMask = OpenSim.Framework.PermissionMask;
41 42
42namespace OpenSim.Services.Connectors.SimianGrid 43namespace OpenSim.Services.Connectors.SimianGrid
43{ 44{
44 /// <summary> 45 /// <summary>
45 /// Permissions bitflags 46 /// Permissions bitflags
46 /// </summary> 47 /// </summary>
48 /*
47 [Flags] 49 [Flags]
48 public enum PermissionMask : uint 50 public enum PermissionMask : uint
49 { 51 {
@@ -55,6 +57,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
55 Damage = 1 << 20, 57 Damage = 1 << 20,
56 All = 0x7FFFFFFF 58 All = 0x7FFFFFFF
57 } 59 }
60 */
58 61
59 /// <summary> 62 /// <summary>
60 /// Connects avatar inventories to the SimianGrid backend 63 /// Connects avatar inventories to the SimianGrid backend
@@ -71,6 +74,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
71// private object m_gestureSyncRoot = new object(); 74// private object m_gestureSyncRoot = new object();
72 private bool m_Enabled = false; 75 private bool m_Enabled = false;
73 76
77 private const double CACHE_EXPIRATION_SECONDS = 20.0;
78 private static ExpiringCache<UUID, InventoryItemBase> m_ItemCache;
79
74 #region ISharedRegionModule 80 #region ISharedRegionModule
75 81
76 public Type ReplaceableInterface { get { return null; } } 82 public Type ReplaceableInterface { get { return null; } }
@@ -96,6 +102,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
96 url = url + '/'; 102 url = url + '/';
97 m_serverUrl = url; 103 m_serverUrl = url;
98 104
105 if (m_ItemCache == null)
106 m_ItemCache = new ExpiringCache<UUID, InventoryItemBase>();
107
99 } 108 }
100 109
101 public void Initialise(IConfigSource source) 110 public void Initialise(IConfigSource source)
@@ -129,6 +138,8 @@ namespace OpenSim.Services.Connectors.SimianGrid
129 { 138 {
130 m_userServerUrl = serviceUrl; 139 m_userServerUrl = serviceUrl;
131 m_Enabled = true; 140 m_Enabled = true;
141 if (m_ItemCache == null)
142 m_ItemCache = new ExpiringCache<UUID, InventoryItemBase>();
132 } 143 }
133 } 144 }
134 } 145 }
@@ -153,7 +164,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
153 { "OwnerID", userID.ToString() } 164 { "OwnerID", userID.ToString() }
154 }; 165 };
155 166
156 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 167 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
157 bool success = response["Success"].AsBoolean(); 168 bool success = response["Success"].AsBoolean();
158 169
159 if (!success) 170 if (!success)
@@ -179,7 +190,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
179 { "ChildrenOnly", "0" } 190 { "ChildrenOnly", "0" }
180 }; 191 };
181 192
182 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 193 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
183 if (response["Success"].AsBoolean() && response["Items"] is OSDArray) 194 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
184 { 195 {
185 OSDArray items = (OSDArray)response["Items"]; 196 OSDArray items = (OSDArray)response["Items"];
@@ -194,37 +205,6 @@ namespace OpenSim.Services.Connectors.SimianGrid
194 } 205 }
195 206
196 /// <summary> 207 /// <summary>
197 /// Synchronous inventory fetch.
198 /// </summary>
199 /// <param name="userID"></param>
200 /// <returns></returns>
201 [Obsolete]
202 public InventoryCollection GetUserInventory(UUID userID)
203 {
204 m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID);
205
206 InventoryCollection inventory = new InventoryCollection();
207 inventory.UserID = userID;
208 inventory.Folders = new List<InventoryFolderBase>();
209 inventory.Items = new List<InventoryItemBase>();
210
211 return inventory;
212 }
213
214 /// <summary>
215 /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the
216 /// inventory has been received
217 /// </summary>
218 /// <param name="userID"></param>
219 /// <param name="callback"></param>
220 [Obsolete]
221 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
222 {
223 m_log.Error("[SIMIAN INVENTORY CONNECTOR]: Obsolete GetUserInventory called for " + userID);
224 callback(new List<InventoryFolderImpl>(0), new List<InventoryItemBase>(0));
225 }
226
227 /// <summary>
228 /// Retrieve the root inventory folder for the given user. 208 /// Retrieve the root inventory folder for the given user.
229 /// </summary> 209 /// </summary>
230 /// <param name="userID"></param> 210 /// <param name="userID"></param>
@@ -241,7 +221,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
241 { "ChildrenOnly", "1" } 221 { "ChildrenOnly", "1" }
242 }; 222 };
243 223
244 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 224 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
245 if (response["Success"].AsBoolean() && response["Items"] is OSDArray) 225 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
246 { 226 {
247 OSDArray items = (OSDArray)response["Items"]; 227 OSDArray items = (OSDArray)response["Items"];
@@ -260,7 +240,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
260 /// <param name="userID"></param> 240 /// <param name="userID"></param>
261 /// <param name="type"></param> 241 /// <param name="type"></param>
262 /// <returns></returns> 242 /// <returns></returns>
263 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) 243 public InventoryFolderBase GetFolderForType(UUID userID, FolderType type)
264 { 244 {
265 string contentType = SLUtil.SLAssetTypeToContentType((int)type); 245 string contentType = SLUtil.SLAssetTypeToContentType((int)type);
266 246
@@ -271,7 +251,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
271 { "OwnerID", userID.ToString() } 251 { "OwnerID", userID.ToString() }
272 }; 252 };
273 253
274 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 254 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
275 if (response["Success"].AsBoolean() && response["Folder"] is OSDMap) 255 if (response["Success"].AsBoolean() && response["Folder"] is OSDMap)
276 { 256 {
277 OSDMap folder = (OSDMap)response["Folder"]; 257 OSDMap folder = (OSDMap)response["Folder"];
@@ -299,6 +279,10 @@ namespace OpenSim.Services.Connectors.SimianGrid
299 /// <returns></returns> 279 /// <returns></returns>
300 public InventoryItemBase GetItem(InventoryItemBase item) 280 public InventoryItemBase GetItem(InventoryItemBase item)
301 { 281 {
282 InventoryItemBase retrieved = null;
283 if (m_ItemCache.TryGetValue(item.ID, out retrieved))
284 return retrieved;
285
302 NameValueCollection requestArgs = new NameValueCollection 286 NameValueCollection requestArgs = new NameValueCollection
303 { 287 {
304 { "RequestMethod", "GetInventoryNode" }, 288 { "RequestMethod", "GetInventoryNode" },
@@ -309,7 +293,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
309 { "ChildrenOnly", "1" } 293 { "ChildrenOnly", "1" }
310 }; 294 };
311 295
312 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 296 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
313 if (response["Success"].AsBoolean() && response["Items"] is OSDArray) 297 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
314 { 298 {
315 List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]); 299 List<InventoryItemBase> items = GetItemsFromResponse((OSDArray)response["Items"]);
@@ -320,7 +304,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
320 for (int i = 0; i < items.Count; i++) 304 for (int i = 0; i < items.Count; i++)
321 { 305 {
322 if (items[i].ID == item.ID) 306 if (items[i].ID == item.ID)
323 return items[i]; 307 {
308 retrieved = items[i];
309 m_ItemCache.AddOrUpdate(item.ID, retrieved, CACHE_EXPIRATION_SECONDS);
310 return retrieved;
311 }
324 } 312 }
325 } 313 }
326 } 314 }
@@ -329,6 +317,21 @@ namespace OpenSim.Services.Connectors.SimianGrid
329 return null; 317 return null;
330 } 318 }
331 319
320 public InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs)
321 {
322 InventoryItemBase[] result = new InventoryItemBase[itemIDs.Length];
323 int i = 0;
324 InventoryItemBase item = new InventoryItemBase();
325 item.Owner = principalID;
326 foreach (UUID id in itemIDs)
327 {
328 item.ID = id;
329 result[i++] = GetItem(item);
330 }
331
332 return result;
333 }
334
332 /// <summary> 335 /// <summary>
333 /// Get a folder, given by its UUID 336 /// Get a folder, given by its UUID
334 /// </summary> 337 /// </summary>
@@ -346,7 +349,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
346 { "ChildrenOnly", "1" } 349 { "ChildrenOnly", "1" }
347 }; 350 };
348 351
349 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 352 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
350 if (response["Success"].AsBoolean() && response["Items"] is OSDArray) 353 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
351 { 354 {
352 OSDArray items = (OSDArray)response["Items"]; 355 OSDArray items = (OSDArray)response["Items"];
@@ -368,7 +371,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
368 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 371 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
369 { 372 {
370 InventoryCollection inventory = new InventoryCollection(); 373 InventoryCollection inventory = new InventoryCollection();
371 inventory.UserID = userID; 374 inventory.OwnerID = userID;
372 375
373 NameValueCollection requestArgs = new NameValueCollection 376 NameValueCollection requestArgs = new NameValueCollection
374 { 377 {
@@ -380,7 +383,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
380 { "ChildrenOnly", "1" } 383 { "ChildrenOnly", "1" }
381 }; 384 };
382 385
383 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 386 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
384 if (response["Success"].AsBoolean() && response["Items"] is OSDArray) 387 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
385 { 388 {
386 OSDArray items = (OSDArray)response["Items"]; 389 OSDArray items = (OSDArray)response["Items"];
@@ -399,6 +402,18 @@ namespace OpenSim.Services.Connectors.SimianGrid
399 return inventory; 402 return inventory;
400 } 403 }
401 404
405 public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
406 {
407 InventoryCollection[] invColl = new InventoryCollection[folderIDs.Length];
408 int i = 0;
409 foreach (UUID fid in folderIDs)
410 {
411 invColl[i++] = GetFolderContent(principalID, fid);
412 }
413
414 return invColl;
415 }
416
402 /// <summary> 417 /// <summary>
403 /// Gets the items inside a folder 418 /// Gets the items inside a folder
404 /// </summary> 419 /// </summary>
@@ -408,7 +423,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
408 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) 423 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
409 { 424 {
410 InventoryCollection inventory = new InventoryCollection(); 425 InventoryCollection inventory = new InventoryCollection();
411 inventory.UserID = userID; 426 inventory.OwnerID = userID;
412 427
413 NameValueCollection requestArgs = new NameValueCollection 428 NameValueCollection requestArgs = new NameValueCollection
414 { 429 {
@@ -420,7 +435,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
420 { "ChildrenOnly", "1" } 435 { "ChildrenOnly", "1" }
421 }; 436 };
422 437
423 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 438 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
424 if (response["Success"].AsBoolean() && response["Items"] is OSDArray) 439 if (response["Success"].AsBoolean() && response["Items"] is OSDArray)
425 { 440 {
426 OSDArray items = (OSDArray)response["Items"]; 441 OSDArray items = (OSDArray)response["Items"];
@@ -451,7 +466,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
451 { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) } 466 { "ContentType", SLUtil.SLAssetTypeToContentType(folder.Type) }
452 }; 467 };
453 468
454 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 469 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
455 bool success = response["Success"].AsBoolean(); 470 bool success = response["Success"].AsBoolean();
456 471
457 if (!success) 472 if (!success)
@@ -515,7 +530,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
515 { "ItemID", itemID.ToString() } 530 { "ItemID", itemID.ToString() }
516 }; 531 };
517 532
518 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 533 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
519 bool success = response["Success"].AsBoolean(); 534 bool success = response["Success"].AsBoolean();
520 535
521 if (!success) 536 if (!success)
@@ -543,7 +558,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
543 { "FolderID", folder.ID.ToString() } 558 { "FolderID", folder.ID.ToString() }
544 }; 559 };
545 560
546 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 561 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
547 bool success = response["Success"].AsBoolean(); 562 bool success = response["Success"].AsBoolean();
548 563
549 if (!success) 564 if (!success)
@@ -565,7 +580,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
565 // A folder of UUID.Zero means we need to find the most appropriate home for this item 580 // A folder of UUID.Zero means we need to find the most appropriate home for this item
566 if (item.Folder == UUID.Zero) 581 if (item.Folder == UUID.Zero)
567 { 582 {
568 InventoryFolderBase folder = GetFolderForType(item.Owner, (AssetType)item.AssetType); 583 InventoryFolderBase folder = null;
584 if (Enum.IsDefined(typeof(FolderType), (sbyte)item.AssetType))
585 folder = GetFolderForType(item.Owner, (FolderType)item.AssetType);
569 if (folder != null && folder.ID != UUID.Zero) 586 if (folder != null && folder.ID != UUID.Zero)
570 item.Folder = folder.ID; 587 item.Folder = folder.ID;
571 else 588 else
@@ -620,7 +637,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
620 { "ExtraData", OSDParser.SerializeJsonString(extraData) } 637 { "ExtraData", OSDParser.SerializeJsonString(extraData) }
621 }; 638 };
622 639
623 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 640 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
624 bool success = response["Success"].AsBoolean(); 641 bool success = response["Success"].AsBoolean();
625 642
626 if (!success) 643 if (!success)
@@ -844,7 +861,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
844 { "Items", String.Join(",", itemIDs) } 861 { "Items", String.Join(",", itemIDs) }
845 }; 862 };
846 863
847 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 864 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
848 bool success = response["Success"].AsBoolean(); 865 bool success = response["Success"].AsBoolean();
849 866
850 if (!success) 867 if (!success)
@@ -882,7 +899,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
882 { "UserID", userID.ToString() } 899 { "UserID", userID.ToString() }
883 }; 900 };
884 901
885 OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs); 902 OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs);
886 if (response["Success"].AsBoolean()) 903 if (response["Success"].AsBoolean())
887 { 904 {
888 OSDMap user = response["User"] as OSDMap; 905 OSDMap user = response["User"] as OSDMap;
@@ -913,7 +930,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
913 { "Gestures", OSDParser.SerializeJsonString(gestures) } 930 { "Gestures", OSDParser.SerializeJsonString(gestures) }
914 }; 931 };
915 932
916 OSDMap response = WebUtil.PostToService(m_userServerUrl, requestArgs); 933 OSDMap response = SimianGrid.PostToService(m_userServerUrl, requestArgs);
917 if (!response["Success"].AsBoolean()) 934 if (!response["Success"].AsBoolean())
918 { 935 {
919 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " + 936 m_log.Warn("[SIMIAN INVENTORY CONNECTOR]: Failed to save active gestures for " + userID + ": " +
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
index 854bea4..211b775 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs
@@ -65,7 +65,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
65 public void PostInitialise() { } 65 public void PostInitialise() { }
66 public void Close() { } 66 public void Close() { }
67 67
68 public SimianPresenceServiceConnector() { m_activityDetector = new SimianActivityDetector(this); } 68 public SimianPresenceServiceConnector() { }
69 public string Name { get { return "SimianPresenceServiceConnector"; } } 69 public string Name { get { return "SimianPresenceServiceConnector"; } }
70 public void AddRegion(Scene scene) 70 public void AddRegion(Scene scene)
71 { 71 {
@@ -121,6 +121,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
121 if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) 121 if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("="))
122 serviceUrl = serviceUrl + '/'; 122 serviceUrl = serviceUrl + '/';
123 m_serverUrl = serviceUrl; 123 m_serverUrl = serviceUrl;
124 m_activityDetector = new SimianActivityDetector(this);
124 m_Enabled = true; 125 m_Enabled = true;
125 } 126 }
126 } 127 }
@@ -137,17 +138,18 @@ namespace OpenSim.Services.Connectors.SimianGrid
137 userID, sessionID, secureSessionID); 138 userID, sessionID, secureSessionID);
138 139
139 NameValueCollection requestArgs = new NameValueCollection 140 NameValueCollection requestArgs = new NameValueCollection
140 { 141 {
141 { "RequestMethod", "AddSession" }, 142 { "RequestMethod", "AddSession" },
142 { "UserID", userID.ToString() } 143 { "UserID", userID.ToString() }
143 }; 144 };
145
144 if (sessionID != UUID.Zero) 146 if (sessionID != UUID.Zero)
145 { 147 {
146 requestArgs["SessionID"] = sessionID.ToString(); 148 requestArgs["SessionID"] = sessionID.ToString();
147 requestArgs["SecureSessionID"] = secureSessionID.ToString(); 149 requestArgs["SecureSessionID"] = secureSessionID.ToString();
148 } 150 }
149 151
150 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 152 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
151 bool success = response["Success"].AsBoolean(); 153 bool success = response["Success"].AsBoolean();
152 154
153 if (!success) 155 if (!success)
@@ -158,15 +160,15 @@ namespace OpenSim.Services.Connectors.SimianGrid
158 160
159 public bool LogoutAgent(UUID sessionID) 161 public bool LogoutAgent(UUID sessionID)
160 { 162 {
161// m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID); 163 // m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID);
162 164
163 NameValueCollection requestArgs = new NameValueCollection 165 NameValueCollection requestArgs = new NameValueCollection
164 { 166 {
165 { "RequestMethod", "RemoveSession" }, 167 { "RequestMethod", "RemoveSession" },
166 { "SessionID", sessionID.ToString() } 168 { "SessionID", sessionID.ToString() }
167 }; 169 };
168 170
169 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 171 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
170 bool success = response["Success"].AsBoolean(); 172 bool success = response["Success"].AsBoolean();
171 173
172 if (!success) 174 if (!success)
@@ -177,15 +179,15 @@ namespace OpenSim.Services.Connectors.SimianGrid
177 179
178 public bool LogoutRegionAgents(UUID regionID) 180 public bool LogoutRegionAgents(UUID regionID)
179 { 181 {
180// m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID); 182 // m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID);
181 183
182 NameValueCollection requestArgs = new NameValueCollection 184 NameValueCollection requestArgs = new NameValueCollection
183 { 185 {
184 { "RequestMethod", "RemoveSessions" }, 186 { "RequestMethod", "RemoveSessions" },
185 { "SceneID", regionID.ToString() } 187 { "SceneID", regionID.ToString() }
186 }; 188 };
187 189
188 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 190 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
189 bool success = response["Success"].AsBoolean(); 191 bool success = response["Success"].AsBoolean();
190 192
191 if (!success) 193 if (!success)
@@ -202,49 +204,46 @@ namespace OpenSim.Services.Connectors.SimianGrid
202 204
203 public PresenceInfo GetAgent(UUID sessionID) 205 public PresenceInfo GetAgent(UUID sessionID)
204 { 206 {
205// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent with sessionID " + sessionID); 207 OSDMap sessionResponse = GetSessionDataFromSessionID(sessionID);
206 208 if (sessionResponse == null)
207 NameValueCollection requestArgs = new NameValueCollection
208 {
209 { "RequestMethod", "GetSession" },
210 { "SessionID", sessionID.ToString() }
211 };
212
213 OSDMap sessionResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
214 if (sessionResponse["Success"].AsBoolean())
215 { 209 {
216 UUID userID = sessionResponse["UserID"].AsUUID(); 210 m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session {0}: {1}",sessionID.ToString(),sessionResponse["Message"].AsString());
217 m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID); 211 return null;
218
219 requestArgs = new NameValueCollection
220 {
221 { "RequestMethod", "GetUser" },
222 { "UserID", userID.ToString() }
223 };
224
225 OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
226 if (userResponse["Success"].AsBoolean())
227 return ResponseToPresenceInfo(sessionResponse, userResponse);
228 else
229 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
230 } 212 }
231 else 213
214 UUID userID = sessionResponse["UserID"].AsUUID();
215 OSDMap userResponse = GetUserData(userID);
216 if (userResponse == null)
232 { 217 {
233 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session " + sessionID + ": " + sessionResponse["Message"].AsString()); 218 m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}: {1}",userID.ToString(),userResponse["Message"].AsString());
219 return null;
234 } 220 }
235 221
236 return null; 222 return ResponseToPresenceInfo(sessionResponse);
237 } 223 }
238 224
239 public PresenceInfo[] GetAgents(string[] userIDs) 225 public PresenceInfo[] GetAgents(string[] userIDs)
240 { 226 {
241 List<PresenceInfo> presences = new List<PresenceInfo>(userIDs.Length); 227 List<PresenceInfo> presences = new List<PresenceInfo>();
228
229 NameValueCollection requestArgs = new NameValueCollection
230 {
231 { "RequestMethod", "GetSessions" },
232 { "UserIDList", String.Join(",",userIDs) }
233 };
242 234
243 for (int i = 0; i < userIDs.Length; i++) 235 OSDMap sessionListResponse = SimianGrid.PostToService(m_serverUrl, requestArgs);
236 if (! sessionListResponse["Success"].AsBoolean())
244 { 237 {
245 UUID userID; 238 m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve sessions: {0}",sessionListResponse["Message"].AsString());
246 if (UUID.TryParse(userIDs[i], out userID) && userID != UUID.Zero) 239 return null;
247 presences.AddRange(GetSessions(userID)); 240 }
241
242 OSDArray sessionList = sessionListResponse["Sessions"] as OSDArray;
243 for (int i = 0; i < sessionList.Count; i++)
244 {
245 OSDMap sessionInfo = sessionList[i] as OSDMap;
246 presences.Add(ResponseToPresenceInfo(sessionInfo));
248 } 247 }
249 248
250 return presences.ToArray(); 249 return presences.ToArray();
@@ -262,7 +261,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
262 261
263 public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) 262 public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
264 { 263 {
265// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Logging out user " + userID); 264 // m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Logging out user " + userID);
266 265
267 // Remove the session to mark this user offline 266 // Remove the session to mark this user offline
268 if (!LogoutAgent(sessionID)) 267 if (!LogoutAgent(sessionID))
@@ -270,13 +269,13 @@ namespace OpenSim.Services.Connectors.SimianGrid
270 269
271 // Save our last position as user data 270 // Save our last position as user data
272 NameValueCollection requestArgs = new NameValueCollection 271 NameValueCollection requestArgs = new NameValueCollection
273 { 272 {
274 { "RequestMethod", "AddUserData" }, 273 { "RequestMethod", "AddUserData" },
275 { "UserID", userID.ToString() }, 274 { "UserID", userID.ToString() },
276 { "LastLocation", SerializeLocation(regionID, lastPosition, lastLookAt) } 275 { "LastLocation", SerializeLocation(regionID, lastPosition, lastLookAt) }
277 }; 276 };
278 277
279 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 278 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
280 bool success = response["Success"].AsBoolean(); 279 bool success = response["Success"].AsBoolean();
281 280
282 if (!success) 281 if (!success)
@@ -287,16 +286,16 @@ namespace OpenSim.Services.Connectors.SimianGrid
287 286
288 public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt) 287 public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
289 { 288 {
290// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Setting home location for user " + userID); 289 // m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Setting home location for user " + userID);
291 290
292 NameValueCollection requestArgs = new NameValueCollection 291 NameValueCollection requestArgs = new NameValueCollection
293 { 292 {
294 { "RequestMethod", "AddUserData" }, 293 { "RequestMethod", "AddUserData" },
295 { "UserID", userID.ToString() }, 294 { "UserID", userID.ToString() },
296 { "HomeLocation", SerializeLocation(regionID, position, lookAt) } 295 { "HomeLocation", SerializeLocation(regionID, position, lookAt) }
297 }; 296 };
298 297
299 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 298 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
300 bool success = response["Success"].AsBoolean(); 299 bool success = response["Success"].AsBoolean();
301 300
302 if (!success) 301 if (!success)
@@ -312,24 +311,19 @@ namespace OpenSim.Services.Connectors.SimianGrid
312 311
313 public GridUserInfo GetGridUserInfo(string user) 312 public GridUserInfo GetGridUserInfo(string user)
314 { 313 {
315// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent " + user); 314 // m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent " + user);
316 315
317 UUID userID = new UUID(user); 316 UUID userID = new UUID(user);
318// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID); 317 OSDMap userResponse = GetUserData(userID);
319 318
320 NameValueCollection requestArgs = new NameValueCollection 319 if (userResponse == null)
321 { 320 {
322 { "RequestMethod", "GetUser" }, 321 m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}", userID);
323 { "UserID", userID.ToString() } 322 }
324 };
325 323
326 OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs); 324 // Note that ResponseToGridUserInfo properly checks for and returns a null if passed a null.
327 if (userResponse["Success"].AsBoolean()) 325 return ResponseToGridUserInfo(userResponse);
328 return ResponseToGridUserInfo(userResponse);
329 else
330 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
331 326
332 return null;
333 } 327 }
334 328
335 #endregion 329 #endregion
@@ -338,67 +332,51 @@ namespace OpenSim.Services.Connectors.SimianGrid
338 332
339 private OSDMap GetUserData(UUID userID) 333 private OSDMap GetUserData(UUID userID)
340 { 334 {
341// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID); 335 // m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
342 336
343 NameValueCollection requestArgs = new NameValueCollection 337 NameValueCollection requestArgs = new NameValueCollection
344 { 338 {
345 { "RequestMethod", "GetUser" }, 339 { "RequestMethod", "GetUser" },
346 { "UserID", userID.ToString() } 340 { "UserID", userID.ToString() }
347 }; 341 };
348 342
349 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 343 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
350 if (response["Success"].AsBoolean() && response["User"] is OSDMap) 344 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
351 return response; 345 return response;
352 else
353 m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + response["Message"].AsString());
354 346
347 m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}; {1}",userID.ToString(),response["Message"].AsString());
355 return null; 348 return null;
356 } 349 }
357 350
358 private List<PresenceInfo> GetSessions(UUID userID) 351 private OSDMap GetSessionDataFromSessionID(UUID sessionID)
359 { 352 {
360 List<PresenceInfo> presences = new List<PresenceInfo>(1); 353 NameValueCollection requestArgs = new NameValueCollection
361
362 OSDMap userResponse = GetUserData(userID);
363 if (userResponse != null)
364 {
365// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting sessions for " + userID);
366
367 NameValueCollection requestArgs = new NameValueCollection
368 { 354 {
369 { "RequestMethod", "GetSession" }, 355 { "RequestMethod", "GetSession" },
370 { "UserID", userID.ToString() } 356 { "SessionID", sessionID.ToString() }
371 }; 357 };
372 358
373 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 359 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
374 if (response["Success"].AsBoolean()) 360 if (response["Success"].AsBoolean())
375 { 361 return response;
376 PresenceInfo presence = ResponseToPresenceInfo(response, userResponse);
377 if (presence != null)
378 presences.Add(presence);
379 }
380// else
381// {
382// m_log.Debug("[SIMIAN PRESENCE CONNECTOR]: No session returned for " + userID + ": " + response["Message"].AsString());
383// }
384 }
385 362
386 return presences; 363 m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session data for {0}; {1}",sessionID.ToString(),response["Message"].AsString());
364 return null;
387 } 365 }
388 366
389 private bool UpdateSession(UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) 367 private bool UpdateSession(UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
390 { 368 {
391 // Save our current location as session data 369 // Save our current location as session data
392 NameValueCollection requestArgs = new NameValueCollection 370 NameValueCollection requestArgs = new NameValueCollection
393 { 371 {
394 { "RequestMethod", "UpdateSession" }, 372 { "RequestMethod", "UpdateSession" },
395 { "SessionID", sessionID.ToString() }, 373 { "SessionID", sessionID.ToString() },
396 { "SceneID", regionID.ToString() }, 374 { "SceneID", regionID.ToString() },
397 { "ScenePosition", lastPosition.ToString() }, 375 { "ScenePosition", lastPosition.ToString() },
398 { "SceneLookAt", lastLookAt.ToString() } 376 { "SceneLookAt", lastLookAt.ToString() }
399 }; 377 };
400 378
401 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 379 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
402 bool success = response["Success"].AsBoolean(); 380 bool success = response["Success"].AsBoolean();
403 381
404 if (!success) 382 if (!success)
@@ -407,7 +385,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
407 return success; 385 return success;
408 } 386 }
409 387
410 private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse) 388 private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse)
411 { 389 {
412 if (sessionResponse == null) 390 if (sessionResponse == null)
413 return null; 391 return null;
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs
index bd8069f..8fc766d 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs
@@ -392,7 +392,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
392 { "UserID", client.AgentId.ToString() } 392 { "UserID", client.AgentId.ToString() }
393 }; 393 };
394 394
395 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 395 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
396 string email = response["Email"].AsString(); 396 string email = response["Email"].AsString();
397 397
398 if (!response["Success"].AsBoolean()) 398 if (!response["Success"].AsBoolean())
@@ -425,7 +425,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
425 estate.EstateID, admin.Name); 425 estate.EstateID, admin.Name);
426 426
427 estate.EstateOwner = admin.PrincipalID; 427 estate.EstateOwner = admin.PrincipalID;
428 estate.Save(); 428 scene.EstateDataService.StoreEstateSettings(estate);
429 } 429 }
430 else 430 else
431 { 431 {
@@ -443,7 +443,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
443 { key, OSDParser.SerializeJsonString(value) } 443 { key, OSDParser.SerializeJsonString(value) }
444 }; 444 };
445 445
446 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 446 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
447 bool success = response["Success"].AsBoolean(); 447 bool success = response["Success"].AsBoolean();
448 448
449 if (!success) 449 if (!success)
@@ -462,7 +462,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
462 { "UserID", userID.ToString() } 462 { "UserID", userID.ToString() }
463 }; 463 };
464 464
465 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 465 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
466 if (response["Success"].AsBoolean() && response["User"] is OSDMap) 466 if (response["Success"].AsBoolean() && response["User"] is OSDMap)
467 { 467 {
468 return (OSDMap)response["User"]; 468 return (OSDMap)response["User"];
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs
index 6e32b3a..698c4c0 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs
@@ -165,7 +165,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
165 { "NameQuery", query } 165 { "NameQuery", query }
166 }; 166 };
167 167
168 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 168 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
169 if (response["Success"].AsBoolean()) 169 if (response["Success"].AsBoolean())
170 { 170 {
171 OSDArray array = response["Users"] as OSDArray; 171 OSDArray array = response["Users"] as OSDArray;
@@ -191,6 +191,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
191 return accounts; 191 return accounts;
192 } 192 }
193 193
194 public void InvalidateCache(UUID userID)
195 {
196 m_accountCache.Remove(userID);
197 }
198
194 public bool StoreUserAccount(UserAccount data) 199 public bool StoreUserAccount(UserAccount data)
195 { 200 {
196// m_log.InfoFormat("[SIMIAN ACCOUNT CONNECTOR]: Storing user account for " + data.Name); 201// m_log.InfoFormat("[SIMIAN ACCOUNT CONNECTOR]: Storing user account for " + data.Name);
@@ -204,7 +209,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
204 { "AccessLevel", data.UserLevel.ToString() } 209 { "AccessLevel", data.UserLevel.ToString() }
205 }; 210 };
206 211
207 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 212 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
208 213
209 if (response["Success"].AsBoolean()) 214 if (response["Success"].AsBoolean())
210 { 215 {
@@ -219,7 +224,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
219 { "UserTitle", data.UserTitle } 224 { "UserTitle", data.UserTitle }
220 }; 225 };
221 226
222 response = WebUtil.PostToService(m_serverUrl, requestArgs); 227 response = SimianGrid.PostToService(m_serverUrl, requestArgs);
223 bool success = response["Success"].AsBoolean(); 228 bool success = response["Success"].AsBoolean();
224 229
225 if (success) 230 if (success)
@@ -252,7 +257,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
252 string lookupValue = (requestArgs.Count > 1) ? requestArgs[1] : "(Unknown)"; 257 string lookupValue = (requestArgs.Count > 1) ? requestArgs[1] : "(Unknown)";
253// m_log.DebugFormat("[SIMIAN ACCOUNT CONNECTOR]: Looking up user account with query: " + lookupValue); 258// m_log.DebugFormat("[SIMIAN ACCOUNT CONNECTOR]: Looking up user account with query: " + lookupValue);
254 259
255 OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs); 260 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
256 if (response["Success"].AsBoolean()) 261 if (response["Success"].AsBoolean())
257 { 262 {
258 OSDMap user = response["User"] as OSDMap; 263 OSDMap user = response["User"] as OSDMap;
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index 57f2ffa..cea870b 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -79,11 +79,37 @@ namespace OpenSim.Services.Connectors.Simulation
79 return "agent/"; 79 return "agent/";
80 } 80 }
81 81
82 public bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason) 82 protected virtual void PackData(OSDMap args, GridRegion source, AgentCircuitData aCircuit, GridRegion destination, uint flags)
83 { 83 {
84 // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CreateAgent start"); 84 if (source != null)
85 85 {
86 args["source_x"] = OSD.FromString(source.RegionLocX.ToString());
87 args["source_y"] = OSD.FromString(source.RegionLocY.ToString());
88 args["source_name"] = OSD.FromString(source.RegionName);
89 args["source_uuid"] = OSD.FromString(source.RegionID.ToString());
90 if (!String.IsNullOrEmpty(source.RawServerURI))
91 args["source_server_uri"] = OSD.FromString(source.RawServerURI);
92 }
93
94 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
95 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
96 args["destination_name"] = OSD.FromString(destination.RegionName);
97 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
98 args["teleport_flags"] = OSD.FromString(flags.ToString());
99 }
100
101 public bool CreateAgent(GridRegion source, GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason)
102 {
103 string tmp = String.Empty;
104 return CreateAgent(source, destination, aCircuit, flags, out tmp, out reason);
105 }
106
107 public bool CreateAgent(GridRegion source, GridRegion destination, AgentCircuitData aCircuit, uint flags, out string myipaddress, out string reason)
108 {
109 m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: Creating agent at {0}", destination.ServerURI);
86 reason = String.Empty; 110 reason = String.Empty;
111 myipaddress = String.Empty;
112
87 if (destination == null) 113 if (destination == null)
88 { 114 {
89 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Given destination is null"); 115 m_log.Debug("[REMOTE SIMULATION CONNECTOR]: Given destination is null");
@@ -95,12 +121,7 @@ namespace OpenSim.Services.Connectors.Simulation
95 try 121 try
96 { 122 {
97 OSDMap args = aCircuit.PackAgentCircuitData(); 123 OSDMap args = aCircuit.PackAgentCircuitData();
98 124 PackData(args, source, aCircuit, destination, flags);
99 args["destination_x"] = OSD.FromString(destination.RegionLocX.ToString());
100 args["destination_y"] = OSD.FromString(destination.RegionLocY.ToString());
101 args["destination_name"] = OSD.FromString(destination.RegionName);
102 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
103 args["teleport_flags"] = OSD.FromString(flags.ToString());
104 125
105 OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000); 126 OSDMap result = WebUtil.PostToServiceCompressed(uri, args, 30000);
106 bool success = result["success"].AsBoolean(); 127 bool success = result["success"].AsBoolean();
@@ -110,11 +131,12 @@ namespace OpenSim.Services.Connectors.Simulation
110 131
111 reason = data["reason"].AsString(); 132 reason = data["reason"].AsString();
112 success = data["success"].AsBoolean(); 133 success = data["success"].AsBoolean();
134 myipaddress = data["your_ip"].AsString();
113 return success; 135 return success;
114 } 136 }
115 137
116 // Try the old version, uncompressed 138 // Try the old version, uncompressed
117 result = WebUtil.PostToService(uri, args, 30000); 139 result = WebUtil.PostToService(uri, args, 30000, false);
118 140
119 if (result["Success"].AsBoolean()) 141 if (result["Success"].AsBoolean())
120 { 142 {
@@ -124,6 +146,7 @@ namespace OpenSim.Services.Connectors.Simulation
124 146
125 reason = data["reason"].AsString(); 147 reason = data["reason"].AsString();
126 success = data["success"].AsBoolean(); 148 success = data["success"].AsBoolean();
149 myipaddress = data["your_ip"].AsString();
127 m_log.WarnFormat( 150 m_log.WarnFormat(
128 "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName); 151 "[REMOTE SIMULATION CONNECTOR]: Remote simulator {0} did not accept compressed transfer, suggest updating it.", destination.RegionName);
129 return success; 152 return success;
@@ -228,7 +251,7 @@ namespace OpenSim.Services.Connectors.Simulation
228 /// </summary> 251 /// </summary>
229 private bool UpdateAgent(GridRegion destination, IAgentData cAgentData, int timeout) 252 private bool UpdateAgent(GridRegion destination, IAgentData cAgentData, int timeout)
230 { 253 {
231 // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: UpdateAgent start"); 254 // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: UpdateAgent in {0}", destination.ServerURI);
232 255
233 // Eventually, we want to use a caps url instead of the agentID 256 // Eventually, we want to use a caps url instead of the agentID
234 string uri = destination.ServerURI + AgentPath() + cAgentData.AgentID + "/"; 257 string uri = destination.ServerURI + AgentPath() + cAgentData.AgentID + "/";
@@ -258,48 +281,10 @@ namespace OpenSim.Services.Connectors.Simulation
258 return false; 281 return false;
259 } 282 }
260 283
261 /// <summary>
262 /// Not sure what sequence causes this function to be invoked. The only calling
263 /// path is through the GET method
264 /// </summary>
265 public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
266 {
267 // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: RetrieveAgent start");
268
269 agent = null;
270
271 // Eventually, we want to use a caps url instead of the agentID
272 string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/";
273
274 try
275 {
276 OSDMap result = WebUtil.GetFromService(uri, 10000);
277 if (result["Success"].AsBoolean())
278 {
279 // OSDMap args = Util.GetOSDMap(result["_RawResult"].AsString());
280 OSDMap args = (OSDMap)result["_Result"];
281 if (args != null)
282 {
283 agent = new CompleteAgentData();
284 agent.Unpack(args, null);
285 return true;
286 }
287 }
288 }
289 catch (Exception e)
290 {
291 m_log.Warn("[REMOTE SIMULATION CONNECTOR]: UpdateAgent failed with exception: " + e.ToString());
292 }
293
294 return false;
295 }
296 284
297 /// <summary> 285 public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> featuresAvailable, EntityTransferContext ctx, out string reason)
298 /// </summary>
299 public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason)
300 { 286 {
301 reason = "Failed to contact destination"; 287 reason = "Failed to contact destination";
302 version = "Unknown";
303 288
304 // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position); 289 // m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: QueryAccess start, position={0}", position);
305 290
@@ -307,14 +292,32 @@ namespace OpenSim.Services.Connectors.Simulation
307 if (ext == null) return false; 292 if (ext == null) return false;
308 293
309 // Eventually, we want to use a caps url instead of the agentID 294 // Eventually, we want to use a caps url instead of the agentID
310 string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; 295 string uri = destination.ServerURI + AgentPath() + agentID + "/" + destination.RegionID.ToString() + "/";
311 296
312 OSDMap request = new OSDMap(); 297 OSDMap request = new OSDMap();
298 request.Add("viaTeleport", OSD.FromBoolean(viaTeleport));
313 request.Add("position", OSD.FromString(position.ToString())); 299 request.Add("position", OSD.FromString(position.ToString()));
300 // To those who still understad this field, we're telling them
301 // the lowest version just to be safe
302 request.Add("my_version", OSD.FromString(String.Format("SIMULATION/{0}", VersionInfo.SimulationServiceVersionSupportedMin)));
303 // New simulation service negotiation
304 request.Add("simulation_service_supported_min", OSD.FromReal(VersionInfo.SimulationServiceVersionSupportedMin));
305 request.Add("simulation_service_supported_max", OSD.FromReal(VersionInfo.SimulationServiceVersionSupportedMax));
306 request.Add("simulation_service_accepted_min", OSD.FromReal(VersionInfo.SimulationServiceVersionAcceptedMin));
307 request.Add("simulation_service_accepted_max", OSD.FromReal(VersionInfo.SimulationServiceVersionAcceptedMax));
308
309 OSDArray features = new OSDArray();
310 foreach (UUID feature in featuresAvailable)
311 features.Add(OSD.FromString(feature.ToString()));
312
313 request.Add("features", features);
314
315 if (agentHomeURI != null)
316 request.Add("agent_home_uri", OSD.FromString(agentHomeURI));
314 317
315 try 318 try
316 { 319 {
317 OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 30000, false); 320 OSDMap result = WebUtil.ServiceOSDRequest(uri, request, "QUERYACCESS", 30000, false, false);
318 bool success = result["success"].AsBoolean(); 321 bool success = result["success"].AsBoolean();
319 if (result.ContainsKey("_Result")) 322 if (result.ContainsKey("_Result"))
320 { 323 {
@@ -325,15 +328,32 @@ namespace OpenSim.Services.Connectors.Simulation
325 success = data["success"]; 328 success = data["success"];
326 329
327 reason = data["reason"].AsString(); 330 reason = data["reason"].AsString();
328 if (data["version"] != null && data["version"].AsString() != string.Empty) 331 // We will need to plumb this and start sing the outbound version as well
329 version = data["version"].AsString(); 332 // TODO: lay the pipe for version plumbing
333 if (data.ContainsKey("negotiated_inbound_version") && data["negotiated_inbound_version"] != null)
334 {
335 ctx.InboundVersion = (float)data["negotiated_inbound_version"].AsReal();
336 ctx.OutboundVersion = (float)data["negotiated_outbound_version"].AsReal();
337 }
338 else if (data["version"] != null && data["version"].AsString() != string.Empty)
339 {
340 string versionString = data["version"].AsString();
341 String[] parts = versionString.Split(new char[] {'/'});
342 if (parts.Length > 1)
343 {
344 ctx.InboundVersion = float.Parse(parts[1]);
345 ctx.OutboundVersion = float.Parse(parts[1]);
346 }
347 }
348 if (data.ContainsKey("variable_wearables_count_supported"))
349 ctx.VariableWearablesSupported = true;
330 350
331 m_log.DebugFormat( 351 m_log.DebugFormat(
332 "[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}, reason {2}, version {3} ({4})", 352 "[REMOTE SIMULATION CONNECTOR]: QueryAccess to {0} returned {1}, reason {2}, version {3}/{4}",
333 uri, success, reason, version, data["version"].AsString()); 353 uri, success, reason, ctx.InboundVersion, ctx.OutboundVersion);
334 } 354 }
335 355
336 if (!success) 356 if (!success || ctx.InboundVersion == 0f || ctx.OutboundVersion == 0f)
337 { 357 {
338 // If we don't check this then OpenSimulator 0.7.3.1 and some period before will never see the 358 // If we don't check this then OpenSimulator 0.7.3.1 and some period before will never see the
339 // actual failure message 359 // actual failure message
@@ -359,6 +379,17 @@ namespace OpenSim.Services.Connectors.Simulation
359 return false; 379 return false;
360 } 380 }
361 381
382
383 featuresAvailable.Clear();
384
385 if (result.ContainsKey("features"))
386 {
387 OSDArray array = (OSDArray)result["features"];
388
389 foreach (OSD o in array)
390 featuresAvailable.Add(new UUID(o.AsString()));
391 }
392
362 return success; 393 return success;
363 } 394 }
364 catch (Exception e) 395 catch (Exception e)
@@ -377,7 +408,7 @@ namespace OpenSim.Services.Connectors.Simulation
377 408
378 try 409 try
379 { 410 {
380 WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false); 411 WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false, false);
381 } 412 }
382 catch (Exception e) 413 catch (Exception e)
383 { 414 {
@@ -389,15 +420,14 @@ namespace OpenSim.Services.Connectors.Simulation
389 420
390 /// <summary> 421 /// <summary>
391 /// </summary> 422 /// </summary>
392 public bool CloseAgent(GridRegion destination, UUID id) 423 public bool CloseAgent(GridRegion destination, UUID id, string auth_code)
393 { 424 {
394// m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent start"); 425 string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/?auth=" + auth_code;
395 426 m_log.DebugFormat("[REMOTE SIMULATION CONNECTOR]: CloseAgent {0}", uri);
396 string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/";
397 427
398 try 428 try
399 { 429 {
400 WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false); 430 WebUtil.ServiceOSDRequest(uri, null, "DELETE", 10000, false, false);
401 } 431 }
402 catch (Exception e) 432 catch (Exception e)
403 { 433 {
@@ -444,11 +474,18 @@ namespace OpenSim.Services.Connectors.Simulation
444 args["destination_name"] = OSD.FromString(destination.RegionName); 474 args["destination_name"] = OSD.FromString(destination.RegionName);
445 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString()); 475 args["destination_uuid"] = OSD.FromString(destination.RegionID.ToString());
446 476
447 WebUtil.PostToService(uri, args, 40000); 477 OSDMap result = WebUtil.PostToService(uri, args, 40000, false);
478
479 if (result == null)
480 return false;
481 bool success = result["success"].AsBoolean();
482 if (!success)
483 return false;
448 } 484 }
449 catch (Exception e) 485 catch (Exception e)
450 { 486 {
451 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] CreateObject failed with exception; {0}",e.ToString()); 487 m_log.WarnFormat("[REMOTE SIMULATION CONNECTOR] CreateObject failed with exception; {0}",e.ToString());
488 return false;
452 } 489 }
453 490
454 return true; 491 return true;
diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs
index 6d5ce28..c21db54 100644
--- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs
+++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs
@@ -32,14 +32,15 @@ using System.IO;
32using System.Reflection; 32using System.Reflection;
33using Nini.Config; 33using Nini.Config;
34using OpenSim.Framework; 34using OpenSim.Framework;
35using OpenSim.Framework.Communications; 35
36using OpenSim.Framework.ServiceAuth;
36using OpenSim.Server.Base; 37using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces; 38using OpenSim.Services.Interfaces;
38using OpenMetaverse; 39using OpenMetaverse;
39 40
40namespace OpenSim.Services.Connectors 41namespace OpenSim.Services.Connectors
41{ 42{
42 public class UserAccountServicesConnector : IUserAccountService 43 public class UserAccountServicesConnector : BaseServiceConnector, IUserAccountService
43 { 44 {
44 private static readonly ILog m_log = 45 private static readonly ILog m_log =
45 LogManager.GetLogger( 46 LogManager.GetLogger(
@@ -79,6 +80,8 @@ namespace OpenSim.Services.Connectors
79 throw new Exception("User account connector init error"); 80 throw new Exception("User account connector init error");
80 } 81 }
81 m_ServerURI = serviceURI; 82 m_ServerURI = serviceURI;
83
84 base.Initialise(source, "UserAccountService");
82 } 85 }
83 86
84 public virtual UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) 87 public virtual UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName)
@@ -144,7 +147,8 @@ namespace OpenSim.Services.Connectors
144 { 147 {
145 reply = SynchronousRestFormsRequester.MakeRequest("POST", 148 reply = SynchronousRestFormsRequester.MakeRequest("POST",
146 uri, 149 uri,
147 reqString); 150 reqString,
151 m_Auth);
148 if (reply == null || (reply != null && reply == string.Empty)) 152 if (reply == null || (reply != null && reply == string.Empty))
149 { 153 {
150 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received null or empty reply"); 154 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccounts received null or empty reply");
@@ -162,7 +166,7 @@ namespace OpenSim.Services.Connectors
162 166
163 if (replyData != null) 167 if (replyData != null)
164 { 168 {
165 if (replyData.ContainsKey("result") && replyData.ContainsKey("result").ToString() == "null") 169 if (replyData.ContainsKey("result") && replyData["result"].ToString() == "null")
166 { 170 {
167 return accounts; 171 return accounts;
168 } 172 }
@@ -187,6 +191,10 @@ namespace OpenSim.Services.Connectors
187 return accounts; 191 return accounts;
188 } 192 }
189 193
194 public void InvalidateCache(UUID userID)
195 {
196 }
197
190 public virtual bool StoreUserAccount(UserAccount data) 198 public virtual bool StoreUserAccount(UserAccount data)
191 { 199 {
192 Dictionary<string, object> sendData = new Dictionary<string, object>(); 200 Dictionary<string, object> sendData = new Dictionary<string, object>();
@@ -207,9 +215,39 @@ namespace OpenSim.Services.Connectors
207 sendData[kvp.Key] = kvp.Value.ToString(); 215 sendData[kvp.Key] = kvp.Value.ToString();
208 } 216 }
209 217
210 return SendAndGetBoolReply(sendData); 218 if (SendAndGetReply(sendData) != null)
219 return true;
220 else
221 return false;
211 } 222 }
212 223
224 /// <summary>
225 /// Create user remotely. Note this this is not part of the IUserAccountsService
226 /// </summary>
227 /// <param name="first"></param>
228 /// <param name="last"></param>
229 /// <param name="password"></param>
230 /// <param name="email"></param>
231 /// <param name="scopeID"></param>
232 /// <returns></returns>
233 public virtual UserAccount CreateUser(string first, string last, string password, string email, UUID scopeID)
234 {
235 Dictionary<string, object> sendData = new Dictionary<string, object>();
236 //sendData["SCOPEID"] = scopeID.ToString();
237 sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
238 sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
239 sendData["METHOD"] = "createuser";
240
241 sendData["FirstName"] = first;
242 sendData["LastName"] = last;
243 sendData["Password"] = password;
244 if (!string.IsNullOrEmpty(email))
245 sendData["Email"] = first;
246 sendData["ScopeID"] = scopeID.ToString();
247
248 return SendAndGetReply(sendData);
249 }
250
213 private UserAccount SendAndGetReply(Dictionary<string, object> sendData) 251 private UserAccount SendAndGetReply(Dictionary<string, object> sendData)
214 { 252 {
215 string reply = string.Empty; 253 string reply = string.Empty;
@@ -220,7 +258,8 @@ namespace OpenSim.Services.Connectors
220 { 258 {
221 reply = SynchronousRestFormsRequester.MakeRequest("POST", 259 reply = SynchronousRestFormsRequester.MakeRequest("POST",
222 uri, 260 uri,
223 reqString); 261 reqString,
262 m_Auth);
224 if (reply == null || (reply != null && reply == string.Empty)) 263 if (reply == null || (reply != null && reply == string.Empty))
225 { 264 {
226 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccount received null or empty reply"); 265 m_log.DebugFormat("[ACCOUNT CONNECTOR]: GetUserAccount received null or empty reply");
@@ -251,14 +290,16 @@ namespace OpenSim.Services.Connectors
251 { 290 {
252 string reqString = ServerUtils.BuildQueryString(sendData); 291 string reqString = ServerUtils.BuildQueryString(sendData);
253 string uri = m_ServerURI + "/accounts"; 292 string uri = m_ServerURI + "/accounts";
254 // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); 293 //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString);
255 try 294 try
256 { 295 {
257 string reply = SynchronousRestFormsRequester.MakeRequest("POST", 296 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
258 uri, 297 uri,
259 reqString); 298 reqString,
299 m_Auth);
260 if (reply != string.Empty) 300 if (reply != string.Empty)
261 { 301 {
302 //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: reply = {0}", reply);
262 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 303 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
263 304
264 if (replyData.ContainsKey("result")) 305 if (replyData.ContainsKey("result"))
diff --git a/OpenSim/Services/Connectors/Simulation/EstateDataService.cs b/OpenSim/Services/EstateService/EstateDataService.cs
index cdcdecf..f6a8654 100644
--- a/OpenSim/Services/Connectors/Simulation/EstateDataService.cs
+++ b/OpenSim/Services/EstateService/EstateDataService.cs
@@ -29,17 +29,14 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using log4net; 31using log4net;
32using Mono.Addins;
33using Nini.Config; 32using Nini.Config;
34using System.Reflection; 33using System.Reflection;
35using OpenSim.Services.Base; 34using OpenSim.Services.Base;
36using OpenSim.Services.Interfaces; 35using OpenSim.Services.Interfaces;
37using OpenSim.Data; 36using OpenSim.Data;
38using OpenSim.Framework; 37using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41 38
42namespace OpenSim.Services.Connectors 39namespace OpenSim.Services.EstateService
43{ 40{
44 public class EstateDataService : ServiceBase, IEstateDataService 41 public class EstateDataService : ServiceBase, IEstateDataService
45 { 42 {
diff --git a/OpenSim/Services/FSAssetService/FSAssetService.cs b/OpenSim/Services/FSAssetService/FSAssetService.cs
new file mode 100644
index 0000000..1bab687
--- /dev/null
+++ b/OpenSim/Services/FSAssetService/FSAssetService.cs
@@ -0,0 +1,723 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Diagnostics;
30using System.Collections.Generic;
31using System.IO;
32using System.IO.Compression;
33using System.Text;
34using System.Threading;
35using System.Reflection;
36using OpenSim.Data;
37using OpenSim.Framework;
38using OpenSim.Framework.Serialization.External;
39using OpenSim.Framework.Console;
40using OpenSim.Server.Base;
41using OpenSim.Services.Base;
42using OpenSim.Services.Interfaces;
43using Nini.Config;
44using log4net;
45using OpenMetaverse;
46using System.Security.Cryptography;
47
48namespace OpenSim.Services.FSAssetService
49{
50 public class FSAssetConnector : ServiceBase, IAssetService
51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
55 static SHA256CryptoServiceProvider SHA256 = new SHA256CryptoServiceProvider();
56
57 static byte[] ToCString(string s)
58 {
59 byte[] ret = enc.GetBytes(s);
60 Array.Resize(ref ret, ret.Length + 1);
61 ret[ret.Length - 1] = 0;
62
63 return ret;
64 }
65
66 protected IAssetLoader m_AssetLoader = null;
67 protected IFSAssetDataPlugin m_DataConnector = null;
68 protected IAssetService m_FallbackService;
69 protected Thread m_WriterThread;
70 protected Thread m_StatsThread;
71 protected string m_SpoolDirectory;
72 protected object m_readLock = new object();
73 protected object m_statsLock = new object();
74 protected int m_readCount = 0;
75 protected int m_readTicks = 0;
76 protected int m_missingAssets = 0;
77 protected int m_missingAssetsFS = 0;
78 protected string m_FSBase;
79
80 private static bool m_Initialized;
81 private bool m_MainInstance;
82
83 public FSAssetConnector(IConfigSource config)
84 : this(config, "AssetService")
85 {
86 }
87
88 public FSAssetConnector(IConfigSource config, string configName) : base(config)
89 {
90 if (!m_Initialized)
91 {
92 m_Initialized = true;
93 m_MainInstance = true;
94
95 MainConsole.Instance.Commands.AddCommand("fs", false,
96 "show assets", "show assets", "Show asset stats",
97 HandleShowAssets);
98 MainConsole.Instance.Commands.AddCommand("fs", false,
99 "show digest", "show digest <ID>", "Show asset digest",
100 HandleShowDigest);
101 MainConsole.Instance.Commands.AddCommand("fs", false,
102 "delete asset", "delete asset <ID>",
103 "Delete asset from database",
104 HandleDeleteAsset);
105 MainConsole.Instance.Commands.AddCommand("fs", false,
106 "import", "import <conn> <table> [<start> <count>]",
107 "Import legacy assets",
108 HandleImportAssets);
109 MainConsole.Instance.Commands.AddCommand("fs", false,
110 "force import", "force import <conn> <table> [<start> <count>]",
111 "Import legacy assets, overwriting current content",
112 HandleImportAssets);
113 }
114
115 IConfig assetConfig = config.Configs[configName];
116
117 if (assetConfig == null)
118 throw new Exception("No AssetService configuration");
119
120 // Get Database Connector from Asset Config (If present)
121 string dllName = assetConfig.GetString("StorageProvider", string.Empty);
122 string m_ConnectionString = assetConfig.GetString("ConnectionString", string.Empty);
123 string m_Realm = assetConfig.GetString("Realm", "fsassets");
124
125 int SkipAccessTimeDays = assetConfig.GetInt("DaysBetweenAccessTimeUpdates", 0);
126
127 // If not found above, fallback to Database defaults
128 IConfig dbConfig = config.Configs["DatabaseService"];
129
130 if (dbConfig != null)
131 {
132 if (dllName == String.Empty)
133 dllName = dbConfig.GetString("StorageProvider", String.Empty);
134
135 if (m_ConnectionString == String.Empty)
136 m_ConnectionString = dbConfig.GetString("ConnectionString", String.Empty);
137 }
138
139 // No databse connection found in either config
140 if (dllName.Equals(String.Empty))
141 throw new Exception("No StorageProvider configured");
142
143 if (m_ConnectionString.Equals(String.Empty))
144 throw new Exception("Missing database connection string");
145
146 // Create Storage Provider
147 m_DataConnector = LoadPlugin<IFSAssetDataPlugin>(dllName);
148
149 if (m_DataConnector == null)
150 throw new Exception(string.Format("Could not find a storage interface in the module {0}", dllName));
151
152 // Initialize DB And perform any migrations required
153 m_DataConnector.Initialise(m_ConnectionString, m_Realm, SkipAccessTimeDays);
154
155 // Setup Fallback Service
156 string str = assetConfig.GetString("FallbackService", string.Empty);
157
158 if (str != string.Empty)
159 {
160 object[] args = new object[] { config };
161 m_FallbackService = LoadPlugin<IAssetService>(str, args);
162 if (m_FallbackService != null)
163 {
164 m_log.Info("[FSASSETS]: Fallback service loaded");
165 }
166 else
167 {
168 m_log.Error("[FSASSETS]: Failed to load fallback service");
169 }
170 }
171
172 // Setup directory structure including temp directory
173 m_SpoolDirectory = assetConfig.GetString("SpoolDirectory", "/tmp");
174
175 string spoolTmp = Path.Combine(m_SpoolDirectory, "spool");
176
177 Directory.CreateDirectory(spoolTmp);
178
179 m_FSBase = assetConfig.GetString("BaseDirectory", String.Empty);
180 if (m_FSBase == String.Empty)
181 {
182 m_log.ErrorFormat("[FSASSETS]: BaseDirectory not specified");
183 throw new Exception("Configuration error");
184 }
185
186 if (m_MainInstance)
187 {
188 string loader = assetConfig.GetString("DefaultAssetLoader", string.Empty);
189 if (loader != string.Empty)
190 {
191 m_AssetLoader = LoadPlugin<IAssetLoader>(loader);
192 string loaderArgs = assetConfig.GetString("AssetLoaderArgs", string.Empty);
193 m_log.InfoFormat("[FSASSETS]: Loading default asset set from {0}", loaderArgs);
194 m_AssetLoader.ForEachDefaultXmlAsset(loaderArgs,
195 delegate(AssetBase a)
196 {
197 Store(a, false);
198 });
199 }
200
201 m_WriterThread = new Thread(Writer);
202 m_WriterThread.Start();
203 m_StatsThread = new Thread(Stats);
204 m_StatsThread.Start();
205 }
206
207 m_log.Info("[FSASSETS]: FS asset service enabled");
208 }
209
210 private void Stats()
211 {
212 while (true)
213 {
214 Thread.Sleep(60000);
215
216 lock (m_statsLock)
217 {
218 if (m_readCount > 0)
219 {
220 double avg = (double)m_readTicks / (double)m_readCount;
221// if (avg > 10000)
222// Environment.Exit(0);
223 m_log.InfoFormat("[FSASSETS]: Read stats: {0} files, {1} ticks, avg {2:F2}, missing {3}, FS {4}", m_readCount, m_readTicks, (double)m_readTicks / (double)m_readCount, m_missingAssets, m_missingAssetsFS);
224 }
225 m_readCount = 0;
226 m_readTicks = 0;
227 m_missingAssets = 0;
228 m_missingAssetsFS = 0;
229 }
230 }
231 }
232
233 private void Writer()
234 {
235 m_log.Info("[FSASSETS]: Writer started");
236
237 while (true)
238 {
239 string[] files = Directory.GetFiles(m_SpoolDirectory);
240
241 if (files.Length > 0)
242 {
243 int tickCount = Environment.TickCount;
244 for (int i = 0 ; i < files.Length ; i++)
245 {
246 string hash = Path.GetFileNameWithoutExtension(files[i]);
247 string s = HashToFile(hash);
248 string diskFile = Path.Combine(m_FSBase, s);
249
250 Directory.CreateDirectory(Path.GetDirectoryName(diskFile));
251 try
252 {
253 byte[] data = File.ReadAllBytes(files[i]);
254
255 using (GZipStream gz = new GZipStream(new FileStream(diskFile + ".gz", FileMode.Create), CompressionMode.Compress))
256 {
257 gz.Write(data, 0, data.Length);
258 gz.Close();
259 }
260 File.Delete(files[i]);
261
262 //File.Move(files[i], diskFile);
263 }
264 catch(System.IO.IOException e)
265 {
266 if (e.Message.StartsWith("Win32 IO returned ERROR_ALREADY_EXISTS"))
267 File.Delete(files[i]);
268 else
269 throw;
270 }
271 }
272 int totalTicks = System.Environment.TickCount - tickCount;
273 if (totalTicks > 0) // Wrap?
274 {
275 m_log.InfoFormat("[FSASSETS]: Write cycle complete, {0} files, {1} ticks, avg {2:F2}", files.Length, totalTicks, (double)totalTicks / (double)files.Length);
276 }
277 }
278
279 Thread.Sleep(1000);
280 }
281 }
282
283 string GetSHA256Hash(byte[] data)
284 {
285 byte[] hash = SHA256.ComputeHash(data);
286
287 return BitConverter.ToString(hash).Replace("-", String.Empty);
288 }
289
290 public string HashToPath(string hash)
291 {
292 if (hash == null || hash.Length < 10)
293 return "junkyard";
294
295 return Path.Combine(hash.Substring(0, 3),
296 Path.Combine(hash.Substring(3, 3)));
297 /*
298 * The below is what core would normally use.
299 * This is modified to work in OSGrid, as seen
300 * above, because the SRAS data is structured
301 * that way.
302 */
303 /*
304 return Path.Combine(hash.Substring(0, 2),
305 Path.Combine(hash.Substring(2, 2),
306 Path.Combine(hash.Substring(4, 2),
307 hash.Substring(6, 4))));
308 */
309 }
310
311 private bool AssetExists(string hash)
312 {
313 string s = HashToFile(hash);
314 string diskFile = Path.Combine(m_FSBase, s);
315
316 if (File.Exists(diskFile + ".gz") || File.Exists(diskFile))
317 return true;
318
319 return false;
320 }
321
322 public virtual bool[] AssetsExist(string[] ids)
323 {
324 UUID[] uuid = Array.ConvertAll(ids, id => UUID.Parse(id));
325 return m_DataConnector.AssetsExist(uuid);
326 }
327
328 public string HashToFile(string hash)
329 {
330 return Path.Combine(HashToPath(hash), hash);
331 }
332
333 public virtual AssetBase Get(string id)
334 {
335 string hash;
336
337 return Get(id, out hash);
338 }
339
340 private AssetBase Get(string id, out string sha)
341 {
342 string hash = string.Empty;
343
344 int startTime = System.Environment.TickCount;
345 AssetMetadata metadata;
346
347 lock (m_readLock)
348 {
349 metadata = m_DataConnector.Get(id, out hash);
350 }
351
352 sha = hash;
353
354 if (metadata == null)
355 {
356 AssetBase asset = null;
357 if (m_FallbackService != null)
358 {
359 asset = m_FallbackService.Get(id);
360 if (asset != null)
361 {
362 asset.Metadata.ContentType =
363 SLUtil.SLAssetTypeToContentType((int)asset.Type);
364 sha = GetSHA256Hash(asset.Data);
365 m_log.InfoFormat("[FSASSETS]: Added asset {0} from fallback to local store", id);
366 Store(asset);
367 }
368 }
369 if (asset == null)
370 {
371 // m_log.InfoFormat("[FSASSETS]: Asset {0} not found", id);
372 m_missingAssets++;
373 }
374 return asset;
375 }
376 AssetBase newAsset = new AssetBase();
377 newAsset.Metadata = metadata;
378 try
379 {
380 newAsset.Data = GetFsData(hash);
381 if (newAsset.Data.Length == 0)
382 {
383 AssetBase asset = null;
384 if (m_FallbackService != null)
385 {
386 asset = m_FallbackService.Get(id);
387 if (asset != null)
388 {
389 asset.Metadata.ContentType =
390 SLUtil.SLAssetTypeToContentType((int)asset.Type);
391 sha = GetSHA256Hash(asset.Data);
392 m_log.InfoFormat("[FSASSETS]: Added asset {0} from fallback to local store", id);
393 Store(asset);
394 }
395 }
396 if (asset == null)
397 m_missingAssetsFS++;
398 // m_log.InfoFormat("[FSASSETS]: Asset {0}, hash {1} not found in FS", id, hash);
399 else
400 {
401 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
402 // Fix bad assets before sending them elsewhere
403 if (asset.Type == (int)AssetType.Object && asset.Data != null)
404 {
405 string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(asset.Data));
406 asset.Data = Utils.StringToBytes(xml);
407 }
408 return asset;
409 }
410 }
411
412 lock (m_statsLock)
413 {
414 m_readTicks += Environment.TickCount - startTime;
415 m_readCount++;
416 }
417
418 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
419 // Fix bad assets before sending them elsewhere
420 if (newAsset.Type == (int)AssetType.Object && newAsset.Data != null)
421 {
422 string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(newAsset.Data));
423 newAsset.Data = Utils.StringToBytes(xml);
424 }
425
426 return newAsset;
427 }
428 catch (Exception exception)
429 {
430 m_log.Error(exception.ToString());
431 Thread.Sleep(5000);
432 Environment.Exit(1);
433 return null;
434 }
435 }
436
437 public virtual AssetMetadata GetMetadata(string id)
438 {
439 string hash;
440 return m_DataConnector.Get(id, out hash);
441 }
442
443 public virtual byte[] GetData(string id)
444 {
445 string hash;
446 if (m_DataConnector.Get(id, out hash) == null)
447 return null;
448
449 return GetFsData(hash);
450 }
451
452 public bool Get(string id, Object sender, AssetRetrieved handler)
453 {
454 AssetBase asset = Get(id);
455
456 handler(id, sender, asset);
457
458 return true;
459 }
460
461 public byte[] GetFsData(string hash)
462 {
463 string spoolFile = Path.Combine(m_SpoolDirectory, hash + ".asset");
464
465 if (File.Exists(spoolFile))
466 {
467 try
468 {
469 byte[] content = File.ReadAllBytes(spoolFile);
470
471 return content;
472 }
473 catch
474 {
475 }
476 }
477
478 string file = HashToFile(hash);
479 string diskFile = Path.Combine(m_FSBase, file);
480
481 if (File.Exists(diskFile + ".gz"))
482 {
483 try
484 {
485 using (GZipStream gz = new GZipStream(new FileStream(diskFile + ".gz", FileMode.Open, FileAccess.Read), CompressionMode.Decompress))
486 {
487 using (MemoryStream ms = new MemoryStream())
488 {
489 byte[] data = new byte[32768];
490 int bytesRead;
491
492 do
493 {
494 bytesRead = gz.Read(data, 0, 32768);
495 if (bytesRead > 0)
496 ms.Write(data, 0, bytesRead);
497 } while (bytesRead > 0);
498
499 return ms.ToArray();
500 }
501 }
502 }
503 catch (Exception)
504 {
505 return new Byte[0];
506 }
507 }
508 else if (File.Exists(diskFile))
509 {
510 try
511 {
512 byte[] content = File.ReadAllBytes(diskFile);
513
514 return content;
515 }
516 catch
517 {
518 }
519 }
520 return new Byte[0];
521
522 }
523
524 public virtual string Store(AssetBase asset)
525 {
526 return Store(asset, false);
527 }
528
529 private string Store(AssetBase asset, bool force)
530 {
531 int tickCount = Environment.TickCount;
532 string hash = GetSHA256Hash(asset.Data);
533
534 if (!AssetExists(hash))
535 {
536 string tempFile = Path.Combine(Path.Combine(m_SpoolDirectory, "spool"), hash + ".asset");
537 string finalFile = Path.Combine(m_SpoolDirectory, hash + ".asset");
538
539 if (!File.Exists(finalFile))
540 {
541 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
542 // Fix bad assets before storing on this server
543 if (asset.Type == (int)AssetType.Object && asset.Data != null)
544 {
545 string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(asset.Data));
546 asset.Data = Utils.StringToBytes(xml);
547 }
548
549 FileStream fs = File.Create(tempFile);
550
551 fs.Write(asset.Data, 0, asset.Data.Length);
552
553 fs.Close();
554
555 File.Move(tempFile, finalFile);
556 }
557 }
558
559 if (asset.ID == string.Empty)
560 {
561 if (asset.FullID == UUID.Zero)
562 {
563 asset.FullID = UUID.Random();
564 }
565 asset.ID = asset.FullID.ToString();
566 }
567 else if (asset.FullID == UUID.Zero)
568 {
569 UUID uuid = UUID.Zero;
570 if (UUID.TryParse(asset.ID, out uuid))
571 {
572 asset.FullID = uuid;
573 }
574 else
575 {
576 asset.FullID = UUID.Random();
577 }
578 }
579
580 if (!m_DataConnector.Store(asset.Metadata, hash))
581 {
582 return UUID.Zero.ToString();
583 }
584 else
585 {
586 return asset.ID;
587 }
588 }
589
590 public bool UpdateContent(string id, byte[] data)
591 {
592 return false;
593
594// string oldhash;
595// AssetMetadata meta = m_DataConnector.Get(id, out oldhash);
596//
597// if (meta == null)
598// return false;
599//
600// AssetBase asset = new AssetBase();
601// asset.Metadata = meta;
602// asset.Data = data;
603//
604// Store(asset);
605//
606// return true;
607 }
608
609 public virtual bool Delete(string id)
610 {
611 m_DataConnector.Delete(id);
612
613 return true;
614 }
615
616 private void HandleShowAssets(string module, string[] args)
617 {
618 int num = m_DataConnector.Count();
619 MainConsole.Instance.Output(string.Format("Total asset count: {0}", num));
620 }
621
622 private void HandleShowDigest(string module, string[] args)
623 {
624 if (args.Length < 3)
625 {
626 MainConsole.Instance.Output("Syntax: show digest <ID>");
627 return;
628 }
629
630 string hash;
631 AssetBase asset = Get(args[2], out hash);
632
633 if (asset == null || asset.Data.Length == 0)
634 {
635 MainConsole.Instance.Output("Asset not found");
636 return;
637 }
638
639 int i;
640
641 MainConsole.Instance.Output(String.Format("Name: {0}", asset.Name));
642 MainConsole.Instance.Output(String.Format("Description: {0}", asset.Description));
643 MainConsole.Instance.Output(String.Format("Type: {0}", asset.Type));
644 MainConsole.Instance.Output(String.Format("Content-type: {0}", asset.Metadata.ContentType));
645 MainConsole.Instance.Output(String.Format("Flags: {0}", asset.Metadata.Flags.ToString()));
646 MainConsole.Instance.Output(String.Format("FS file: {0}", HashToFile(hash)));
647
648 for (i = 0 ; i < 5 ; i++)
649 {
650 int off = i * 16;
651 if (asset.Data.Length <= off)
652 break;
653 int len = 16;
654 if (asset.Data.Length < off + len)
655 len = asset.Data.Length - off;
656
657 byte[] line = new byte[len];
658 Array.Copy(asset.Data, off, line, 0, len);
659
660 string text = BitConverter.ToString(line);
661 MainConsole.Instance.Output(String.Format("{0:x4}: {1}", off, text));
662 }
663 }
664
665 private void HandleDeleteAsset(string module, string[] args)
666 {
667 if (args.Length < 3)
668 {
669 MainConsole.Instance.Output("Syntax: delete asset <ID>");
670 return;
671 }
672
673 AssetBase asset = Get(args[2]);
674
675 if (asset == null || asset.Data.Length == 0)
676 {
677 MainConsole.Instance.Output("Asset not found");
678 return;
679 }
680
681 m_DataConnector.Delete(args[2]);
682
683 MainConsole.Instance.Output("Asset deleted");
684 }
685
686 private void HandleImportAssets(string module, string[] args)
687 {
688 bool force = false;
689 if (args[0] == "force")
690 {
691 force = true;
692 List<string> list = new List<string>(args);
693 list.RemoveAt(0);
694 args = list.ToArray();
695 }
696 if (args.Length < 3)
697 {
698 MainConsole.Instance.Output("Syntax: import <conn> <table> [<start> <count>]");
699 }
700 else
701 {
702 string conn = args[1];
703 string table = args[2];
704 int start = 0;
705 int count = -1;
706 if (args.Length > 3)
707 {
708 start = Convert.ToInt32(args[3]);
709 }
710 if (args.Length > 4)
711 {
712 count = Convert.ToInt32(args[4]);
713 }
714 m_DataConnector.Import(conn, table, start, count, force, new FSStoreDelegate(Store));
715 }
716 }
717
718 public AssetBase GetCached(string id)
719 {
720 return Get(id);
721 }
722 }
723}
diff --git a/OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs b/OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs
index 58c7283..1e3560b 100644
--- a/OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/Friends/Properties/AssemblyInfo.cs b/OpenSim/Services/Friends/Properties/AssemblyInfo.cs
index dddb091..87fb6a9 100644
--- a/OpenSim/Services/Friends/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/Friends/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index ee3b858..0c502a2 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -46,6 +46,7 @@ namespace OpenSim.Services.GridService
46 private static readonly ILog m_log = 46 private static readonly ILog m_log =
47 LogManager.GetLogger( 47 LogManager.GetLogger(
48 MethodBase.GetCurrentMethod().DeclaringType); 48 MethodBase.GetCurrentMethod().DeclaringType);
49 private string LogHeader = "[GRID SERVICE]";
49 50
50 private bool m_DeleteOnUnregister = true; 51 private bool m_DeleteOnUnregister = true;
51 private static GridService m_RootInstance = null; 52 private static GridService m_RootInstance = null;
@@ -56,6 +57,10 @@ namespace OpenSim.Services.GridService
56 protected bool m_AllowDuplicateNames = false; 57 protected bool m_AllowDuplicateNames = false;
57 protected bool m_AllowHypergridMapSearch = false; 58 protected bool m_AllowHypergridMapSearch = false;
58 59
60 protected bool m_SuppressVarregionOverlapCheckOnRegistration = false;
61
62 private static Dictionary<string,object> m_ExtraFeatures = new Dictionary<string, object>();
63
59 public GridService(IConfigSource config) 64 public GridService(IConfigSource config)
60 : base(config) 65 : base(config)
61 { 66 {
@@ -63,6 +68,9 @@ namespace OpenSim.Services.GridService
63 68
64 m_config = config; 69 m_config = config;
65 IConfig gridConfig = config.Configs["GridService"]; 70 IConfig gridConfig = config.Configs["GridService"];
71
72 bool suppressConsoleCommands = false;
73
66 if (gridConfig != null) 74 if (gridConfig != null)
67 { 75 {
68 m_DeleteOnUnregister = gridConfig.GetBoolean("DeleteOnUnregister", true); 76 m_DeleteOnUnregister = gridConfig.GetBoolean("DeleteOnUnregister", true);
@@ -76,32 +84,33 @@ namespace OpenSim.Services.GridService
76 } 84 }
77 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); 85 m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames);
78 m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch); 86 m_AllowHypergridMapSearch = gridConfig.GetBoolean("AllowHypergridMapSearch", m_AllowHypergridMapSearch);
87
88 m_SuppressVarregionOverlapCheckOnRegistration = gridConfig.GetBoolean("SuppressVarregionOverlapCheckOnRegistration", m_SuppressVarregionOverlapCheckOnRegistration);
89
90 // This service is also used locally by a simulator running in grid mode. This switches prevents
91 // inappropriate console commands from being registered
92 suppressConsoleCommands = gridConfig.GetBoolean("SuppressConsoleCommands", suppressConsoleCommands);
79 } 93 }
80 94
81 if (m_RootInstance == null) 95 if (m_RootInstance == null)
82 { 96 {
83 m_RootInstance = this; 97 m_RootInstance = this;
84 98
85 if (MainConsole.Instance != null) 99 if (!suppressConsoleCommands && MainConsole.Instance != null)
86 { 100 {
87 MainConsole.Instance.Commands.AddCommand("Regions", true, 101 MainConsole.Instance.Commands.AddCommand("Regions", true,
88 "deregister region id", 102 "deregister region id",
89 "deregister region id <Region UUID>", 103 "deregister region id <region-id>+",
90 "Deregister a region manually.", 104 "Deregister a region manually.",
91 String.Empty, 105 String.Empty,
92 HandleDeregisterRegion); 106 HandleDeregisterRegion);
93 107
94 // A messy way of stopping this command being added if we are in standalone (since the simulator 108 MainConsole.Instance.Commands.AddCommand("Regions", true,
95 // has an identically named command 109 "show regions",
96 // 110 "show regions",
97 // XXX: We're relying on the OpenSimulator version being registered first, which is not well defined. 111 "Show details on all regions",
98 if (MainConsole.Instance.Commands.Resolve(new string[] { "show", "regions" }).Length == 0) 112 String.Empty,
99 MainConsole.Instance.Commands.AddCommand("Regions", true, 113 HandleShowRegions);
100 "show regions",
101 "show regions",
102 "Show details on all regions",
103 String.Empty,
104 HandleShowRegions);
105 114
106 MainConsole.Instance.Commands.AddCommand("Regions", true, 115 MainConsole.Instance.Commands.AddCommand("Regions", true,
107 "show region name", 116 "show region name",
@@ -117,17 +126,72 @@ namespace OpenSim.Services.GridService
117 "For example, show region at 1000 1000", 126 "For example, show region at 1000 1000",
118 HandleShowRegionAt); 127 HandleShowRegionAt);
119 128
120 MainConsole.Instance.Commands.AddCommand("Regions", true, 129 MainConsole.Instance.Commands.AddCommand("General", true,
121 "set region flags", 130 "show grid size",
122 "set region flags <Region name> <flags>", 131 "show grid size",
123 "Set database flags for region", 132 "Show the current grid size (excluding hyperlink references)",
124 String.Empty, 133 String.Empty,
125 HandleSetFlags); 134 HandleShowGridSize);
135
136 MainConsole.Instance.Commands.AddCommand("Regions", true,
137 "set region flags",
138 "set region flags <Region name> <flags>",
139 "Set database flags for region",
140 String.Empty,
141 HandleSetFlags);
126 } 142 }
143
144 if (!suppressConsoleCommands)
145 SetExtraServiceURLs(config);
146
127 m_HypergridLinker = new HypergridLinker(m_config, this, m_Database); 147 m_HypergridLinker = new HypergridLinker(m_config, this, m_Database);
128 } 148 }
129 } 149 }
130 150
151 private void SetExtraServiceURLs(IConfigSource config)
152 {
153 IConfig loginConfig = config.Configs["LoginService"];
154 IConfig gridConfig = config.Configs["GridService"];
155
156 if (loginConfig == null || gridConfig == null)
157 return;
158
159 string configVal;
160
161 configVal = loginConfig.GetString("SearchURL", string.Empty);
162 if (!string.IsNullOrEmpty(configVal))
163 m_ExtraFeatures["search-server-url"] = configVal;
164
165 configVal = loginConfig.GetString("MapTileURL", string.Empty);
166 if (!string.IsNullOrEmpty(configVal))
167 {
168 // This URL must end with '/', the viewer doesn't check
169 configVal = configVal.Trim();
170 if (!configVal.EndsWith("/"))
171 configVal = configVal + "/";
172 m_ExtraFeatures["map-server-url"] = configVal;
173 }
174
175 configVal = loginConfig.GetString("DestinationGuide", string.Empty);
176 if (!string.IsNullOrEmpty(configVal))
177 m_ExtraFeatures["destination-guide-url"] = configVal;
178
179 configVal = Util.GetConfigVarFromSections<string>(
180 config, "GatekeeperURI", new string[] { "Startup", "Hypergrid" }, String.Empty);
181 if (!string.IsNullOrEmpty(configVal))
182 m_ExtraFeatures["GridURL"] = configVal;
183
184 configVal = Util.GetConfigVarFromSections<string>(
185 config, "GridName", new string[] { "Const", "Hypergrid" }, String.Empty);
186 if (string.IsNullOrEmpty(configVal))
187 configVal = Util.GetConfigVarFromSections<string>(
188 config, "gridname", new string[] { "GridInfo" }, String.Empty);
189 if (!string.IsNullOrEmpty(configVal))
190 m_ExtraFeatures["GridName"] = configVal;
191
192 m_ExtraFeatures["ExportSupported"] = gridConfig.GetString("ExportSupported", "true");
193 }
194
131 #region IGridService 195 #region IGridService
132 196
133 public string RegisterRegion(UUID scopeID, GridRegion regionInfos) 197 public string RegisterRegion(UUID scopeID, GridRegion regionInfos)
@@ -137,12 +201,19 @@ namespace OpenSim.Services.GridService
137 if (regionInfos.RegionID == UUID.Zero) 201 if (regionInfos.RegionID == UUID.Zero)
138 return "Invalid RegionID - cannot be zero UUID"; 202 return "Invalid RegionID - cannot be zero UUID";
139 203
140 RegionData region = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 204 String reason = "Region overlaps another region";
141 if ((region != null) && (region.RegionID != regionInfos.RegionID)) 205 RegionData region = FindAnyConflictingRegion(regionInfos, scopeID, out reason);
206 // If there is a conflicting region, if it has the same ID and same coordinates
207 // then it is a region re-registering (permissions and ownership checked later).
208 if ((region != null)
209 && ( (region.coordX != regionInfos.RegionCoordX)
210 || (region.coordY != regionInfos.RegionCoordY)
211 || (region.RegionID != regionInfos.RegionID) )
212 )
142 { 213 {
143 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register in coordinates {1}, {2} which are already in use in scope {3}.", 214 // If not same ID and same coordinates, this new region has conflicts and can't be registered.
144 regionInfos.RegionID, regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID); 215 m_log.WarnFormat("{0} Register region conflict in scope {1}. {2}", LogHeader, scopeID, reason);
145 return "Region overlaps another region"; 216 return reason;
146 } 217 }
147 218
148 if (region != null) 219 if (region != null)
@@ -185,15 +256,15 @@ namespace OpenSim.Services.GridService
185 256
186 if (!m_AllowDuplicateNames) 257 if (!m_AllowDuplicateNames)
187 { 258 {
188 List<RegionData> dupe = m_Database.Get(regionInfos.RegionName, scopeID); 259 List<RegionData> dupe = m_Database.Get(Util.EscapeForLike(regionInfos.RegionName), scopeID);
189 if (dupe != null && dupe.Count > 0) 260 if (dupe != null && dupe.Count > 0)
190 { 261 {
191 foreach (RegionData d in dupe) 262 foreach (RegionData d in dupe)
192 { 263 {
193 if (d.RegionID != regionInfos.RegionID) 264 if (d.RegionID != regionInfos.RegionID)
194 { 265 {
195 m_log.WarnFormat("[GRID SERVICE]: Region {0} tried to register duplicate name with ID {1}.", 266 m_log.WarnFormat("[GRID SERVICE]: Region tried to register using a duplicate name. New region: {0} ({1}), existing region: {2} ({3}).",
196 regionInfos.RegionName, regionInfos.RegionID); 267 regionInfos.RegionName, regionInfos.RegionID, d.RegionName, d.RegionID);
197 return "Duplicate region name"; 268 return "Duplicate region name";
198 } 269 }
199 } 270 }
@@ -265,12 +336,121 @@ namespace OpenSim.Services.GridService
265 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e); 336 m_log.DebugFormat("[GRID SERVICE]: Database exception: {0}", e);
266 } 337 }
267 338
268 m_log.DebugFormat("[GRID SERVICE]: Region {0} ({1}) registered successfully at {2}-{3}", 339 m_log.InfoFormat
269 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionCoordX, regionInfos.RegionCoordY); 340 ("[GRID SERVICE]: Region {0} ({1}, {2}x{3}) registered at {4},{5} with flags {6}",
341 regionInfos.RegionName, regionInfos.RegionID, regionInfos.RegionSizeX, regionInfos.RegionSizeY,
342 regionInfos.RegionCoordX, regionInfos.RegionCoordY,
343 (OpenSim.Framework.RegionFlags)flags);
270 344
271 return String.Empty; 345 return String.Empty;
272 } 346 }
273 347
348 /// <summary>
349 /// Search the region map for regions conflicting with this region.
350 /// The region to be added is passed and we look for any existing regions that are
351 /// in the requested location, that are large varregions that overlap this region, or
352 /// are previously defined regions that would lie under this new region.
353 /// </summary>
354 /// <param name="regionInfos">Information on region requested to be added to the world map</param>
355 /// <param name="scopeID">Grid id for region</param>
356 /// <param name="reason">The reason the returned region conflicts with passed region</param>
357 /// <returns></returns>
358 private RegionData FindAnyConflictingRegion(GridRegion regionInfos, UUID scopeID, out string reason)
359 {
360 reason = "Reregistration";
361 // First see if there is an existing region right where this region is trying to go
362 // (We keep this result so it can be returned if suppressing errors)
363 RegionData noErrorRegion = m_Database.Get(regionInfos.RegionLocX, regionInfos.RegionLocY, scopeID);
364 RegionData region = noErrorRegion;
365 if (region != null
366 && region.RegionID == regionInfos.RegionID
367 && region.sizeX == regionInfos.RegionSizeX
368 && region.sizeY == regionInfos.RegionSizeY)
369 {
370 // If this seems to be exactly the same region, return this as it could be
371 // a re-registration (permissions checked by calling routine).
372 m_log.DebugFormat("{0} FindAnyConflictingRegion: re-register of {1}",
373 LogHeader, RegionString(regionInfos));
374 return region;
375 }
376
377 // No region exactly there or we're resizing an existing region.
378 // Fetch regions that could be varregions overlapping requested location.
379 int xmin = regionInfos.RegionLocX - (int)Constants.MaximumRegionSize + 10;
380 int xmax = regionInfos.RegionLocX;
381 int ymin = regionInfos.RegionLocY - (int)Constants.MaximumRegionSize + 10;
382 int ymax = regionInfos.RegionLocY;
383 List<RegionData> rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID);
384 foreach (RegionData rdata in rdatas)
385 {
386 // m_log.DebugFormat("{0} FindAnyConflictingRegion: find existing. Checking {1}", LogHeader, RegionString(rdata) );
387 if ( (rdata.posX + rdata.sizeX > regionInfos.RegionLocX)
388 && (rdata.posY + rdata.sizeY > regionInfos.RegionLocY) )
389 {
390 region = rdata;
391 m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of {1} by existing varregion {2}",
392 LogHeader, RegionString(regionInfos), RegionString(region));
393 reason = String.Format("Region location is overlapped by existing varregion {0}",
394 RegionString(region));
395
396 if (m_SuppressVarregionOverlapCheckOnRegistration)
397 region = noErrorRegion;
398 return region;
399 }
400 }
401
402 // There isn't a region that overlaps this potential region.
403 // See if this potential region overlaps an existing region.
404 // First, a shortcut of not looking for overlap if new region is legacy region sized
405 // and connot overlap anything.
406 if (regionInfos.RegionSizeX != Constants.RegionSize
407 || regionInfos.RegionSizeY != Constants.RegionSize)
408 {
409 // trim range looked for so we don't pick up neighbor regions just off the edges
410 xmin = regionInfos.RegionLocX;
411 xmax = regionInfos.RegionLocX + regionInfos.RegionSizeX - 10;
412 ymin = regionInfos.RegionLocY;
413 ymax = regionInfos.RegionLocY + regionInfos.RegionSizeY - 10;
414 rdatas = m_Database.Get(xmin, ymin, xmax, ymax, scopeID);
415
416 // If the region is being resized, the found region could be ourself.
417 foreach (RegionData rdata in rdatas)
418 {
419 // m_log.DebugFormat("{0} FindAnyConflictingRegion: see if overlap. Checking {1}", LogHeader, RegionString(rdata) );
420 if (region == null || region.RegionID != regionInfos.RegionID)
421 {
422 region = rdata;
423 m_log.WarnFormat("{0} FindAnyConflictingRegion: conflict of varregion {1} overlaps existing region {2}",
424 LogHeader, RegionString(regionInfos), RegionString(region));
425 reason = String.Format("Region {0} would overlap existing region {1}",
426 RegionString(regionInfos), RegionString(region));
427
428 if (m_SuppressVarregionOverlapCheckOnRegistration)
429 region = noErrorRegion;
430 return region;
431 }
432 }
433 }
434
435 // If we get here, region is either null (nothing found here) or
436 // is the non-conflicting region found at the location being requested.
437 return region;
438 }
439
440 // String describing name and region location of passed region
441 private String RegionString(RegionData reg)
442 {
443 return String.Format("{0}/{1} at <{2},{3}>",
444 reg.RegionName, reg.RegionID, reg.coordX, reg.coordY);
445 }
446
447 // String describing name and region location of passed region
448 private String RegionString(GridRegion reg)
449 {
450 return String.Format("{0}/{1} at <{2},{3}>",
451 reg.RegionName, reg.RegionID, reg.RegionCoordX, reg.RegionCoordY);
452 }
453
274 public bool DeregisterRegion(UUID regionID) 454 public bool DeregisterRegion(UUID regionID)
275 { 455 {
276 RegionData region = m_Database.Get(regionID, UUID.Zero); 456 RegionData region = m_Database.Get(regionID, UUID.Zero);
@@ -312,8 +492,10 @@ namespace OpenSim.Services.GridService
312 if (region != null) 492 if (region != null)
313 { 493 {
314 // Not really? Maybe? 494 // Not really? Maybe?
315 List<RegionData> rdatas = m_Database.Get(region.posX - (int)Constants.RegionSize - 1, region.posY - (int)Constants.RegionSize - 1, 495 // The adjacent regions are presumed to be the same size as the current region
316 region.posX + (int)Constants.RegionSize + 1, region.posY + (int)Constants.RegionSize + 1, scopeID); 496 List<RegionData> rdatas = m_Database.Get(
497 region.posX - region.sizeX - 1, region.posY - region.sizeY - 1,
498 region.posX + region.sizeX + 1, region.posY + region.sizeY + 1, scopeID);
317 499
318 foreach (RegionData rdata in rdatas) 500 foreach (RegionData rdata in rdatas)
319 { 501 {
@@ -325,7 +507,11 @@ namespace OpenSim.Services.GridService
325 } 507 }
326 } 508 }
327 509
328// m_log.DebugFormat("[GRID SERVICE]: region {0} has {1} neighbours", region.RegionName, rinfos.Count); 510 // string rNames = "";
511 // foreach (GridRegion gr in rinfos)
512 // rNames += gr.RegionName + ",";
513 // m_log.DebugFormat("{0} region {1} has {2} neighbours ({3})",
514 // LogHeader, region.RegionName, rinfos.Count, rNames);
329 } 515 }
330 else 516 else
331 { 517 {
@@ -346,20 +532,36 @@ namespace OpenSim.Services.GridService
346 return null; 532 return null;
347 } 533 }
348 534
535 // Get a region given its base coordinates.
536 // NOTE: this is NOT 'get a region by some point in the region'. The coordinate MUST
537 // be the base coordinate of the region.
538 // The snapping is technically unnecessary but is harmless because regions are always
539 // multiples of the legacy region size (256).
349 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y) 540 public GridRegion GetRegionByPosition(UUID scopeID, int x, int y)
350 { 541 {
351 int snapX = (int)(x / Constants.RegionSize) * (int)Constants.RegionSize; 542 uint regionX = Util.WorldToRegionLoc((uint)x);
352 int snapY = (int)(y / Constants.RegionSize) * (int)Constants.RegionSize; 543 uint regionY = Util.WorldToRegionLoc((uint)y);
544 int snapX = (int)Util.RegionToWorldLoc(regionX);
545 int snapY = (int)Util.RegionToWorldLoc(regionY);
546
353 RegionData rdata = m_Database.Get(snapX, snapY, scopeID); 547 RegionData rdata = m_Database.Get(snapX, snapY, scopeID);
354 if (rdata != null) 548 if (rdata != null)
549 {
550 m_log.DebugFormat("{0} GetRegionByPosition. Found region {1} in database. Pos=<{2},{3}>",
551 LogHeader, rdata.RegionName, regionX, regionY);
355 return RegionData2RegionInfo(rdata); 552 return RegionData2RegionInfo(rdata);
356 553 }
357 return null; 554 else
555 {
556 m_log.DebugFormat("{0} GetRegionByPosition. Did not find region in database. Pos=<{1},{2}>",
557 LogHeader, regionX, regionY);
558 return null;
559 }
358 } 560 }
359 561
360 public GridRegion GetRegionByName(UUID scopeID, string name) 562 public GridRegion GetRegionByName(UUID scopeID, string name)
361 { 563 {
362 List<RegionData> rdatas = m_Database.Get(name, scopeID); 564 List<RegionData> rdatas = m_Database.Get(Util.EscapeForLike(name), scopeID);
363 if ((rdatas != null) && (rdatas.Count > 0)) 565 if ((rdatas != null) && (rdatas.Count > 0))
364 return RegionData2RegionInfo(rdatas[0]); // get the first 566 return RegionData2RegionInfo(rdatas[0]); // get the first
365 567
@@ -377,7 +579,7 @@ namespace OpenSim.Services.GridService
377 { 579 {
378// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); 580// m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name);
379 581
380 List<RegionData> rdatas = m_Database.Get(name + "%", scopeID); 582 List<RegionData> rdatas = m_Database.Get(Util.EscapeForLike(name) + "%", scopeID);
381 583
382 int count = 0; 584 int count = 0;
383 List<GridRegion> rinfos = new List<GridRegion>(); 585 List<GridRegion> rinfos = new List<GridRegion>();
@@ -440,6 +642,8 @@ namespace OpenSim.Services.GridService
440 RegionData rdata = new RegionData(); 642 RegionData rdata = new RegionData();
441 rdata.posX = (int)rinfo.RegionLocX; 643 rdata.posX = (int)rinfo.RegionLocX;
442 rdata.posY = (int)rinfo.RegionLocY; 644 rdata.posY = (int)rinfo.RegionLocY;
645 rdata.sizeX = rinfo.RegionSizeX;
646 rdata.sizeY = rinfo.RegionSizeY;
443 rdata.RegionID = rinfo.RegionID; 647 rdata.RegionID = rinfo.RegionID;
444 rdata.RegionName = rinfo.RegionName; 648 rdata.RegionName = rinfo.RegionName;
445 rdata.Data = rinfo.ToKeyValuePairs(); 649 rdata.Data = rinfo.ToKeyValuePairs();
@@ -453,6 +657,8 @@ namespace OpenSim.Services.GridService
453 GridRegion rinfo = new GridRegion(rdata.Data); 657 GridRegion rinfo = new GridRegion(rdata.Data);
454 rinfo.RegionLocX = rdata.posX; 658 rinfo.RegionLocX = rdata.posX;
455 rinfo.RegionLocY = rdata.posY; 659 rinfo.RegionLocY = rdata.posY;
660 rinfo.RegionSizeX = rdata.sizeX;
661 rinfo.RegionSizeY = rdata.sizeY;
456 rinfo.RegionID = rdata.RegionID; 662 rinfo.RegionID = rdata.RegionID;
457 rinfo.RegionName = rdata.RegionName; 663 rinfo.RegionName = rdata.RegionName;
458 rinfo.ScopeID = rdata.ScopeID; 664 rinfo.ScopeID = rdata.ScopeID;
@@ -478,6 +684,33 @@ namespace OpenSim.Services.GridService
478 return ret; 684 return ret;
479 } 685 }
480 686
687 public List<GridRegion> GetDefaultHypergridRegions(UUID scopeID)
688 {
689 List<GridRegion> ret = new List<GridRegion>();
690
691 List<RegionData> regions = m_Database.GetDefaultHypergridRegions(scopeID);
692
693 foreach (RegionData r in regions)
694 {
695 if ((Convert.ToInt32(r.Data["flags"]) & (int)OpenSim.Framework.RegionFlags.RegionOnline) != 0)
696 ret.Add(RegionData2RegionInfo(r));
697 }
698
699 int hgDefaultRegionsFoundOnline = regions.Count;
700
701 // For now, hypergrid default regions will always be given precedence but we will also return simple default
702 // regions in case no specific hypergrid regions are specified.
703 ret.AddRange(GetDefaultRegions(scopeID));
704
705 int normalDefaultRegionsFoundOnline = ret.Count - hgDefaultRegionsFoundOnline;
706
707 m_log.DebugFormat(
708 "[GRID SERVICE]: GetDefaultHypergridRegions returning {0} hypergrid default and {1} normal default regions",
709 hgDefaultRegionsFoundOnline, normalDefaultRegionsFoundOnline);
710
711 return ret;
712 }
713
481 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y) 714 public List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y)
482 { 715 {
483 List<GridRegion> ret = new List<GridRegion>(); 716 List<GridRegion> ret = new List<GridRegion>();
@@ -526,40 +759,41 @@ namespace OpenSim.Services.GridService
526 759
527 private void HandleDeregisterRegion(string module, string[] cmd) 760 private void HandleDeregisterRegion(string module, string[] cmd)
528 { 761 {
529 if (cmd.Length != 4) 762 if (cmd.Length < 4)
530 { 763 {
531 MainConsole.Instance.Output("Syntax: degregister region id <Region UUID>"); 764 MainConsole.Instance.Output("Usage: degregister region id <region-id>+");
532 return; 765 return;
533 } 766 }
534 767
535 string rawRegionUuid = cmd[3]; 768 for (int i = 3; i < cmd.Length; i++)
536 UUID regionUuid;
537
538 if (!UUID.TryParse(rawRegionUuid, out regionUuid))
539 { 769 {
540 MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid); 770 string rawRegionUuid = cmd[i];
541 return; 771 UUID regionUuid;
542 }
543 772
544 GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid); 773 if (!UUID.TryParse(rawRegionUuid, out regionUuid))
774 {
775 MainConsole.Instance.OutputFormat("{0} is not a valid region uuid", rawRegionUuid);
776 return;
777 }
545 778
546 if (region == null) 779 GridRegion region = GetRegionByUUID(UUID.Zero, regionUuid);
547 {
548 MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid);
549 return;
550 }
551 780
552 if (DeregisterRegion(regionUuid)) 781 if (region == null)
553 { 782 {
554 MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid); 783 MainConsole.Instance.OutputFormat("No region with UUID {0}", regionUuid);
555 } 784 return;
556 else 785 }
557 {
558 // I don't think this can ever occur if we know that the region exists.
559 MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid);
560 }
561 786
562 return; 787 if (DeregisterRegion(regionUuid))
788 {
789 MainConsole.Instance.OutputFormat("Deregistered {0} {1}", region.RegionName, regionUuid);
790 }
791 else
792 {
793 // I don't think this can ever occur if we know that the region exists.
794 MainConsole.Instance.OutputFormat("Error deregistering {0} {1}", region.RegionName, regionUuid);
795 }
796 }
563 } 797 }
564 798
565 private void HandleShowRegions(string module, string[] cmd) 799 private void HandleShowRegions(string module, string[] cmd)
@@ -575,6 +809,27 @@ namespace OpenSim.Services.GridService
575 OutputRegionsToConsoleSummary(regions); 809 OutputRegionsToConsoleSummary(regions);
576 } 810 }
577 811
812 private void HandleShowGridSize(string module, string[] cmd)
813 {
814 List<RegionData> regions = m_Database.Get(int.MinValue, int.MinValue, int.MaxValue, int.MaxValue, UUID.Zero);
815
816 double size = 0;
817
818 foreach (RegionData region in regions)
819 {
820 int flags = Convert.ToInt32(region.Data["flags"]);
821
822 if ((flags & (int)Framework.RegionFlags.Hyperlink) == 0)
823 size += region.sizeX * region.sizeY;
824 }
825
826 MainConsole.Instance.Output("This is a very rough approximation.");
827 MainConsole.Instance.Output("Although it will not count regions that are actually links to others over the Hypergrid, ");
828 MainConsole.Instance.Output("it will count regions that are inactive but were not deregistered from the grid service");
829 MainConsole.Instance.Output("(e.g. simulator crashed rather than shutting down cleanly).\n");
830
831 MainConsole.Instance.OutputFormat("Grid size: {0} km squared.", size / 1000000);
832 }
578 833
579 private void HandleShowRegion(string module, string[] cmd) 834 private void HandleShowRegion(string module, string[] cmd)
580 { 835 {
@@ -586,7 +841,7 @@ namespace OpenSim.Services.GridService
586 841
587 string regionName = cmd[3]; 842 string regionName = cmd[3];
588 843
589 List<RegionData> regions = m_Database.Get(regionName, UUID.Zero); 844 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(regionName), UUID.Zero);
590 if (regions == null || regions.Count < 1) 845 if (regions == null || regions.Count < 1)
591 { 846 {
592 MainConsole.Instance.Output("No region with name {0} found", regionName); 847 MainConsole.Instance.Output("No region with name {0} found", regionName);
@@ -604,20 +859,20 @@ namespace OpenSim.Services.GridService
604 return; 859 return;
605 } 860 }
606 861
607 int x, y; 862 uint x, y;
608 if (!int.TryParse(cmd[3], out x)) 863 if (!uint.TryParse(cmd[3], out x))
609 { 864 {
610 MainConsole.Instance.Output("x-coord must be an integer"); 865 MainConsole.Instance.Output("x-coord must be an integer");
611 return; 866 return;
612 } 867 }
613 868
614 if (!int.TryParse(cmd[4], out y)) 869 if (!uint.TryParse(cmd[4], out y))
615 { 870 {
616 MainConsole.Instance.Output("y-coord must be an integer"); 871 MainConsole.Instance.Output("y-coord must be an integer");
617 return; 872 return;
618 } 873 }
619 874
620 RegionData region = m_Database.Get(x * (int)Constants.RegionSize, y * (int)Constants.RegionSize, UUID.Zero); 875 RegionData region = m_Database.Get((int)Util.RegionToWorldLoc(x), (int)Util.RegionToWorldLoc(y), UUID.Zero);
621 if (region == null) 876 if (region == null)
622 { 877 {
623 MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y); 878 MainConsole.Instance.OutputFormat("No region found at {0},{1}", x, y);
@@ -634,7 +889,8 @@ namespace OpenSim.Services.GridService
634 ConsoleDisplayList dispList = new ConsoleDisplayList(); 889 ConsoleDisplayList dispList = new ConsoleDisplayList();
635 dispList.AddRow("Region Name", r.RegionName); 890 dispList.AddRow("Region Name", r.RegionName);
636 dispList.AddRow("Region ID", r.RegionID); 891 dispList.AddRow("Region ID", r.RegionID);
637 dispList.AddRow("Location", string.Format("{0},{1}", r.coordX, r.coordY)); 892 dispList.AddRow("Position", string.Format("{0},{1}", r.coordX, r.coordY));
893 dispList.AddRow("Size", string.Format("{0}x{1}", r.sizeX, r.sizeY));
638 dispList.AddRow("URI", r.Data["serverURI"]); 894 dispList.AddRow("URI", r.Data["serverURI"]);
639 dispList.AddRow("Owner ID", r.Data["owner_uuid"]); 895 dispList.AddRow("Owner ID", r.Data["owner_uuid"]);
640 dispList.AddRow("Flags", flags); 896 dispList.AddRow("Flags", flags);
@@ -651,10 +907,10 @@ namespace OpenSim.Services.GridService
651 private void OutputRegionsToConsoleSummary(List<RegionData> regions) 907 private void OutputRegionsToConsoleSummary(List<RegionData> regions)
652 { 908 {
653 ConsoleDisplayTable dispTable = new ConsoleDisplayTable(); 909 ConsoleDisplayTable dispTable = new ConsoleDisplayTable();
654 dispTable.AddColumn("Name", 16); 910 dispTable.AddColumn("Name", 44);
655 dispTable.AddColumn("ID", 36); 911 dispTable.AddColumn("ID", 36);
656 dispTable.AddColumn("Position", 11); 912 dispTable.AddColumn("Position", 11);
657 dispTable.AddColumn("Owner ID", 36); 913 dispTable.AddColumn("Size", 11);
658 dispTable.AddColumn("Flags", 60); 914 dispTable.AddColumn("Flags", 60);
659 915
660 foreach (RegionData r in regions) 916 foreach (RegionData r in regions)
@@ -664,7 +920,7 @@ namespace OpenSim.Services.GridService
664 r.RegionName, 920 r.RegionName,
665 r.RegionID.ToString(), 921 r.RegionID.ToString(),
666 string.Format("{0},{1}", r.coordX, r.coordY), 922 string.Format("{0},{1}", r.coordX, r.coordY),
667 r.Data["owner_uuid"].ToString(), 923 string.Format("{0}x{1}", r.sizeX, r.sizeY),
668 flags.ToString()); 924 flags.ToString());
669 } 925 }
670 926
@@ -716,7 +972,7 @@ namespace OpenSim.Services.GridService
716 return; 972 return;
717 } 973 }
718 974
719 List<RegionData> regions = m_Database.Get(cmd[3], UUID.Zero); 975 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(cmd[3]), UUID.Zero);
720 if (regions == null || regions.Count < 1) 976 if (regions == null || regions.Count < 1)
721 { 977 {
722 MainConsole.Instance.Output("Region not found"); 978 MainConsole.Instance.Output("Region not found");
@@ -734,5 +990,18 @@ namespace OpenSim.Services.GridService
734 m_Database.Store(r); 990 m_Database.Store(r);
735 } 991 }
736 } 992 }
993
994 /// <summary>
995 /// Gets the grid extra service URls we wish for the region to send in OpenSimExtras to dynamically refresh
996 /// parameters in the viewer used to access services like map, search and destination guides.
997 /// <para>see "SimulatorFeaturesModule" </para>
998 /// </summary>
999 /// <returns>
1000 /// The grid extra service URls.
1001 /// </returns>
1002 public Dictionary<string,object> GetExtraFeatures()
1003 {
1004 return m_ExtraFeatures;
1005 }
737 } 1006 }
738} 1007}
diff --git a/OpenSim/Services/GridService/HypergridLinker.cs b/OpenSim/Services/GridService/HypergridLinker.cs
index 7abed20..9d016fc 100644
--- a/OpenSim/Services/GridService/HypergridLinker.cs
+++ b/OpenSim/Services/GridService/HypergridLinker.cs
@@ -47,7 +47,7 @@ using OpenMetaverse;
47 47
48namespace OpenSim.Services.GridService 48namespace OpenSim.Services.GridService
49{ 49{
50 public class HypergridLinker 50 public class HypergridLinker : IHypergridLinker
51 { 51 {
52 private static readonly ILog m_log = 52 private static readonly ILog m_log =
53 LogManager.GetLogger( 53 LogManager.GetLogger(
@@ -63,14 +63,11 @@ namespace OpenSim.Services.GridService
63 protected GatekeeperServiceConnector m_GatekeeperConnector; 63 protected GatekeeperServiceConnector m_GatekeeperConnector;
64 64
65 protected UUID m_ScopeID = UUID.Zero; 65 protected UUID m_ScopeID = UUID.Zero;
66// protected bool m_Check4096 = true;
66 protected string m_MapTileDirectory = string.Empty; 67 protected string m_MapTileDirectory = string.Empty;
67 protected string m_ThisGatekeeper = string.Empty; 68 protected string m_ThisGatekeeper = string.Empty;
68 protected Uri m_ThisGatekeeperURI = null; 69 protected Uri m_ThisGatekeeperURI = null;
69 70
70 // Hyperlink regions are hyperlinks on the map
71 public readonly Dictionary<UUID, GridRegion> m_HyperlinkRegions = new Dictionary<UUID, GridRegion>();
72 protected Dictionary<UUID, ulong> m_HyperlinkHandles = new Dictionary<UUID, ulong>();
73
74 protected GridRegion m_DefaultRegion; 71 protected GridRegion m_DefaultRegion;
75 protected GridRegion DefaultRegion 72 protected GridRegion DefaultRegion
76 { 73 {
@@ -78,7 +75,7 @@ namespace OpenSim.Services.GridService
78 { 75 {
79 if (m_DefaultRegion == null) 76 if (m_DefaultRegion == null)
80 { 77 {
81 List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID); 78 List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
82 if (defs != null && defs.Count > 0) 79 if (defs != null && defs.Count > 0)
83 m_DefaultRegion = defs[0]; 80 m_DefaultRegion = defs[0];
84 else 81 else
@@ -123,9 +120,14 @@ namespace OpenSim.Services.GridService
123 if (scope != string.Empty) 120 if (scope != string.Empty)
124 UUID.TryParse(scope, out m_ScopeID); 121 UUID.TryParse(scope, out m_ScopeID);
125 122
123// m_Check4096 = gridConfig.GetBoolean("Check4096", true);
124
126 m_MapTileDirectory = gridConfig.GetString("MapTileDirectory", "maptiles"); 125 m_MapTileDirectory = gridConfig.GetString("MapTileDirectory", "maptiles");
127 126
128 m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", string.Empty); 127 m_ThisGatekeeper = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
128 new string[] { "Startup", "Hypergrid", "GridService" }, String.Empty);
129 // Legacy. Remove soon!
130 m_ThisGatekeeper = gridConfig.GetString("Gatekeeper", m_ThisGatekeeper);
129 try 131 try
130 { 132 {
131 m_ThisGatekeeperURI = new Uri(m_ThisGatekeeper); 133 m_ThisGatekeeperURI = new Uri(m_ThisGatekeeper);
@@ -154,18 +156,18 @@ namespace OpenSim.Services.GridService
154 156
155 if (MainConsole.Instance != null) 157 if (MainConsole.Instance != null)
156 { 158 {
157 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region", 159 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-region",
158 "link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]", 160 "link-region <Xloc> <Yloc> <ServerURI> [<RemoteRegionName>]",
159 "Link a HyperGrid Region. Examples for <ServerURI>: http://grid.net:8002/ or http://example.org/path/foo.php", RunCommand); 161 "Link a HyperGrid Region. Examples for <ServerURI>: http://grid.net:8002/ or http://example.org/path/foo.php", RunCommand);
160 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region", 162 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-region",
161 "link-region <Xloc> <Yloc> <RegionIP> <RegionPort> [<RemoteRegionName>]", 163 "link-region <Xloc> <Yloc> <RegionIP> <RegionPort> [<RemoteRegionName>]",
162 "Link a hypergrid region (deprecated)", RunCommand); 164 "Link a hypergrid region (deprecated)", RunCommand);
163 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "unlink-region", 165 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "unlink-region",
164 "unlink-region <local name>", 166 "unlink-region <local name>",
165 "Unlink a hypergrid region", RunCommand); 167 "Unlink a hypergrid region", RunCommand);
166 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-mapping", "link-mapping [<x> <y>]", 168 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "link-mapping", "link-mapping [<x> <y>]",
167 "Set local coordinate to map HG regions to", RunCommand); 169 "Set local coordinate to map HG regions to", RunCommand);
168 MainConsole.Instance.Commands.AddCommand("hypergrid", false, "show hyperlinks", "show hyperlinks", 170 MainConsole.Instance.Commands.AddCommand("Hypergrid", false, "show hyperlinks", "show hyperlinks",
169 "List the HG regions", HandleShow); 171 "List the HG regions", HandleShow);
170 } 172 }
171 } 173 }
@@ -177,14 +179,14 @@ namespace OpenSim.Services.GridService
177 public GridRegion LinkRegion(UUID scopeID, string regionDescriptor) 179 public GridRegion LinkRegion(UUID scopeID, string regionDescriptor)
178 { 180 {
179 string reason = string.Empty; 181 string reason = string.Empty;
180 int xloc = random.Next(0, Int16.MaxValue) * (int)Constants.RegionSize; 182 uint xloc = Util.RegionToWorldLoc((uint)random.Next(0, Int16.MaxValue));
181 return TryLinkRegionToCoords(scopeID, regionDescriptor, xloc, 0, out reason); 183 return TryLinkRegionToCoords(scopeID, regionDescriptor, (int)xloc, 0, out reason);
182 } 184 }
183 185
184 private static Random random = new Random(); 186 private static Random random = new Random();
185 187
186 // From the command line link-region (obsolete) and the map 188 // From the command line link-region (obsolete) and the map
187 public GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason) 189 private GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, out string reason)
188 { 190 {
189 return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason); 191 return TryLinkRegionToCoords(scopeID, mapName, xloc, yloc, UUID.Zero, out reason);
190 } 192 }
@@ -194,24 +196,36 @@ namespace OpenSim.Services.GridService
194 reason = string.Empty; 196 reason = string.Empty;
195 GridRegion regInfo = null; 197 GridRegion regInfo = null;
196 198
199 mapName = mapName.Trim();
200
197 if (!mapName.StartsWith("http")) 201 if (!mapName.StartsWith("http"))
198 { 202 {
199 string host = "127.0.0.1"; 203 // Formats: grid.example.com:8002:region name
200 string portstr; 204 // grid.example.com:region name
205 // grid.example.com:8002
206 // grid.example.com
207
208 string host;
209 uint port = 80;
201 string regionName = ""; 210 string regionName = "";
202 uint port = 0; 211
203 string[] parts = mapName.Split(new char[] { ':' }); 212 string[] parts = mapName.Split(new char[] { ':' });
204 if (parts.Length >= 1) 213
214 if (parts.Length == 0)
205 { 215 {
206 host = parts[0]; 216 reason = "Wrong format for link-region";
217 return null;
207 } 218 }
219
220 host = parts[0];
221
208 if (parts.Length >= 2) 222 if (parts.Length >= 2)
209 { 223 {
210 portstr = parts[1]; 224 // If it's a number then assume it's a port. Otherwise, it's a region name.
211 //m_log.Debug("-- port = " + portstr); 225 if (!UInt32.TryParse(parts[1], out port))
212 if (!UInt32.TryParse(portstr, out port))
213 regionName = parts[1]; 226 regionName = parts[1];
214 } 227 }
228
215 // always take the last one 229 // always take the last one
216 if (parts.Length >= 3) 230 if (parts.Length >= 3)
217 { 231 {
@@ -228,14 +242,30 @@ namespace OpenSim.Services.GridService
228 } 242 }
229 else 243 else
230 { 244 {
231 string[] parts = mapName.Split(new char[] {' '}); 245 // Formats: http://grid.example.com region name
232 string regionName = String.Empty; 246 // http://grid.example.com "region name"
233 if (parts.Length > 1) 247 // http://grid.example.com
248
249 string serverURI;
250 string regionName = "";
251
252 string[] parts = mapName.Split(new char[] { ' ' });
253
254 if (parts.Length == 0)
234 { 255 {
235 regionName = mapName.Substring(parts[0].Length + 1); 256 reason = "Wrong format for link-region";
236 regionName = regionName.Trim(new char[] {'"'}); 257 return null;
237 } 258 }
238 if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, parts[0], ownerID, out regInfo, out reason)) 259
260 serverURI = parts[0];
261
262 if (parts.Length >= 2)
263 {
264 regionName = mapName.Substring(serverURI.Length);
265 regionName = regionName.Trim(new char[] { '"', ' ' });
266 }
267
268 if (TryCreateLink(scopeID, xloc, yloc, regionName, 0, null, serverURI, ownerID, out regInfo, out reason))
239 { 269 {
240 regInfo.RegionName = mapName; 270 regInfo.RegionName = mapName;
241 return regInfo; 271 return regInfo;
@@ -244,31 +274,39 @@ namespace OpenSim.Services.GridService
244 274
245 return null; 275 return null;
246 } 276 }
247 277
248 public bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason) 278 private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, UUID ownerID, out GridRegion regInfo, out string reason)
249 { 279 {
250 return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason); 280 return TryCreateLink(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, null, ownerID, out regInfo, out reason);
251 } 281 }
252 282
253 public bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason) 283 private bool TryCreateLink(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason)
254 { 284 {
255 m_log.DebugFormat("[HYPERGRID LINKER]: Link to {0} {1}, in {2}-{3}", 285 lock (this)
286 {
287 return TryCreateLinkImpl(scopeID, xloc, yloc, remoteRegionName, externalPort, externalHostName, serverURI, ownerID, out regInfo, out reason);
288 }
289 }
290
291 private bool TryCreateLinkImpl(UUID scopeID, int xloc, int yloc, string remoteRegionName, uint externalPort, string externalHostName, string serverURI, UUID ownerID, out GridRegion regInfo, out string reason)
292 {
293 m_log.InfoFormat("[HYPERGRID LINKER]: Link to {0} {1}, in <{2},{3}>",
256 ((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI), 294 ((serverURI == null) ? (externalHostName + ":" + externalPort) : serverURI),
257 remoteRegionName, xloc / Constants.RegionSize, yloc / Constants.RegionSize); 295 remoteRegionName, Util.WorldToRegionLoc((uint)xloc), Util.WorldToRegionLoc((uint)yloc));
258 296
259 reason = string.Empty; 297 reason = string.Empty;
260 Uri uri = null; 298 Uri uri = null;
261 299
262 regInfo = new GridRegion(); 300 regInfo = new GridRegion();
263 if ( externalPort > 0) 301 if (externalPort > 0)
264 regInfo.HttpPort = externalPort; 302 regInfo.HttpPort = externalPort;
265 else 303 else
266 regInfo.HttpPort = 0; 304 regInfo.HttpPort = 80;
267 if ( externalHostName != null) 305 if (externalHostName != null)
268 regInfo.ExternalHostName = externalHostName; 306 regInfo.ExternalHostName = externalHostName;
269 else 307 else
270 regInfo.ExternalHostName = "0.0.0.0"; 308 regInfo.ExternalHostName = "0.0.0.0";
271 if ( serverURI != null) 309 if (serverURI != null)
272 { 310 {
273 regInfo.ServerURI = serverURI; 311 regInfo.ServerURI = serverURI;
274 try 312 try
@@ -280,7 +318,7 @@ namespace OpenSim.Services.GridService
280 catch {} 318 catch {}
281 } 319 }
282 320
283 if ( remoteRegionName != string.Empty ) 321 if (remoteRegionName != string.Empty)
284 regInfo.RegionName = remoteRegionName; 322 regInfo.RegionName = remoteRegionName;
285 323
286 regInfo.RegionLocX = xloc; 324 regInfo.RegionLocX = xloc;
@@ -293,6 +331,7 @@ namespace OpenSim.Services.GridService
293 { 331 {
294 if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port) 332 if (regInfo.ExternalHostName == m_ThisGatekeeperURI.Host && regInfo.HttpPort == m_ThisGatekeeperURI.Port)
295 { 333 {
334 m_log.InfoFormat("[HYPERGRID LINKER]: Cannot hyperlink to regions on the same grid");
296 reason = "Cannot hyperlink to regions on the same grid"; 335 reason = "Cannot hyperlink to regions on the same grid";
297 return false; 336 return false;
298 } 337 }
@@ -304,8 +343,8 @@ namespace OpenSim.Services.GridService
304 GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY); 343 GridRegion region = m_GridService.GetRegionByPosition(regInfo.ScopeID, regInfo.RegionLocX, regInfo.RegionLocY);
305 if (region != null) 344 if (region != null)
306 { 345 {
307 m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates {0}-{1} are already occupied by region {2} with uuid {3}", 346 m_log.WarnFormat("[HYPERGRID LINKER]: Coordinates <{0},{1}> are already occupied by region {2} with uuid {3}",
308 regInfo.RegionLocX / Constants.RegionSize, regInfo.RegionLocY / Constants.RegionSize, 347 Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY),
309 region.RegionName, region.RegionID); 348 region.RegionName, region.RegionID);
310 reason = "Coordinates are already in use"; 349 reason = "Coordinates are already in use";
311 return false; 350 return false;
@@ -340,12 +379,25 @@ namespace OpenSim.Services.GridService
340 region = m_GridService.GetRegionByUUID(scopeID, regionID); 379 region = m_GridService.GetRegionByUUID(scopeID, regionID);
341 if (region != null) 380 if (region != null)
342 { 381 {
343 m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates {0} {1}", 382 m_log.DebugFormat("[HYPERGRID LINKER]: Region already exists in coordinates <{0},{1}>",
344 region.RegionLocX / Constants.RegionSize, region.RegionLocY / Constants.RegionSize); 383 Util.WorldToRegionLoc((uint)region.RegionLocX), Util.WorldToRegionLoc((uint)region.RegionLocY));
345 regInfo = region; 384 regInfo = region;
346 return true; 385 return true;
347 } 386 }
348 387
388 // We are now performing this check for each individual teleport in the EntityTransferModule instead. This
389 // allows us to give better feedback when teleports fail because of the distance reason (which can't be
390 // done here) and it also hypergrid teleports that are within range (possibly because the source grid
391 // itself has regions that are very far apart).
392// uint x, y;
393// if (m_Check4096 && !Check4096(handle, out x, out y))
394// {
395// //RemoveHyperlinkRegion(regInfo.RegionID);
396// reason = "Region is too far (" + x + ", " + y + ")";
397// m_log.Info("[HYPERGRID LINKER]: Unable to link, region is too far (" + x + ", " + y + ")");
398// //return false;
399// }
400
349 regInfo.RegionID = regionID; 401 regInfo.RegionID = regionID;
350 402
351 if (externalName == string.Empty) 403 if (externalName == string.Empty)
@@ -362,7 +414,8 @@ namespace OpenSim.Services.GridService
362 regInfo.RegionSecret = handle.ToString(); 414 regInfo.RegionSecret = handle.ToString();
363 415
364 AddHyperlinkRegion(regInfo, handle); 416 AddHyperlinkRegion(regInfo, handle);
365 m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} with image {1}", regInfo.RegionName, regInfo.TerrainImage); 417 m_log.InfoFormat("[HYPERGRID LINKER]: Successfully linked to region {0} at <{1},{2}> with image {3}",
418 regInfo.RegionName, Util.WorldToRegionLoc((uint)regInfo.RegionLocX), Util.WorldToRegionLoc((uint)regInfo.RegionLocY), regInfo.TerrainImage);
366 return true; 419 return true;
367 } 420 }
368 421
@@ -371,7 +424,7 @@ namespace OpenSim.Services.GridService
371 m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName); 424 m_log.DebugFormat("[HYPERGRID LINKER]: Request to unlink {0}", mapName);
372 GridRegion regInfo = null; 425 GridRegion regInfo = null;
373 426
374 List<RegionData> regions = m_Database.Get(mapName, m_ScopeID); 427 List<RegionData> regions = m_Database.Get(Util.EscapeForLike(mapName), m_ScopeID);
375 if (regions != null && regions.Count > 0) 428 if (regions != null && regions.Count > 0)
376 { 429 {
377 OpenSim.Framework.RegionFlags rflags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]); 430 OpenSim.Framework.RegionFlags rflags = (OpenSim.Framework.RegionFlags)Convert.ToInt32(regions[0].Data["flags"]);
@@ -395,6 +448,52 @@ namespace OpenSim.Services.GridService
395 } 448 }
396 } 449 }
397 450
451// Not currently used
452// /// <summary>
453// /// Cope with this viewer limitation.
454// /// </summary>
455// /// <param name="regInfo"></param>
456// /// <returns></returns>
457// public bool Check4096(ulong realHandle, out uint x, out uint y)
458// {
459// uint ux = 0, uy = 0;
460// Utils.LongToUInts(realHandle, out ux, out uy);
461// x = Util.WorldToRegionLoc(ux);
462// y = Util.WorldToRegionLoc(uy);
463//
464// const uint limit = Util.RegionToWorldLoc(4096 - 1);
465// uint xmin = ux - limit;
466// uint xmax = ux + limit;
467// uint ymin = uy - limit;
468// uint ymax = uy + limit;
469// // World map boundary checks
470// if (xmin < 0 || xmin > ux)
471// xmin = 0;
472// if (xmax > int.MaxValue || xmax < ux)
473// xmax = int.MaxValue;
474// if (ymin < 0 || ymin > uy)
475// ymin = 0;
476// if (ymax > int.MaxValue || ymax < uy)
477// ymax = int.MaxValue;
478//
479// // Check for any regions that are within the possible teleport range to the linked region
480// List<GridRegion> regions = m_GridService.GetRegionRange(m_ScopeID, (int)xmin, (int)xmax, (int)ymin, (int)ymax);
481// if (regions.Count == 0)
482// {
483// return false;
484// }
485// else
486// {
487// // Check for regions which are not linked regions
488// List<GridRegion> hyperlinks = m_GridService.GetHyperlinks(m_ScopeID);
489// IEnumerable<GridRegion> availableRegions = regions.Except(hyperlinks);
490// if (availableRegions.Count() == 0)
491// return false;
492// }
493//
494// return true;
495// }
496
398 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle) 497 private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle)
399 { 498 {
400 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo); 499 RegionData rdata = m_GridService.RegionInfo2RegionData(regionInfo);
@@ -437,9 +536,14 @@ namespace OpenSim.Services.GridService
437 MainConsole.Instance.Output(new string('-', 72)); 536 MainConsole.Instance.Output(new string('-', 72));
438 foreach (RegionData r in regions) 537 foreach (RegionData r in regions)
439 { 538 {
440 MainConsole.Instance.Output(String.Format("{0}\n{2,-32} {1}\n", 539 MainConsole.Instance.Output(
441 r.RegionName, r.RegionID, String.Format("{0},{1} ({2},{3})", r.posX, r.posY, 540 String.Format("{0}\n{2,-32} {1}\n",
442 r.posX / Constants.RegionSize, r.posY / Constants.RegionSize))); 541 r.RegionName, r.RegionID,
542 String.Format("{0},{1} ({2},{3})", r.posX, r.posY,
543 Util.WorldToRegionLoc((uint)r.posX), Util.WorldToRegionLoc((uint)r.posY)
544 )
545 )
546 );
443 } 547 }
444 return; 548 return;
445 } 549 }
@@ -464,8 +568,8 @@ namespace OpenSim.Services.GridService
464 int xloc, yloc; 568 int xloc, yloc;
465 string serverURI; 569 string serverURI;
466 string remoteName = null; 570 string remoteName = null;
467 xloc = Convert.ToInt32(cmdparams[0]) * (int)Constants.RegionSize; 571 xloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[0]));
468 yloc = Convert.ToInt32(cmdparams[1]) * (int)Constants.RegionSize; 572 yloc = (int)Util.RegionToWorldLoc((uint)Convert.ToInt32(cmdparams[1]));
469 serverURI = cmdparams[2]; 573 serverURI = cmdparams[2];
470 if (cmdparams.Length > 3) 574 if (cmdparams.Length > 3)
471 remoteName = string.Join(" ", cmdparams, 3, cmdparams.Length - 3); 575 remoteName = string.Join(" ", cmdparams, 3, cmdparams.Length - 3);
@@ -536,13 +640,13 @@ namespace OpenSim.Services.GridService
536 { 640 {
537 // old format 641 // old format
538 GridRegion regInfo; 642 GridRegion regInfo;
539 int xloc, yloc; 643 uint xloc, yloc;
540 uint externalPort; 644 uint externalPort;
541 string externalHostName; 645 string externalHostName;
542 try 646 try
543 { 647 {
544 xloc = Convert.ToInt32(cmdparams[0]); 648 xloc = Convert.ToUInt32(cmdparams[0]);
545 yloc = Convert.ToInt32(cmdparams[1]); 649 yloc = Convert.ToUInt32(cmdparams[1]);
546 externalPort = Convert.ToUInt32(cmdparams[3]); 650 externalPort = Convert.ToUInt32(cmdparams[3]);
547 externalHostName = cmdparams[2]; 651 externalHostName = cmdparams[2];
548 //internalPort = Convert.ToUInt32(cmdparams[4]); 652 //internalPort = Convert.ToUInt32(cmdparams[4]);
@@ -556,10 +660,11 @@ namespace OpenSim.Services.GridService
556 } 660 }
557 661
558 // Convert cell coordinates given by the user to meters 662 // Convert cell coordinates given by the user to meters
559 xloc = xloc * (int)Constants.RegionSize; 663 xloc = Util.RegionToWorldLoc(xloc);
560 yloc = yloc * (int)Constants.RegionSize; 664 yloc = Util.RegionToWorldLoc(yloc);
561 string reason = string.Empty; 665 string reason = string.Empty;
562 if (TryCreateLink(UUID.Zero, xloc, yloc, string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason)) 666 if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc,
667 string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
563 { 668 {
564 // What is this? The GridRegion instance will be discarded anyway, 669 // What is this? The GridRegion instance will be discarded anyway,
565 // which effectively ignores any local name given with the command. 670 // which effectively ignores any local name given with the command.
@@ -639,13 +744,13 @@ namespace OpenSim.Services.GridService
639 private void ReadLinkFromConfig(IConfig config) 744 private void ReadLinkFromConfig(IConfig config)
640 { 745 {
641 GridRegion regInfo; 746 GridRegion regInfo;
642 int xloc, yloc; 747 uint xloc, yloc;
643 uint externalPort; 748 uint externalPort;
644 string externalHostName; 749 string externalHostName;
645 uint realXLoc, realYLoc; 750 uint realXLoc, realYLoc;
646 751
647 xloc = Convert.ToInt32(config.GetString("xloc", "0")); 752 xloc = Convert.ToUInt32(config.GetString("xloc", "0"));
648 yloc = Convert.ToInt32(config.GetString("yloc", "0")); 753 yloc = Convert.ToUInt32(config.GetString("yloc", "0"));
649 externalPort = Convert.ToUInt32(config.GetString("externalPort", "0")); 754 externalPort = Convert.ToUInt32(config.GetString("externalPort", "0"));
650 externalHostName = config.GetString("externalHostName", ""); 755 externalHostName = config.GetString("externalHostName", "");
651 realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0")); 756 realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0"));
@@ -653,18 +758,19 @@ namespace OpenSim.Services.GridService
653 758
654 if (m_enableAutoMapping) 759 if (m_enableAutoMapping)
655 { 760 {
656 xloc = (int)((xloc % 100) + m_autoMappingX); 761 xloc = (xloc % 100) + m_autoMappingX;
657 yloc = (int)((yloc % 100) + m_autoMappingY); 762 yloc = (yloc % 100) + m_autoMappingY;
658 } 763 }
659 764
660 if (((realXLoc == 0) && (realYLoc == 0)) || 765 if (((realXLoc == 0) && (realYLoc == 0)) ||
661 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) && 766 (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) &&
662 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896)))) 767 ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896))))
663 { 768 {
664 xloc = xloc * (int)Constants.RegionSize; 769 xloc = Util.RegionToWorldLoc(xloc);
665 yloc = yloc * (int)Constants.RegionSize; 770 yloc = Util.RegionToWorldLoc(yloc);
666 string reason = string.Empty; 771 string reason = string.Empty;
667 if (TryCreateLink(UUID.Zero, xloc, yloc, string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason)) 772 if (TryCreateLink(UUID.Zero, (int)xloc, (int)yloc,
773 string.Empty, externalPort, externalHostName, UUID.Zero, out regInfo, out reason))
668 { 774 {
669 regInfo.RegionName = config.GetString("localName", ""); 775 regInfo.RegionName = config.GetString("localName", "");
670 } 776 }
diff --git a/OpenSim/Services/GridService/Properties/AssemblyInfo.cs b/OpenSim/Services/GridService/Properties/AssemblyInfo.cs
index 5c0c8f4..0841e5a 100644
--- a/OpenSim/Services/GridService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/GridService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs
index 7b84d55..8e10125 100644
--- a/OpenSim/Services/HypergridService/GatekeeperService.cs
+++ b/OpenSim/Services/HypergridService/GatekeeperService.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -58,6 +58,7 @@ namespace OpenSim.Services.HypergridService
58 private static IUserAgentService m_UserAgentService; 58 private static IUserAgentService m_UserAgentService;
59 private static ISimulationService m_SimulationService; 59 private static ISimulationService m_SimulationService;
60 private static IGridUserService m_GridUserService; 60 private static IGridUserService m_GridUserService;
61 private static IBansService m_BansService;
61 62
62 private static string m_AllowedClients = string.Empty; 63 private static string m_AllowedClients = string.Empty;
63 private static string m_DeniedClients = string.Empty; 64 private static string m_DeniedClients = string.Empty;
@@ -87,6 +88,7 @@ namespace OpenSim.Services.HypergridService
87 string presenceService = serverConfig.GetString("PresenceService", String.Empty); 88 string presenceService = serverConfig.GetString("PresenceService", String.Empty);
88 string simulationService = serverConfig.GetString("SimulationService", String.Empty); 89 string simulationService = serverConfig.GetString("SimulationService", String.Empty);
89 string gridUserService = serverConfig.GetString("GridUserService", String.Empty); 90 string gridUserService = serverConfig.GetString("GridUserService", String.Empty);
91 string bansService = serverConfig.GetString("BansService", String.Empty);
90 92
91 // These are mandatory, the others aren't 93 // These are mandatory, the others aren't
92 if (gridService == string.Empty || presenceService == string.Empty) 94 if (gridService == string.Empty || presenceService == string.Empty)
@@ -96,7 +98,9 @@ namespace OpenSim.Services.HypergridService
96 UUID.TryParse(scope, out m_ScopeID); 98 UUID.TryParse(scope, out m_ScopeID);
97 //m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!"); 99 //m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!");
98 m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean("AllowTeleportsToAnyRegion", true); 100 m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean("AllowTeleportsToAnyRegion", true);
99 m_ExternalName = serverConfig.GetString("ExternalName", string.Empty); 101 m_ExternalName = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
102 new string[] { "Startup", "Hypergrid", "GatekeeperService" }, String.Empty);
103 m_ExternalName = serverConfig.GetString("ExternalName", m_ExternalName);
100 if (m_ExternalName != string.Empty && !m_ExternalName.EndsWith("/")) 104 if (m_ExternalName != string.Empty && !m_ExternalName.EndsWith("/"))
101 m_ExternalName = m_ExternalName + "/"; 105 m_ExternalName = m_ExternalName + "/";
102 106
@@ -119,14 +123,19 @@ namespace OpenSim.Services.HypergridService
119 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(homeUsersService, args); 123 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(homeUsersService, args);
120 if (gridUserService != string.Empty) 124 if (gridUserService != string.Empty)
121 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args); 125 m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
126 if (bansService != string.Empty)
127 m_BansService = ServerUtils.LoadPlugin<IBansService>(bansService, args);
122 128
123 if (simService != null) 129 if (simService != null)
124 m_SimulationService = simService; 130 m_SimulationService = simService;
125 else if (simulationService != string.Empty) 131 else if (simulationService != string.Empty)
126 m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args); 132 m_SimulationService = ServerUtils.LoadPlugin<ISimulationService>(simulationService, args);
127 133
128 m_AllowedClients = serverConfig.GetString("AllowedClients", string.Empty); 134 string[] possibleAccessControlConfigSections = new string[] { "AccessControl", "GatekeeperService" };
129 m_DeniedClients = serverConfig.GetString("DeniedClients", string.Empty); 135 m_AllowedClients = Util.GetConfigVarFromSections<string>(
136 config, "AllowedClients", possibleAccessControlConfigSections, string.Empty);
137 m_DeniedClients = Util.GetConfigVarFromSections<string>(
138 config, "DeniedClients", possibleAccessControlConfigSections, string.Empty);
130 m_ForeignAgentsAllowed = serverConfig.GetBoolean("ForeignAgentsAllowed", true); 139 m_ForeignAgentsAllowed = serverConfig.GetBoolean("ForeignAgentsAllowed", true);
131 140
132 LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_ForeignsAllowedExceptions); 141 LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_ForeignsAllowedExceptions);
@@ -165,7 +174,7 @@ namespace OpenSim.Services.HypergridService
165 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName); 174 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to link to {0}", (regionName == string.Empty)? "default region" : regionName);
166 if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty) 175 if (!m_AllowTeleportsToAnyRegion || regionName == string.Empty)
167 { 176 {
168 List<GridRegion> defs = m_GridService.GetDefaultRegions(m_ScopeID); 177 List<GridRegion> defs = m_GridService.GetDefaultHypergridRegions(m_ScopeID);
169 if (defs != null && defs.Count > 0) 178 if (defs != null && defs.Count > 0)
170 { 179 {
171 region = defs[0]; 180 region = defs[0];
@@ -198,41 +207,75 @@ namespace OpenSim.Services.HypergridService
198 return true; 207 return true;
199 } 208 }
200 209
201 public GridRegion GetHyperlinkRegion(UUID regionID) 210 public GridRegion GetHyperlinkRegion(UUID regionID, UUID agentID, string agentHomeURI, out string message)
202 { 211 {
203 m_log.DebugFormat("[GATEKEEPER SERVICE]: Request to get hyperlink region {0}", regionID); 212 message = null;
204 213
205 if (!m_AllowTeleportsToAnyRegion) 214 if (!m_AllowTeleportsToAnyRegion)
215 {
206 // Don't even check the given regionID 216 // Don't even check the given regionID
217 m_log.DebugFormat(
218 "[GATEKEEPER SERVICE]: Returning gateway region {0} {1} @ {2} to user {3}{4} as teleporting to arbitrary regions is not allowed.",
219 m_DefaultGatewayRegion.RegionName,
220 m_DefaultGatewayRegion.RegionID,
221 m_DefaultGatewayRegion.ServerURI,
222 agentID,
223 agentHomeURI == null ? "" : " @ " + agentHomeURI);
224
225 message = "Teleporting to the default region.";
207 return m_DefaultGatewayRegion; 226 return m_DefaultGatewayRegion;
227 }
208 228
209 GridRegion region = m_GridService.GetRegionByUUID(m_ScopeID, regionID); 229 GridRegion region = m_GridService.GetRegionByUUID(m_ScopeID, regionID);
230
231 if (region == null)
232 {
233 m_log.DebugFormat(
234 "[GATEKEEPER SERVICE]: Could not find region with ID {0} as requested by user {1}{2}. Returning null.",
235 regionID, agentID, (agentHomeURI == null) ? "" : " @ " + agentHomeURI);
236
237 message = "The teleport destination could not be found.";
238 return null;
239 }
240
241 m_log.DebugFormat(
242 "[GATEKEEPER SERVICE]: Returning region {0} {1} @ {2} to user {3}{4}.",
243 region.RegionName,
244 region.RegionID,
245 region.ServerURI,
246 agentID,
247 agentHomeURI == null ? "" : " @ " + agentHomeURI);
248
210 return region; 249 return region;
211 } 250 }
212 251
213 #region Login Agent 252 #region Login Agent
214 public bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason) 253 public bool LoginAgent(GridRegion source, AgentCircuitData aCircuit, GridRegion destination, out string reason)
215 { 254 {
216 reason = string.Empty; 255 reason = string.Empty;
217 256
218 string authURL = string.Empty; 257 string authURL = string.Empty;
219 if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) 258 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
220 authURL = aCircuit.ServiceURLs["HomeURI"].ToString(); 259 authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
221 m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9} Teleport Flags {10}", 260
222 aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionName, 261 m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}, Teleport Flags: {10}. From region {11}",
223 aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0, aCircuit.teleportFlags.ToString()); 262 aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionID,
224 263 aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0, (TeleportFlags)aCircuit.teleportFlags,
264 (source == null) ? "Unknown" : string.Format("{0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI));
265
266 string curViewer = Util.GetViewerName(aCircuit);
267
225 // 268 //
226 // Check client 269 // Check client
227 // 270 //
228 if (m_AllowedClients != string.Empty) 271 if (m_AllowedClients != string.Empty)
229 { 272 {
230 Regex arx = new Regex(m_AllowedClients); 273 Regex arx = new Regex(m_AllowedClients);
231 Match am = arx.Match(aCircuit.Viewer); 274 Match am = arx.Match(curViewer);
232 275
233 if (!am.Success) 276 if (!am.Success)
234 { 277 {
235 m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed", aCircuit.Viewer); 278 m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed", curViewer);
236 return false; 279 return false;
237 } 280 }
238 } 281 }
@@ -240,11 +283,11 @@ namespace OpenSim.Services.HypergridService
240 if (m_DeniedClients != string.Empty) 283 if (m_DeniedClients != string.Empty)
241 { 284 {
242 Regex drx = new Regex(m_DeniedClients); 285 Regex drx = new Regex(m_DeniedClients);
243 Match dm = drx.Match(aCircuit.Viewer); 286 Match dm = drx.Match(curViewer);
244 287
245 if (dm.Success) 288 if (dm.Success)
246 { 289 {
247 m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied", aCircuit.Viewer); 290 m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied", curViewer);
248 return false; 291 return false;
249 } 292 }
250 } 293 }
@@ -285,17 +328,16 @@ namespace OpenSim.Services.HypergridService
285 } 328 }
286 } 329 }
287 } 330 }
288 m_log.DebugFormat("[GATEKEEPER SERVICE]: User is ok");
289 331
290 // 332 //
291 // Foreign agents allowed? Exceptions? 333 // Foreign agents allowed? Exceptions?
292 // 334 //
293 if (account == null) 335 if (account == null)
294 { 336 {
295 bool allowed = m_ForeignAgentsAllowed; 337 bool allowed = m_ForeignAgentsAllowed;
296 338
297 if (m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsAllowedExceptions)) 339 if (m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsAllowedExceptions))
298 allowed = false; 340 allowed = false;
299 341
300 if (!m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsDisallowedExceptions)) 342 if (!m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsDisallowedExceptions))
301 allowed = true; 343 allowed = true;
@@ -309,6 +351,20 @@ namespace OpenSim.Services.HypergridService
309 } 351 }
310 } 352 }
311 353
354 //
355 // Is the user banned?
356 // This uses a Ban service that's more powerful than the configs
357 //
358 string uui = (account != null ? aCircuit.AgentID.ToString() : Util.ProduceUserUniversalIdentifier(aCircuit));
359 if (m_BansService != null && m_BansService.IsBanned(uui, aCircuit.IPAddress, aCircuit.Id0, authURL))
360 {
361 reason = "You are banned from this world";
362 m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: user {0} is banned", uui);
363 return false;
364 }
365
366 m_log.DebugFormat("[GATEKEEPER SERVICE]: User {0} is ok", aCircuit.Name);
367
312 bool isFirstLogin = false; 368 bool isFirstLogin = false;
313 // 369 //
314 // Login the presence, if it's not there yet (by the login service) 370 // Login the presence, if it's not there yet (by the login service)
@@ -326,7 +382,8 @@ namespace OpenSim.Services.HypergridService
326 aCircuit.firstname, aCircuit.lastname); 382 aCircuit.firstname, aCircuit.lastname);
327 return false; 383 return false;
328 } 384 }
329 m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence ok"); 385
386 m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence {0} is ok", aCircuit.Name);
330 387
331 // Also login foreigners with GridUser service 388 // Also login foreigners with GridUser service
332 if (m_GridUserService != null && account == null) 389 if (m_GridUserService != null && account == null)
@@ -357,7 +414,9 @@ namespace OpenSim.Services.HypergridService
357 reason = "Destination region not found"; 414 reason = "Destination region not found";
358 return false; 415 return false;
359 } 416 }
360 m_log.DebugFormat("[GATEKEEPER SERVICE]: destination ok: {0}", destination.RegionName); 417
418 m_log.DebugFormat(
419 "[GATEKEEPER SERVICE]: Destination {0} is ok for {1}", destination.RegionName, aCircuit.Name);
361 420
362 // 421 //
363 // Adjust the visible name 422 // Adjust the visible name
@@ -374,7 +433,7 @@ namespace OpenSim.Services.HypergridService
374 try 433 try
375 { 434 {
376 Uri uri = new Uri(aCircuit.ServiceURLs["HomeURI"].ToString()); 435 Uri uri = new Uri(aCircuit.ServiceURLs["HomeURI"].ToString());
377 aCircuit.lastname = "@" + uri.Host; // + ":" + uri.Port; 436 aCircuit.lastname = "@" + uri.Authority;
378 } 437 }
379 catch 438 catch
380 { 439 {
@@ -391,8 +450,16 @@ namespace OpenSim.Services.HypergridService
391 // Preserve our TeleportFlags we have gathered so-far 450 // Preserve our TeleportFlags we have gathered so-far
392 loginFlag |= (Constants.TeleportFlags) aCircuit.teleportFlags; 451 loginFlag |= (Constants.TeleportFlags) aCircuit.teleportFlags;
393 452
394 m_log.DebugFormat("[GATEKEEPER SERVICE]: launching agent {0}", loginFlag); 453 m_log.DebugFormat("[GATEKEEPER SERVICE]: Launching {0}, Teleport Flags: {1}", aCircuit.Name, loginFlag);
395 return m_SimulationService.CreateAgent(destination, aCircuit, (uint)loginFlag, out reason); 454
455 EntityTransferContext ctx = new EntityTransferContext();
456
457 if (!m_SimulationService.QueryAccess(
458 destination, aCircuit.AgentID, aCircuit.ServiceURLs["HomeURI"].ToString(),
459 true, aCircuit.startpos, new List<UUID>(), ctx, out reason))
460 return false;
461
462 return m_SimulationService.CreateAgent(source, destination, aCircuit, (uint)loginFlag, out reason);
396 } 463 }
397 464
398 protected bool Authenticate(AgentCircuitData aCircuit) 465 protected bool Authenticate(AgentCircuitData aCircuit)
@@ -400,6 +467,12 @@ namespace OpenSim.Services.HypergridService
400 if (!CheckAddress(aCircuit.ServiceSessionID)) 467 if (!CheckAddress(aCircuit.ServiceSessionID))
401 return false; 468 return false;
402 469
470 if (string.IsNullOrEmpty(aCircuit.IPAddress))
471 {
472 m_log.DebugFormat("[GATEKEEPER SERVICE]: Agent did not provide a client IP address.");
473 return false;
474 }
475
403 string userURL = string.Empty; 476 string userURL = string.Empty;
404 if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) 477 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
405 userURL = aCircuit.ServiceURLs["HomeURI"].ToString(); 478 userURL = aCircuit.ServiceURLs["HomeURI"].ToString();
diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs
index 84dec8d..b83fb1e 100644
--- a/OpenSim/Services/HypergridService/HGAssetService.cs
+++ b/OpenSim/Services/HypergridService/HGAssetService.cs
@@ -76,10 +76,10 @@ namespace OpenSim.Services.HypergridService
76 if (m_UserAccountService == null) 76 if (m_UserAccountService == null)
77 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); 77 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
78 78
79 // legacy configuration [obsolete] 79 m_HomeURL = Util.GetConfigVarFromSections<string>(config, "HomeURI",
80 m_HomeURL = assetConfig.GetString("ProfileServerURI", string.Empty); 80 new string[] { "Startup", "Hypergrid", configName }, string.Empty);
81 // Preferred 81 if (m_HomeURL == string.Empty)
82 m_HomeURL = assetConfig.GetString("HomeURI", m_HomeURL); 82 throw new Exception("[HGAssetService] No HomeURI specified");
83 83
84 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); 84 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
85 85
@@ -100,7 +100,7 @@ namespace OpenSim.Services.HypergridService
100 return null; 100 return null;
101 101
102 if (asset.Metadata.Type == (sbyte)AssetType.Object) 102 if (asset.Metadata.Type == (sbyte)AssetType.Object)
103 asset.Data = AdjustIdentifiers(asset.Data); ; 103 asset.Data = AdjustIdentifiers(asset.Data);
104 104
105 AdjustIdentifiers(asset.Metadata); 105 AdjustIdentifiers(asset.Metadata);
106 106
@@ -129,6 +129,14 @@ namespace OpenSim.Services.HypergridService
129 if (!m_AssetPerms.AllowedExport(asset.Type)) 129 if (!m_AssetPerms.AllowedExport(asset.Type))
130 return null; 130 return null;
131 131
132 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
133 // Fix bad assets before sending them elsewhere
134 if (asset.Type == (int)AssetType.Object && asset.Data != null)
135 {
136 string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(asset.Data));
137 asset.Data = Utils.StringToBytes(xml);
138 }
139
132 return asset.Data; 140 return asset.Data;
133 } 141 }
134 142
@@ -139,6 +147,14 @@ namespace OpenSim.Services.HypergridService
139 if (!m_AssetPerms.AllowedImport(asset.Type)) 147 if (!m_AssetPerms.AllowedImport(asset.Type))
140 return string.Empty; 148 return string.Empty;
141 149
150 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
151 // Fix bad assets before storing on this server
152 if (asset.Type == (int)AssetType.Object && asset.Data != null)
153 {
154 string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(asset.Data));
155 asset.Data = Utils.StringToBytes(xml);
156 }
157
142 return base.Store(asset); 158 return base.Store(asset);
143 } 159 }
144 160
@@ -160,10 +176,16 @@ namespace OpenSim.Services.HypergridService
160 meta.CreatorID = meta.CreatorID + ";" + m_HomeURL + "/" + creator.FirstName + " " + creator.LastName; 176 meta.CreatorID = meta.CreatorID + ";" + m_HomeURL + "/" + creator.FirstName + " " + creator.LastName;
161 } 177 }
162 178
179 // Only for Object
163 protected byte[] AdjustIdentifiers(byte[] data) 180 protected byte[] AdjustIdentifiers(byte[] data)
164 { 181 {
165 string xml = Utils.BytesToString(data); 182 string xml = Utils.BytesToString(data);
166 return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, m_HomeURL, m_Cache, UUID.Zero)); 183
184 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
185 // Fix bad assets before sending them elsewhere
186 xml = ExternalRepresentationUtils.SanitizeXml(xml);
187
188 return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, "HGAssetService", m_HomeURL, m_Cache, UUID.Zero));
167 } 189 }
168 190
169 } 191 }
diff --git a/OpenSim/Services/HypergridService/HGFSAssetService.cs b/OpenSim/Services/HypergridService/HGFSAssetService.cs
new file mode 100644
index 0000000..54e8ccb
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGFSAssetService.cs
@@ -0,0 +1,189 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Reflection;
29
30using Nini.Config;
31using log4net;
32using OpenMetaverse;
33
34using OpenSim.Framework;
35using OpenSim.Framework.Serialization.External;
36using OpenSim.Server.Base;
37using OpenSim.Services.Interfaces;
38using OpenSim.Services.FSAssetService;
39
40namespace OpenSim.Services.HypergridService
41{
42 /// <summary>
43 /// Hypergrid asset service. It serves the IAssetService interface,
44 /// but implements it in ways that are appropriate for inter-grid
45 /// asset exchanges. This version is for FSAssets.
46 /// </summary>
47 public class HGFSAssetService : FSAssetConnector, IAssetService
48 {
49 private static readonly ILog m_log =
50 LogManager.GetLogger(
51 MethodBase.GetCurrentMethod().DeclaringType);
52
53 private string m_HomeURL;
54 private IUserAccountService m_UserAccountService;
55
56 private UserAccountCache m_Cache;
57
58 private AssetPermissions m_AssetPerms;
59
60 public HGFSAssetService(IConfigSource config, string configName) : base(config, "AssetService")
61 {
62 m_log.Debug("[HGAsset Service]: Starting in FSAsset mode");
63 IConfig assetConfig = config.Configs[configName];
64 if (assetConfig == null)
65 throw new Exception("No HGAssetService configuration");
66
67 string userAccountsDll = assetConfig.GetString("UserAccountsService", string.Empty);
68 if (userAccountsDll == string.Empty)
69 throw new Exception("Please specify UserAccountsService in HGAssetService configuration");
70
71 Object[] args = new Object[] { config };
72 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountsDll, args);
73 if (m_UserAccountService == null)
74 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
75
76 m_HomeURL = Util.GetConfigVarFromSections<string>(config, "HomeURI",
77 new string[] { "Startup", "Hypergrid", configName }, string.Empty);
78 if (m_HomeURL == string.Empty)
79 throw new Exception("[HGAssetService] No HomeURI specified");
80
81 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
82
83 // Permissions
84 m_AssetPerms = new AssetPermissions(assetConfig);
85 }
86
87 #region IAssetService overrides
88 public override AssetBase Get(string id)
89 {
90 AssetBase asset = base.Get(id);
91
92 if (asset == null)
93 return null;
94
95 if (!m_AssetPerms.AllowedExport(asset.Type))
96 return null;
97
98 if (asset.Metadata.Type == (sbyte)AssetType.Object)
99 asset.Data = AdjustIdentifiers(asset.Data);
100
101 AdjustIdentifiers(asset.Metadata);
102
103 return asset;
104 }
105
106 public override AssetMetadata GetMetadata(string id)
107 {
108 AssetMetadata meta = base.GetMetadata(id);
109
110 if (meta == null)
111 return null;
112
113 AdjustIdentifiers(meta);
114
115 return meta;
116 }
117
118 public override byte[] GetData(string id)
119 {
120 AssetBase asset = Get(id);
121
122 if (asset == null)
123 return null;
124
125 if (!m_AssetPerms.AllowedExport(asset.Type))
126 return null;
127
128 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
129 // Fix bad assets before sending them elsewhere
130 if (asset.Type == (int)AssetType.Object && asset.Data != null)
131 {
132 string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(asset.Data));
133 asset.Data = Utils.StringToBytes(xml);
134 }
135
136 return asset.Data;
137 }
138
139 //public virtual bool Get(string id, Object sender, AssetRetrieved handler)
140
141 public override string Store(AssetBase asset)
142 {
143 if (!m_AssetPerms.AllowedImport(asset.Type))
144 return string.Empty;
145
146 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
147 // Fix bad assets before storing on this server
148 if (asset.Type == (int)AssetType.Object && asset.Data != null)
149 {
150 string xml = ExternalRepresentationUtils.SanitizeXml(Utils.BytesToString(asset.Data));
151 asset.Data = Utils.StringToBytes(xml);
152 }
153
154 return base.Store(asset);
155 }
156
157 public override bool Delete(string id)
158 {
159 // NOGO
160 return false;
161 }
162
163 #endregion
164
165 protected void AdjustIdentifiers(AssetMetadata meta)
166 {
167 if (meta == null || m_Cache == null)
168 return;
169
170 UserAccount creator = m_Cache.GetUser(meta.CreatorID);
171 if (creator != null)
172 meta.CreatorID = meta.CreatorID + ";" + m_HomeURL + "/" + creator.FirstName + " " + creator.LastName;
173 }
174
175 // Only for Object
176 protected byte[] AdjustIdentifiers(byte[] data)
177 {
178 string xml = Utils.BytesToString(data);
179
180 // Deal with bug introduced in Oct. 20 (1eb3e6cc43e2a7b4053bc1185c7c88e22356c5e8)
181 // Fix bad assets before sending them elsewhere
182 xml = ExternalRepresentationUtils.SanitizeXml(xml);
183
184 return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, "HGAssetService", m_HomeURL, m_Cache, UUID.Zero));
185 }
186
187 }
188
189}
diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs
index a8bcfb2..6e35a88 100644
--- a/OpenSim/Services/HypergridService/HGFriendsService.cs
+++ b/OpenSim/Services/HypergridService/HGFriendsService.cs
@@ -198,7 +198,8 @@ namespace OpenSim.Services.HypergridService
198 // So let's send back the call, but start a thread to continue 198 // So let's send back the call, but start a thread to continue
199 // with the verification and the actual action. 199 // with the verification and the actual action.
200 200
201 Util.FireAndForget(delegate { ProcessFriendshipOffered(fromID, fromName, toID, message); }); 201 Util.FireAndForget(
202 o => ProcessFriendshipOffered(fromID, fromName, toID, message), null, "HGFriendsService.ProcessFriendshipOffered");
202 203
203 return true; 204 return true;
204 } 205 }
diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs
index e8d7cca..32ca09a 100644
--- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs
+++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs
@@ -101,7 +101,14 @@ namespace OpenSim.Services.HypergridService
101 Object[] args = new Object[] { config }; 101 Object[] args = new Object[] { config };
102 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args); 102 m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args);
103 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args); 103 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args);
104 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(userAgentService, args); 104 try
105 {
106 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(userAgentService, args);
107 }
108 catch
109 {
110 m_log.WarnFormat("[HG IM SERVICE]: Unable to create User Agent Service. Missing config var in [HGInstantMessageService]?");
111 }
105 112
106 m_RegionCache = new ExpiringCache<UUID, GridRegion>(); 113 m_RegionCache = new ExpiringCache<UUID, GridRegion>();
107 114
@@ -215,7 +222,15 @@ namespace OpenSim.Services.HypergridService
215 { 222 {
216 // Let's check with the UAS if the user is elsewhere 223 // Let's check with the UAS if the user is elsewhere
217 m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service"); 224 m_log.DebugFormat("[HG IM SERVICE]: User is not present. Checking location with User Agent service");
218 url = m_UserAgentService.LocateUser(toAgentID); 225 try
226 {
227 url = m_UserAgentService.LocateUser(toAgentID);
228 }
229 catch (Exception e)
230 {
231 m_log.Warn("[HG IM SERVICE]: LocateUser call failed ", e);
232 url = string.Empty;
233 }
219 } 234 }
220 235
221 // check if we've tried this before.. 236 // check if we've tried this before..
diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs
index 2e9bd40..9158b41 100644
--- a/OpenSim/Services/HypergridService/HGInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGInventoryService.cs
@@ -81,10 +81,8 @@ namespace OpenSim.Services.HypergridService
81 if (m_UserAccountService == null) 81 if (m_UserAccountService == null)
82 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll)); 82 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
83 83
84 // legacy configuration [obsolete] 84 m_HomeURL = Util.GetConfigVarFromSections<string>(config, "HomeURI",
85 m_HomeURL = invConfig.GetString("ProfileServerURI", string.Empty); 85 new string[] { "Startup", "Hypergrid", m_ConfigName }, String.Empty);
86 // Preferred
87 m_HomeURL = invConfig.GetString("HomeURI", m_HomeURL);
88 86
89 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); 87 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
90 } 88 }
@@ -105,12 +103,6 @@ namespace OpenSim.Services.HypergridService
105 return new List<InventoryFolderBase>(); 103 return new List<InventoryFolderBase>();
106 } 104 }
107 105
108 public override InventoryCollection GetUserInventory(UUID userID)
109 {
110 // NOGO for this inventory service
111 return null;
112 }
113
114 public override InventoryFolderBase GetRootFolder(UUID principalID) 106 public override InventoryFolderBase GetRootFolder(UUID principalID)
115 { 107 {
116 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID); 108 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetRootFolder for {0}", principalID);
@@ -123,7 +115,7 @@ namespace OpenSim.Services.HypergridService
123 return ConvertToOpenSim(folders[0]); 115 return ConvertToOpenSim(folders[0]);
124 116
125 // make one 117 // make one
126 XInventoryFolder suitcase = CreateFolder(principalID, UUID.Zero, (int)AssetType.Folder, "My Suitcase"); 118 XInventoryFolder suitcase = CreateFolder(principalID, UUID.Zero, (int)FolderType.Suitcase, "My Suitcase");
127 return ConvertToOpenSim(suitcase); 119 return ConvertToOpenSim(suitcase);
128 } 120 }
129 121
@@ -149,7 +141,7 @@ namespace OpenSim.Services.HypergridService
149 //} 141 //}
150 142
151 143
152 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 144 public override InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
153 { 145 {
154 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type); 146 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type);
155 return GetRootFolder(principalID); 147 return GetRootFolder(principalID);
@@ -161,7 +153,14 @@ namespace OpenSim.Services.HypergridService
161 //public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) 153 //public InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
162 //{ 154 //{
163 //} 155 //}
164 156
157 // NOGO
158 //
159 public override InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderID)
160 {
161 return new InventoryCollection[0];
162 }
163
165 //public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) 164 //public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
166 //{ 165 //{
167 //} 166 //}
@@ -300,7 +299,7 @@ namespace OpenSim.Services.HypergridService
300 UserAccount user = m_Cache.GetUser(it.CreatorId); 299 UserAccount user = m_Cache.GetUser(it.CreatorId);
301 300
302 // Adjust the creator data 301 // Adjust the creator data
303 if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty)) 302 if (user != null && it != null && string.IsNullOrEmpty(it.CreatorData))
304 it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName; 303 it.CreatorData = m_HomeURL + ";" + user.FirstName + " " + user.LastName;
305 } 304 }
306 return it; 305 return it;
diff --git a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
index 784f136..40eb6d4 100644
--- a/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
+++ b/OpenSim/Services/HypergridService/HGSuitcaseInventoryService.cs
@@ -54,7 +54,7 @@ namespace OpenSim.Services.HypergridService
54 LogManager.GetLogger( 54 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType); 55 MethodBase.GetCurrentMethod().DeclaringType);
56 56
57 private string m_HomeURL; 57// private string m_HomeURL;
58 private IUserAccountService m_UserAccountService; 58 private IUserAccountService m_UserAccountService;
59 private IAvatarService m_AvatarService; 59 private IAvatarService m_AvatarService;
60 60
@@ -96,8 +96,8 @@ namespace OpenSim.Services.HypergridService
96 if (m_AvatarService == null) 96 if (m_AvatarService == null)
97 throw new Exception(String.Format("Unable to create m_AvatarService from {0}", avatarDll)); 97 throw new Exception(String.Format("Unable to create m_AvatarService from {0}", avatarDll));
98 98
99 // Preferred 99// m_HomeURL = Util.GetConfigVarFromSections<string>(config, "HomeURI",
100 m_HomeURL = invConfig.GetString("HomeURI", m_HomeURL); 100// new string[] { "Startup", "Hypergrid", m_ConfigName }, String.Empty);
101 101
102// m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService); 102// m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
103 } 103 }
@@ -115,8 +115,14 @@ namespace OpenSim.Services.HypergridService
115 { 115 {
116 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); 116 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
117 117
118 if (suitcase == null)
119 {
120 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Found no suitcase folder for user {0} when looking for inventory skeleton", principalID);
121 return null;
122 }
123
118 List<XInventoryFolder> tree = GetFolderTree(principalID, suitcase.folderID); 124 List<XInventoryFolder> tree = GetFolderTree(principalID, suitcase.folderID);
119 if (tree == null || (tree != null && tree.Count == 0)) 125 if (tree.Count == 0)
120 return null; 126 return null;
121 127
122 List<InventoryFolderBase> folders = new List<InventoryFolderBase>(); 128 List<InventoryFolderBase> folders = new List<InventoryFolderBase>();
@@ -131,58 +137,13 @@ namespace OpenSim.Services.HypergridService
131 return folders; 137 return folders;
132 } 138 }
133 139
134 public override InventoryCollection GetUserInventory(UUID userID)
135 {
136 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Get Suitcase inventory for user {0}", userID);
137 InventoryCollection userInventory = new InventoryCollection();
138 userInventory.UserID = userID;
139 userInventory.Folders = new List<InventoryFolderBase>();
140 userInventory.Items = new List<InventoryItemBase>();
141
142 XInventoryFolder suitcase = GetSuitcaseXFolder(userID);
143
144 List<XInventoryFolder> tree = GetFolderTree(userID, suitcase.folderID);
145 if (tree == null || (tree != null && tree.Count == 0))
146 {
147 SetAsNormalFolder(suitcase);
148 userInventory.Folders.Add(ConvertToOpenSim(suitcase));
149 return userInventory;
150 }
151
152 List<InventoryItemBase> items;
153 foreach (XInventoryFolder f in tree)
154 {
155 // Add the items of this subfolder
156 items = GetFolderItems(userID, f.folderID);
157 if (items != null && items.Count > 0)
158 {
159 userInventory.Items.AddRange(items);
160 }
161
162 // Add the folder itself
163 userInventory.Folders.Add(ConvertToOpenSim(f));
164 }
165
166 items = GetFolderItems(userID, suitcase.folderID);
167 if (items != null && items.Count > 0)
168 {
169 userInventory.Items.AddRange(items);
170 }
171
172 SetAsNormalFolder(suitcase);
173 userInventory.Folders.Add(ConvertToOpenSim(suitcase));
174
175 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetUserInventory for user {0} returning {1} folders and {2} items",
176 userID, userInventory.Folders.Count, userInventory.Items.Count);
177 return userInventory;
178 }
179
180 public override InventoryFolderBase GetRootFolder(UUID principalID) 140 public override InventoryFolderBase GetRootFolder(UUID principalID)
181 { 141 {
182 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetRootFolder for {0}", principalID); 142 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetRootFolder for {0}", principalID);
183 143
184 // Let's find out the local root folder 144 // Let's find out the local root folder
185 XInventoryFolder root = GetRootXFolder(principalID); ; 145 XInventoryFolder root = GetRootXFolder(principalID);
146
186 if (root == null) 147 if (root == null)
187 { 148 {
188 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve local root folder for user {0}", principalID); 149 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to retrieve local root folder for user {0}", principalID);
@@ -195,14 +156,15 @@ namespace OpenSim.Services.HypergridService
195 if (suitcase == null) 156 if (suitcase == null)
196 { 157 {
197 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder. Creating it...", principalID); 158 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder. Creating it...", principalID);
198 // make one, and let's add it to the user's inventory as a direct child of the root folder 159 // Create the My Suitcase folder under the user's root folder.
199 // In the DB we tag it as type 100, but we use -1 (Unknown) outside 160 // In the DB we tag it as type 100, but we use type 8 (Folder) outside, as this affects the sort order.
200 suitcase = CreateFolder(principalID, root.folderID, 100, "My Suitcase"); 161 suitcase = CreateFolder(principalID, root.folderID, (int)FolderType.Suitcase, InventoryFolderBase.SUITCASE_FOLDER_NAME);
201 if (suitcase == null) 162 if (suitcase == null)
163 {
202 m_log.ErrorFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to create suitcase folder"); 164 m_log.ErrorFormat("[HG SUITCASE INVENTORY SERVICE]: Unable to create suitcase folder");
203 m_Database.StoreFolder(suitcase); 165 return null;
166 }
204 167
205 // Create System folders
206 CreateSystemFolders(principalID, suitcase.folderID); 168 CreateSystemFolders(principalID, suitcase.folderID);
207 } 169 }
208 170
@@ -216,45 +178,51 @@ namespace OpenSim.Services.HypergridService
216 m_log.Debug("[HG SUITCASE INVENTORY SERVICE]: Creating System folders under Suitcase..."); 178 m_log.Debug("[HG SUITCASE INVENTORY SERVICE]: Creating System folders under Suitcase...");
217 XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootID); 179 XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootID);
218 180
219 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Animation) return true; return false; })) 181 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Animation) return true; return false; }))
220 CreateFolder(principalID, rootID, (int)AssetType.Animation, "Animations"); 182 CreateFolder(principalID, rootID, (int)FolderType.Animation, "Animations");
221 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Bodypart) return true; return false; })) 183 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.BodyPart) return true; return false; }))
222 CreateFolder(principalID, rootID, (int)AssetType.Bodypart, "Body Parts"); 184 CreateFolder(principalID, rootID, (int)FolderType.BodyPart, "Body Parts");
223 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.CallingCard) return true; return false; })) 185 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.CallingCard) return true; return false; }))
224 CreateFolder(principalID, rootID, (int)AssetType.CallingCard, "Calling Cards"); 186 CreateFolder(principalID, rootID, (int)FolderType.CallingCard, "Calling Cards");
225 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Clothing) return true; return false; })) 187 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Clothing) return true; return false; }))
226 CreateFolder(principalID, rootID, (int)AssetType.Clothing, "Clothing"); 188 CreateFolder(principalID, rootID, (int)FolderType.Clothing, "Clothing");
227 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Gesture) return true; return false; })) 189 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.CurrentOutfit) return true; return false; }))
228 CreateFolder(principalID, rootID, (int)AssetType.Gesture, "Gestures"); 190 CreateFolder(principalID, rootID, (int)FolderType.CurrentOutfit, "Current Outfit");
229 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Landmark) return true; return false; })) 191 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Favorites) return true; return false; }))
230 CreateFolder(principalID, rootID, (int)AssetType.Landmark, "Landmarks"); 192 CreateFolder(principalID, rootID, (int)FolderType.Favorites, "Favorites");
231 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.LostAndFoundFolder) return true; return false; })) 193 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Gesture) return true; return false; }))
232 CreateFolder(principalID, rootID, (int)AssetType.LostAndFoundFolder, "Lost And Found"); 194 CreateFolder(principalID, rootID, (int)FolderType.Gesture, "Gestures");
233 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Notecard) return true; return false; })) 195 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Landmark) return true; return false; }))
234 CreateFolder(principalID, rootID, (int)AssetType.Notecard, "Notecards"); 196 CreateFolder(principalID, rootID, (int)FolderType.Landmark, "Landmarks");
235 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Object) return true; return false; })) 197 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.LostAndFound) return true; return false; }))
236 CreateFolder(principalID, rootID, (int)AssetType.Object, "Objects"); 198 CreateFolder(principalID, rootID, (int)FolderType.LostAndFound, "Lost And Found");
237 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.SnapshotFolder) return true; return false; })) 199 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Notecard) return true; return false; }))
238 CreateFolder(principalID, rootID, (int)AssetType.SnapshotFolder, "Photo Album"); 200 CreateFolder(principalID, rootID, (int)FolderType.Notecard, "Notecards");
239 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.LSLText) return true; return false; })) 201 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Object) return true; return false; }))
240 CreateFolder(principalID, rootID, (int)AssetType.LSLText, "Scripts"); 202 CreateFolder(principalID, rootID, (int)FolderType.Object, "Objects");
241 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Sound) return true; return false; })) 203 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Snapshot) return true; return false; }))
242 CreateFolder(principalID, rootID, (int)AssetType.Sound, "Sounds"); 204 CreateFolder(principalID, rootID, (int)FolderType.Snapshot, "Photo Album");
243 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.Texture) return true; return false; })) 205 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.LSLText) return true; return false; }))
244 CreateFolder(principalID, rootID, (int)AssetType.Texture, "Textures"); 206 CreateFolder(principalID, rootID, (int)FolderType.LSLText, "Scripts");
245 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.TrashFolder) return true; return false; })) 207 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Sound) return true; return false; }))
246 CreateFolder(principalID, rootID, (int)AssetType.TrashFolder, "Trash"); 208 CreateFolder(principalID, rootID, (int)FolderType.Sound, "Sounds");
247 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.FavoriteFolder) return true; return false; })) 209 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Texture) return true; return false; }))
248 CreateFolder(principalID, rootID, (int)AssetType.FavoriteFolder, "Favorites"); 210 CreateFolder(principalID, rootID, (int)FolderType.Texture, "Textures");
249 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)AssetType.CurrentOutfitFolder) return true; return false; })) 211 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Trash) return true; return false; }))
250 CreateFolder(principalID, rootID, (int)AssetType.CurrentOutfitFolder, "Current Outfit"); 212 CreateFolder(principalID, rootID, (int)FolderType.Trash, "Trash");
251
252 } 213 }
253 214
254 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 215 public override InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
255 { 216 {
256 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type); 217 //m_log.DebugFormat("[HG INVENTORY SERVICE]: GetFolderForType for {0} {0}", principalID, type);
257 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); 218 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
219
220 if (suitcase == null)
221 {
222 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: Found no suitcase folder for user {0} when looking for child type folder {1}", principalID, type);
223 return null;
224 }
225
258 XInventoryFolder[] folders = m_Database.GetFolders( 226 XInventoryFolder[] folders = m_Database.GetFolders(
259 new string[] { "agentID", "type", "parentFolderID" }, 227 new string[] { "agentID", "type", "parentFolderID" },
260 new string[] { principalID.ToString(), ((int)type).ToString(), suitcase.folderID.ToString() }); 228 new string[] { principalID.ToString(), ((int)type).ToString(), suitcase.folderID.ToString() });
@@ -277,7 +245,10 @@ namespace OpenSim.Services.HypergridService
277 InventoryCollection coll = null; 245 InventoryCollection coll = null;
278 246
279 if (!IsWithinSuitcaseTree(principalID, folderID)) 247 if (!IsWithinSuitcaseTree(principalID, folderID))
248 {
249 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderContent: folder {0} (user {1}) is not within Suitcase tree", folderID, principalID);
280 return new InventoryCollection(); 250 return new InventoryCollection();
251 }
281 252
282 coll = base.GetFolderContent(principalID, folderID); 253 coll = base.GetFolderContent(principalID, folderID);
283 254
@@ -294,7 +265,10 @@ namespace OpenSim.Services.HypergridService
294 // Let's do a bit of sanity checking, more than the base service does 265 // Let's do a bit of sanity checking, more than the base service does
295 // make sure the given folder exists under the suitcase tree of this user 266 // make sure the given folder exists under the suitcase tree of this user
296 if (!IsWithinSuitcaseTree(principalID, folderID)) 267 if (!IsWithinSuitcaseTree(principalID, folderID))
268 {
269 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolderItems: folder {0} (user {1}) is not within Suitcase tree", folderID, principalID);
297 return new List<InventoryItemBase>(); 270 return new List<InventoryItemBase>();
271 }
298 272
299 return base.GetFolderItems(principalID, folderID); 273 return base.GetFolderItems(principalID, folderID);
300 } 274 }
@@ -306,7 +280,10 @@ namespace OpenSim.Services.HypergridService
306 // make sure the given folder's parent folder exists under the suitcase tree of this user 280 // make sure the given folder's parent folder exists under the suitcase tree of this user
307 281
308 if (!IsWithinSuitcaseTree(folder.Owner, folder.ParentID)) 282 if (!IsWithinSuitcaseTree(folder.Owner, folder.ParentID))
283 {
284 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddFolder: folder {0} (user {1}) is not within Suitcase tree", folder.ParentID, folder.Owner);
309 return false; 285 return false;
286 }
310 287
311 // OK, it's legit 288 // OK, it's legit
312 if (base.AddFolder(folder)) 289 if (base.AddFolder(folder))
@@ -326,7 +303,7 @@ namespace OpenSim.Services.HypergridService
326 //m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Update folder {0}, version {1}", folder.ID, folder.Version); 303 //m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Update folder {0}, version {1}", folder.ID, folder.Version);
327 if (!IsWithinSuitcaseTree(folder.Owner, folder.ID)) 304 if (!IsWithinSuitcaseTree(folder.Owner, folder.ID))
328 { 305 {
329 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: folder {0} not within Suitcase tree", folder.Name); 306 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: UpdateFolder: folder {0}/{1} (user {2}) is not within Suitcase tree", folder.Name, folder.ID, folder.Owner);
330 return false; 307 return false;
331 } 308 }
332 309
@@ -336,9 +313,17 @@ namespace OpenSim.Services.HypergridService
336 313
337 public override bool MoveFolder(InventoryFolderBase folder) 314 public override bool MoveFolder(InventoryFolderBase folder)
338 { 315 {
339 if (!IsWithinSuitcaseTree(folder.Owner, folder.ID) || 316 if (!IsWithinSuitcaseTree(folder.Owner, folder.ID))
340 !IsWithinSuitcaseTree(folder.Owner, folder.ParentID)) 317 {
318 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveFolder: folder {0} (user {1}) is not within Suitcase tree", folder.ID, folder.Owner);
319 return false;
320 }
321
322 if (!IsWithinSuitcaseTree(folder.Owner, folder.ParentID))
323 {
324 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveFolder: folder {0} (user {1}) is not within Suitcase tree", folder.ParentID, folder.Owner);
341 return false; 325 return false;
326 }
342 327
343 return base.MoveFolder(folder); 328 return base.MoveFolder(folder);
344 } 329 }
@@ -360,7 +345,10 @@ namespace OpenSim.Services.HypergridService
360 // Let's do a bit of sanity checking, more than the base service does 345 // Let's do a bit of sanity checking, more than the base service does
361 // make sure the given folder's parent folder exists under the suitcase tree of this user 346 // make sure the given folder's parent folder exists under the suitcase tree of this user
362 if (!IsWithinSuitcaseTree(item.Owner, item.Folder)) 347 if (!IsWithinSuitcaseTree(item.Owner, item.Folder))
348 {
349 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: AddItem: folder {0} (user {1}) is not within Suitcase tree", item.Folder, item.Owner);
363 return false; 350 return false;
351 }
364 352
365 // OK, it's legit 353 // OK, it's legit
366 return base.AddItem(item); 354 return base.AddItem(item);
@@ -370,7 +358,10 @@ namespace OpenSim.Services.HypergridService
370 public override bool UpdateItem(InventoryItemBase item) 358 public override bool UpdateItem(InventoryItemBase item)
371 { 359 {
372 if (!IsWithinSuitcaseTree(item.Owner, item.Folder)) 360 if (!IsWithinSuitcaseTree(item.Owner, item.Folder))
361 {
362 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: UpdateItem: folder {0} (user {1}) is not within Suitcase tree", item.Folder, item.Owner);
373 return false; 363 return false;
364 }
374 365
375 return base.UpdateItem(item); 366 return base.UpdateItem(item);
376 } 367 }
@@ -379,11 +370,28 @@ namespace OpenSim.Services.HypergridService
379 { 370 {
380 // Principal is b0rked. *sigh* 371 // Principal is b0rked. *sigh*
381 372
382 if (!IsWithinSuitcaseTree(items[0].Owner, items[0].Folder)) 373 // Check the items' destination folders
383 return false; 374 foreach (InventoryItemBase item in items)
375 {
376 if (!IsWithinSuitcaseTree(item.Owner, item.Folder))
377 {
378 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveItems: folder {0} (user {1}) is not within Suitcase tree", item.Folder, item.Owner);
379 return false;
380 }
381 }
384 382
385 return base.MoveItems(principalID, items); 383 // Check the items' current folders
384 foreach (InventoryItemBase item in items)
385 {
386 InventoryItemBase originalItem = base.GetItem(item);
387 if (!IsWithinSuitcaseTree(originalItem.Owner, originalItem.Folder))
388 {
389 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: MoveItems: folder {0} (user {1}) is not within Suitcase tree", item.Folder, item.Owner);
390 return false;
391 }
392 }
386 393
394 return base.MoveItems(principalID, items);
387 } 395 }
388 396
389 public override bool DeleteItems(UUID principalID, List<UUID> itemIDs) 397 public override bool DeleteItems(UUID principalID, List<UUID> itemIDs)
@@ -403,8 +411,8 @@ namespace OpenSim.Services.HypergridService
403 411
404 if (!IsWithinSuitcaseTree(it.Owner, it.Folder) && !IsPartOfAppearance(it.Owner, it.ID)) 412 if (!IsWithinSuitcaseTree(it.Owner, it.Folder) && !IsPartOfAppearance(it.Owner, it.ID))
405 { 413 {
406 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: Item {0} (folder {1}) is not within Suitcase", 414 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetItem: item {0}/{1} (folder {2}) (user {3}) is not within Suitcase tree or Appearance",
407 it.Name, it.Folder); 415 it.Name, it.ID, it.Folder, it.Owner);
408 return null; 416 return null;
409 } 417 }
410 418
@@ -425,7 +433,11 @@ namespace OpenSim.Services.HypergridService
425 if (f != null) 433 if (f != null)
426 { 434 {
427 if (!IsWithinSuitcaseTree(f.Owner, f.ID)) 435 if (!IsWithinSuitcaseTree(f.Owner, f.ID))
436 {
437 m_log.DebugFormat("[HG SUITCASE INVENTORY SERVICE]: GetFolder: folder {0}/{1} (user {2}) is not within Suitcase tree",
438 f.Name, f.ID, f.Owner);
428 return null; 439 return null;
440 }
429 } 441 }
430 442
431 return f; 443 return f;
@@ -456,7 +468,7 @@ namespace OpenSim.Services.HypergridService
456 { 468 {
457 XInventoryFolder[] folders = m_Database.GetFolders( 469 XInventoryFolder[] folders = m_Database.GetFolders(
458 new string[] { "agentID", "folderName", "type" }, 470 new string[] { "agentID", "folderName", "type" },
459 new string[] { principalID.ToString(), "My Inventory", ((int)AssetType.RootFolder).ToString() }); 471 new string[] { principalID.ToString(), InventoryFolderBase.ROOT_FOLDER_NAME, ((int)FolderType.Root).ToString() });
460 472
461 if (folders != null && folders.Length > 0) 473 if (folders != null && folders.Length > 0)
462 return folders[0]; 474 return folders[0];
@@ -464,7 +476,7 @@ namespace OpenSim.Services.HypergridService
464 // OK, so the RootFolder type didn't work. Let's look for any type with parent UUID.Zero. 476 // OK, so the RootFolder type didn't work. Let's look for any type with parent UUID.Zero.
465 folders = m_Database.GetFolders( 477 folders = m_Database.GetFolders(
466 new string[] { "agentID", "folderName", "parentFolderID" }, 478 new string[] { "agentID", "folderName", "parentFolderID" },
467 new string[] { principalID.ToString(), "My Inventory", UUID.Zero.ToString() }); 479 new string[] { principalID.ToString(), InventoryFolderBase.ROOT_FOLDER_NAME, UUID.Zero.ToString() });
468 480
469 if (folders != null && folders.Length > 0) 481 if (folders != null && folders.Length > 0)
470 return folders[0]; 482 return folders[0];
@@ -472,12 +484,28 @@ namespace OpenSim.Services.HypergridService
472 return null; 484 return null;
473 } 485 }
474 486
487 private XInventoryFolder GetCurrentOutfitXFolder(UUID userID)
488 {
489 XInventoryFolder root = GetRootXFolder(userID);
490 if (root == null)
491 return null;
492
493 XInventoryFolder[] folders = m_Database.GetFolders(
494 new string[] { "agentID", "type", "parentFolderID" },
495 new string[] { userID.ToString(), ((int)FolderType.CurrentOutfit).ToString(), root.folderID.ToString() });
496
497 if (folders.Length == 0)
498 return null;
499
500 return folders[0];
501 }
502
475 private XInventoryFolder GetSuitcaseXFolder(UUID principalID) 503 private XInventoryFolder GetSuitcaseXFolder(UUID principalID)
476 { 504 {
477 // Warp! Root folder for travelers 505 // Warp! Root folder for travelers
478 XInventoryFolder[] folders = m_Database.GetFolders( 506 XInventoryFolder[] folders = m_Database.GetFolders(
479 new string[] { "agentID", "type" }, 507 new string[] { "agentID", "type" },
480 new string[] { principalID.ToString(), "100" }); // This is a special folder type... 508 new string[] { principalID.ToString(), ((int)FolderType.Suitcase).ToString() });
481 509
482 if (folders != null && folders.Length > 0) 510 if (folders != null && folders.Length > 0)
483 return folders[0]; 511 return folders[0];
@@ -485,13 +513,13 @@ namespace OpenSim.Services.HypergridService
485 // check to see if we have the old Suitcase folder 513 // check to see if we have the old Suitcase folder
486 folders = m_Database.GetFolders( 514 folders = m_Database.GetFolders(
487 new string[] { "agentID", "folderName", "parentFolderID" }, 515 new string[] { "agentID", "folderName", "parentFolderID" },
488 new string[] { principalID.ToString(), "My Suitcase", UUID.Zero.ToString() }); 516 new string[] { principalID.ToString(), InventoryFolderBase.SUITCASE_FOLDER_NAME, UUID.Zero.ToString() });
489 if (folders != null && folders.Length > 0) 517 if (folders != null && folders.Length > 0)
490 { 518 {
491 // Move it to under the root folder 519 // Move it to under the root folder
492 XInventoryFolder root = GetRootXFolder(principalID); 520 XInventoryFolder root = GetRootXFolder(principalID);
493 folders[0].parentFolderID = root.folderID; 521 folders[0].parentFolderID = root.folderID;
494 folders[0].type = 100; 522 folders[0].type = (int)FolderType.Suitcase;
495 m_Database.StoreFolder(folders[0]); 523 m_Database.StoreFolder(folders[0]);
496 return folders[0]; 524 return folders[0];
497 } 525 }
@@ -501,17 +529,18 @@ namespace OpenSim.Services.HypergridService
501 529
502 private void SetAsNormalFolder(XInventoryFolder suitcase) 530 private void SetAsNormalFolder(XInventoryFolder suitcase)
503 { 531 {
504 suitcase.type = (short)AssetType.Folder; 532 //suitcase.type = InventoryItemBase.SUITCASE_FOLDER_FAKE_TYPE;
505 } 533 }
506 534
507 private List<XInventoryFolder> GetFolderTree(UUID principalID, UUID folder) 535 private List<XInventoryFolder> GetFolderTree(UUID principalID, UUID folder)
508 { 536 {
509 List<XInventoryFolder> t = null; 537 List<XInventoryFolder> t;
510 if (m_SuitcaseTrees.TryGetValue(principalID, out t)) 538 if (m_SuitcaseTrees.TryGetValue(principalID, out t))
511 return t; 539 return t;
512 540
541 // Get the tree of the suitcase folder
513 t = GetFolderTreeRecursive(folder); 542 t = GetFolderTreeRecursive(folder);
514 m_SuitcaseTrees.AddOrUpdate(principalID, t, 5*60); // 5minutes 543 m_SuitcaseTrees.AddOrUpdate(principalID, t, 5*60); // 5 minutes
515 return t; 544 return t;
516 } 545 }
517 546
@@ -522,8 +551,10 @@ namespace OpenSim.Services.HypergridService
522 new string[] { "parentFolderID" }, 551 new string[] { "parentFolderID" },
523 new string[] { root.ToString() }); 552 new string[] { root.ToString() });
524 553
525 if (folders == null || (folders != null && folders.Length == 0)) 554 if (folders == null || folders.Length == 0)
555 {
526 return tree; // empty tree 556 return tree; // empty tree
557 }
527 else 558 else
528 { 559 {
529 foreach (XInventoryFolder f in folders) 560 foreach (XInventoryFolder f in folders)
@@ -546,6 +577,7 @@ namespace OpenSim.Services.HypergridService
546 private bool IsWithinSuitcaseTree(UUID principalID, UUID folderID) 577 private bool IsWithinSuitcaseTree(UUID principalID, UUID folderID)
547 { 578 {
548 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID); 579 XInventoryFolder suitcase = GetSuitcaseXFolder(principalID);
580
549 if (suitcase == null) 581 if (suitcase == null)
550 { 582 {
551 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder", principalID); 583 m_log.WarnFormat("[HG SUITCASE INVENTORY SERVICE]: User {0} does not have a Suitcase folder", principalID);
@@ -555,14 +587,18 @@ namespace OpenSim.Services.HypergridService
555 List<XInventoryFolder> tree = new List<XInventoryFolder>(); 587 List<XInventoryFolder> tree = new List<XInventoryFolder>();
556 tree.Add(suitcase); // Warp! the tree is the real root folder plus the children of the suitcase folder 588 tree.Add(suitcase); // Warp! the tree is the real root folder plus the children of the suitcase folder
557 tree.AddRange(GetFolderTree(principalID, suitcase.folderID)); 589 tree.AddRange(GetFolderTree(principalID, suitcase.folderID));
590
591 // Also add the Current Outfit folder to the list of available folders
592 XInventoryFolder folder = GetCurrentOutfitXFolder(principalID);
593 if (folder != null)
594 tree.Add(folder);
595
558 XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl) 596 XInventoryFolder f = tree.Find(delegate(XInventoryFolder fl)
559 { 597 {
560 if (fl.folderID == folderID) return true; 598 return (fl.folderID == folderID);
561 else return false;
562 }); 599 });
563 600
564 if (f == null) return false; 601 return (f != null);
565 else return true;
566 } 602 }
567 #endregion 603 #endregion
568 604
diff --git a/OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs b/OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs
index 49f2176..9999237 100644
--- a/OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/HypergridService/UserAccountCache.cs b/OpenSim/Services/HypergridService/UserAccountCache.cs
index 65f9dd5..fa7dd0b 100644
--- a/OpenSim/Services/HypergridService/UserAccountCache.cs
+++ b/OpenSim/Services/HypergridService/UserAccountCache.cs
@@ -1,4 +1,4 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Reflection; 3using System.Reflection;
4 4
@@ -95,6 +95,11 @@ namespace OpenSim.Services.HypergridService
95 return null; 95 return null;
96 } 96 }
97 97
98 public void InvalidateCache(UUID userID)
99 {
100 m_UUIDCache.Remove(userID);
101 }
102
98 public bool StoreUserAccount(UserAccount data) 103 public bool StoreUserAccount(UserAccount data)
99 { 104 {
100 return false; 105 return false;
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index a26a922..c65122a 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -30,6 +30,7 @@ using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using System.Reflection; 31using System.Reflection;
32 32
33using OpenSim.Data;
33using OpenSim.Framework; 34using OpenSim.Framework;
34using OpenSim.Services.Connectors.Friends; 35using OpenSim.Services.Connectors.Friends;
35using OpenSim.Services.Connectors.Hypergrid; 36using OpenSim.Services.Connectors.Hypergrid;
@@ -50,14 +51,14 @@ namespace OpenSim.Services.HypergridService
50 /// needs to do it for them. 51 /// needs to do it for them.
51 /// Once we have better clients, this shouldn't be needed. 52 /// Once we have better clients, this shouldn't be needed.
52 /// </summary> 53 /// </summary>
53 public class UserAgentService : IUserAgentService 54 public class UserAgentService : UserAgentServiceBase, IUserAgentService
54 { 55 {
55 private static readonly ILog m_log = 56 private static readonly ILog m_log =
56 LogManager.GetLogger( 57 LogManager.GetLogger(
57 MethodBase.GetCurrentMethod().DeclaringType); 58 MethodBase.GetCurrentMethod().DeclaringType);
58 59
59 // This will need to go into a DB table 60 // This will need to go into a DB table
60 static Dictionary<UUID, TravelingAgentInfo> m_TravelingAgents = new Dictionary<UUID, TravelingAgentInfo>(); 61 //static Dictionary<UUID, TravelingAgentInfo> m_Database = new Dictionary<UUID, TravelingAgentInfo>();
61 62
62 static bool m_Initialized = false; 63 static bool m_Initialized = false;
63 64
@@ -74,6 +75,7 @@ namespace OpenSim.Services.HypergridService
74 protected static string m_GridName; 75 protected static string m_GridName;
75 76
76 protected static int m_LevelOutsideContacts; 77 protected static int m_LevelOutsideContacts;
78 protected static bool m_ShowDetails;
77 79
78 protected static bool m_BypassClientVerification; 80 protected static bool m_BypassClientVerification;
79 81
@@ -86,6 +88,7 @@ namespace OpenSim.Services.HypergridService
86 } 88 }
87 89
88 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector) 90 public UserAgentService(IConfigSource config, IFriendsSimConnector friendsConnector)
91 : base(config)
89 { 92 {
90 // Let's set this always, because we don't know the sequence 93 // Let's set this always, because we don't know the sequence
91 // of instantiations 94 // of instantiations
@@ -126,20 +129,30 @@ namespace OpenSim.Services.HypergridService
126 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountService, args); 129 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountService, args);
127 130
128 m_LevelOutsideContacts = serverConfig.GetInt("LevelOutsideContacts", 0); 131 m_LevelOutsideContacts = serverConfig.GetInt("LevelOutsideContacts", 0);
132 m_ShowDetails = serverConfig.GetBoolean("ShowUserDetailsInHGProfile", true);
129 133
130 LoadTripPermissionsFromConfig(serverConfig, "ForeignTripsAllowed"); 134 LoadTripPermissionsFromConfig(serverConfig, "ForeignTripsAllowed");
131 LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_TripsAllowedExceptions); 135 LoadDomainExceptionsFromConfig(serverConfig, "AllowExcept", m_TripsAllowedExceptions);
132 LoadDomainExceptionsFromConfig(serverConfig, "DisallowExcept", m_TripsDisallowedExceptions); 136 LoadDomainExceptionsFromConfig(serverConfig, "DisallowExcept", m_TripsDisallowedExceptions);
133 137
134 m_GridName = serverConfig.GetString("ExternalName", string.Empty); 138 m_GridName = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
135 if (m_GridName == string.Empty) 139 new string[] { "Startup", "Hypergrid", "UserAgentService" }, String.Empty);
140 if (string.IsNullOrEmpty(m_GridName)) // Legacy. Remove soon.
136 { 141 {
137 serverConfig = config.Configs["GatekeeperService"];
138 m_GridName = serverConfig.GetString("ExternalName", string.Empty); 142 m_GridName = serverConfig.GetString("ExternalName", string.Empty);
143 if (m_GridName == string.Empty)
144 {
145 serverConfig = config.Configs["GatekeeperService"];
146 m_GridName = serverConfig.GetString("ExternalName", string.Empty);
147 }
139 } 148 }
149
140 if (!m_GridName.EndsWith("/")) 150 if (!m_GridName.EndsWith("/"))
141 m_GridName = m_GridName + "/"; 151 m_GridName = m_GridName + "/";
142 152
153 // Finally some cleanup
154 m_Database.DeleteOld();
155
143 } 156 }
144 } 157 }
145 158
@@ -204,10 +217,10 @@ namespace OpenSim.Services.HypergridService
204 return home; 217 return home;
205 } 218 }
206 219
207 public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason) 220 public bool LoginAgentToGrid(GridRegion source, AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason)
208 { 221 {
209 m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}", 222 m_log.DebugFormat("[USER AGENT SERVICE]: Request to login user {0} {1} (@{2}) to grid {3}",
210 agentCircuit.firstname, agentCircuit.lastname, ((clientIP == null) ? "stored IP" : clientIP.Address.ToString()), gatekeeper.ServerURI); 223 agentCircuit.firstname, agentCircuit.lastname, (fromLogin ? agentCircuit.IPAddress : "stored IP"), gatekeeper.ServerURI);
211 224
212 string gridName = gatekeeper.ServerURI; 225 string gridName = gatekeeper.ServerURI;
213 226
@@ -254,21 +267,21 @@ namespace OpenSim.Services.HypergridService
254 267
255 // Generate a new service session 268 // Generate a new service session
256 agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random(); 269 agentCircuit.ServiceSessionID = region.ServerURI + ";" + UUID.Random();
257 TravelingAgentInfo old = UpdateTravelInfo(agentCircuit, region); 270 TravelingAgentInfo old = null;
271 TravelingAgentInfo travel = CreateTravelInfo(agentCircuit, region, fromLogin, out old);
258 272
259 bool success = false; 273 bool success = false;
260 string myExternalIP = string.Empty; 274 string myExternalIP = string.Empty;
261 275
262 m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}", m_GridName, gridName); 276 m_log.DebugFormat("[USER AGENT SERVICE]: this grid: {0}, desired grid: {1}, desired region: {2}", m_GridName, gridName, region.RegionID);
263 277
264 if (m_GridName == gridName) 278 if (m_GridName == gridName)
265 success = m_GatekeeperService.LoginAgent(agentCircuit, finalDestination, out reason); 279 {
280 success = m_GatekeeperService.LoginAgent(source, agentCircuit, finalDestination, out reason);
281 }
266 else 282 else
267 { 283 {
268 success = m_GatekeeperConnector.CreateAgent(region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason); 284 success = m_GatekeeperConnector.CreateAgent(source, region, agentCircuit, (uint)Constants.TeleportFlags.ViaLogin, out myExternalIP, out reason);
269 if (success)
270 // Report them as nowhere
271 m_PresenceService.ReportAgent(agentCircuit.SessionID, UUID.Zero);
272 } 285 }
273 286
274 if (!success) 287 if (!success)
@@ -276,84 +289,64 @@ namespace OpenSim.Services.HypergridService
276 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}", 289 m_log.DebugFormat("[USER AGENT SERVICE]: Unable to login user {0} {1} to grid {2}, reason: {3}",
277 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason); 290 agentCircuit.firstname, agentCircuit.lastname, region.ServerURI, reason);
278 291
279 // restore the old travel info 292 if (old != null)
280 lock (m_TravelingAgents) 293 StoreTravelInfo(old);
281 { 294 else
282 if (old == null) 295 m_Database.Delete(agentCircuit.SessionID);
283 m_TravelingAgents.Remove(agentCircuit.SessionID);
284 else
285 m_TravelingAgents[agentCircuit.SessionID] = old;
286 }
287 296
288 return false; 297 return false;
289 } 298 }
290 299
300 // Everything is ok
301
302 // Update the perceived IP Address of our grid
291 m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP); 303 m_log.DebugFormat("[USER AGENT SERVICE]: Gatekeeper sees me as {0}", myExternalIP);
292 // else set the IP addresses associated with this client 304 travel.MyIpAddress = myExternalIP;
293 if (clientIP != null) 305
294 m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress = clientIP.Address.ToString(); 306 StoreTravelInfo(travel);
295 m_TravelingAgents[agentCircuit.SessionID].MyIpAddress = myExternalIP;
296 307
297 return true; 308 return true;
298 } 309 }
299 310
300 public bool LoginAgentToGrid(AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason) 311 public bool LoginAgentToGrid(GridRegion source, AgentCircuitData agentCircuit, GridRegion gatekeeper, GridRegion finalDestination, out string reason)
301 { 312 {
302 reason = string.Empty; 313 reason = string.Empty;
303 return LoginAgentToGrid(agentCircuit, gatekeeper, finalDestination, null, out reason); 314 return LoginAgentToGrid(source, agentCircuit, gatekeeper, finalDestination, false, out reason);
304 } 315 }
305 316
306 private void SetClientIP(UUID sessionID, string ip) 317 TravelingAgentInfo CreateTravelInfo(AgentCircuitData agentCircuit, GridRegion region, bool fromLogin, out TravelingAgentInfo existing)
307 { 318 {
308 if (m_TravelingAgents.ContainsKey(sessionID)) 319 HGTravelingData hgt = m_Database.Get(agentCircuit.SessionID);
309 { 320 existing = null;
310 m_log.DebugFormat("[USER AGENT SERVICE]: Setting IP {0} for session {1}", ip, sessionID);
311 m_TravelingAgents[sessionID].ClientIPAddress = ip;
312 }
313 }
314 321
315 TravelingAgentInfo UpdateTravelInfo(AgentCircuitData agentCircuit, GridRegion region) 322 if (hgt != null)
316 {
317 TravelingAgentInfo travel = new TravelingAgentInfo();
318 TravelingAgentInfo old = null;
319 lock (m_TravelingAgents)
320 { 323 {
321 if (m_TravelingAgents.ContainsKey(agentCircuit.SessionID)) 324 // Very important! Override whatever this agent comes with.
322 { 325 // UserAgentService always sets the IP for every new agent
323 // Very important! Override whatever this agent comes with. 326 // with the original IP address.
324 // UserAgentService always sets the IP for every new agent 327 existing = new TravelingAgentInfo(hgt);
325 // with the original IP address. 328 agentCircuit.IPAddress = existing.ClientIPAddress;
326 agentCircuit.IPAddress = m_TravelingAgents[agentCircuit.SessionID].ClientIPAddress;
327
328 old = m_TravelingAgents[agentCircuit.SessionID];
329 }
330
331 m_TravelingAgents[agentCircuit.SessionID] = travel;
332 } 329 }
330
331 TravelingAgentInfo travel = new TravelingAgentInfo(existing);
332 travel.SessionID = agentCircuit.SessionID;
333 travel.UserID = agentCircuit.AgentID; 333 travel.UserID = agentCircuit.AgentID;
334 travel.GridExternalName = region.ServerURI; 334 travel.GridExternalName = region.ServerURI;
335 travel.ServiceToken = agentCircuit.ServiceSessionID; 335 travel.ServiceToken = agentCircuit.ServiceSessionID;
336 if (old != null)
337 travel.ClientIPAddress = old.ClientIPAddress;
338 336
339 return old; 337 if (fromLogin)
338 travel.ClientIPAddress = agentCircuit.IPAddress;
339
340 StoreTravelInfo(travel);
341
342 return travel;
340 } 343 }
341 344
342 public void LogoutAgent(UUID userID, UUID sessionID) 345 public void LogoutAgent(UUID userID, UUID sessionID)
343 { 346 {
344 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID); 347 m_log.DebugFormat("[USER AGENT SERVICE]: User {0} logged out", userID);
345 348
346 lock (m_TravelingAgents) 349 m_Database.Delete(sessionID);
347 {
348 List<UUID> travels = new List<UUID>();
349 foreach (KeyValuePair<UUID, TravelingAgentInfo> kvp in m_TravelingAgents)
350 if (kvp.Value == null) // do some clean up
351 travels.Add(kvp.Key);
352 else if (kvp.Value.UserID == userID)
353 travels.Add(kvp.Key);
354 foreach (UUID session in travels)
355 m_TravelingAgents.Remove(session);
356 }
357 350
358 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString()); 351 GridUserInfo guinfo = m_GridUserService.GetGridUserInfo(userID.ToString());
359 if (guinfo != null) 352 if (guinfo != null)
@@ -363,10 +356,11 @@ namespace OpenSim.Services.HypergridService
363 // We need to prevent foreign users with the same UUID as a local user 356 // We need to prevent foreign users with the same UUID as a local user
364 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName) 357 public bool IsAgentComingHome(UUID sessionID, string thisGridExternalName)
365 { 358 {
366 if (!m_TravelingAgents.ContainsKey(sessionID)) 359 HGTravelingData hgt = m_Database.Get(sessionID);
360 if (hgt == null)
367 return false; 361 return false;
368 362
369 TravelingAgentInfo travel = m_TravelingAgents[sessionID]; 363 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
370 364
371 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower(); 365 return travel.GridExternalName.ToLower() == thisGridExternalName.ToLower();
372 } 366 }
@@ -379,31 +373,32 @@ namespace OpenSim.Services.HypergridService
379 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.", 373 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying Client session {0} with reported IP {1}.",
380 sessionID, reportedIP); 374 sessionID, reportedIP);
381 375
382 if (m_TravelingAgents.ContainsKey(sessionID)) 376 HGTravelingData hgt = m_Database.Get(sessionID);
383 { 377 if (hgt == null)
384 bool result = m_TravelingAgents[sessionID].ClientIPAddress == reportedIP || 378 return false;
385 m_TravelingAgents[sessionID].MyIpAddress == reportedIP; // NATed
386 379
387 m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}", 380 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
388 reportedIP, m_TravelingAgents[sessionID].ClientIPAddress, m_TravelingAgents[sessionID].MyIpAddress, result);
389 381
390 return result; 382 bool result = travel.ClientIPAddress == reportedIP || travel.MyIpAddress == reportedIP; // NATed
391 } 383
384 m_log.DebugFormat("[USER AGENT SERVICE]: Comparing {0} with login IP {1} and MyIP {1}; result is {3}",
385 reportedIP, travel.ClientIPAddress, travel.MyIpAddress, result);
392 386
393 return false; 387 return result;
394 } 388 }
395 389
396 public bool VerifyAgent(UUID sessionID, string token) 390 public bool VerifyAgent(UUID sessionID, string token)
397 { 391 {
398 if (m_TravelingAgents.ContainsKey(sessionID)) 392 HGTravelingData hgt = m_Database.Get(sessionID);
393 if (hgt == null)
399 { 394 {
400 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, m_TravelingAgents[sessionID].ServiceToken); 395 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID);
401 return m_TravelingAgents[sessionID].ServiceToken == token; 396 return false;
402 } 397 }
403 398
404 m_log.DebugFormat("[USER AGENT SERVICE]: Token verification for session {0}: no such session", sessionID); 399 TravelingAgentInfo travel = new TravelingAgentInfo(hgt);
405 400 m_log.DebugFormat("[USER AGENT SERVICE]: Verifying agent token {0} against {1}", token, travel.ServiceToken);
406 return false; 401 return travel.ServiceToken == token;
407 } 402 }
408 403
409 [Obsolete] 404 [Obsolete]
@@ -466,17 +461,17 @@ namespace OpenSim.Services.HypergridService
466 } 461 }
467 } 462 }
468 463
469 // Lastly, let's notify the rest who may be online somewhere else 464 //// Lastly, let's notify the rest who may be online somewhere else
470 foreach (string user in usersToBeNotified) 465 //foreach (string user in usersToBeNotified)
471 { 466 //{
472 UUID id = new UUID(user); 467 // UUID id = new UUID(user);
473 if (m_TravelingAgents.ContainsKey(id) && m_TravelingAgents[id].GridExternalName != m_GridName) 468 // if (m_Database.ContainsKey(id) && m_Database[id].GridExternalName != m_GridName)
474 { 469 // {
475 string url = m_TravelingAgents[id].GridExternalName; 470 // string url = m_Database[id].GridExternalName;
476 // forward 471 // // forward
477 m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url); 472 // m_log.WarnFormat("[USER AGENT SERVICE]: User {0} is visiting {1}. HG Status notifications still not implemented.", user, url);
478 } 473 // }
479 } 474 //}
480 475
481 // and finally, let's send the online friends 476 // and finally, let's send the online friends
482 if (online) 477 if (online)
@@ -578,10 +573,22 @@ namespace OpenSim.Services.HypergridService
578 573
579 if (account != null) 574 if (account != null)
580 { 575 {
581 info.Add("user_flags", (object)account.UserFlags); 576 info.Add("user_firstname", account.FirstName);
582 info.Add("user_created", (object)account.Created); 577 info.Add("user_lastname", account.LastName);
583 info.Add("user_title", (object)account.UserTitle);
584 info.Add("result", "success"); 578 info.Add("result", "success");
579
580 if (m_ShowDetails)
581 {
582 info.Add("user_flags", account.UserFlags);
583 info.Add("user_created", account.Created);
584 info.Add("user_title", account.UserTitle);
585 }
586 else
587 {
588 info.Add("user_flags", 0);
589 info.Add("user_created", 0);
590 info.Add("user_title", string.Empty);
591 }
585 } 592 }
586 593
587 return info; 594 return info;
@@ -603,16 +610,13 @@ namespace OpenSim.Services.HypergridService
603 610
604 public string LocateUser(UUID userID) 611 public string LocateUser(UUID userID)
605 { 612 {
606 foreach (TravelingAgentInfo t in m_TravelingAgents.Values) 613 HGTravelingData[] hgts = m_Database.GetSessions(userID);
607 { 614 if (hgts == null)
608 if (t == null) 615 return string.Empty;
609 { 616
610 m_log.ErrorFormat("[USER AGENT SERVICE]: Oops! Null TravelingAgentInfo. Please report this on mantis"); 617 foreach (HGTravelingData t in hgts)
611 continue; 618 if (t.Data.ContainsKey("GridExternalName") && !m_GridName.Equals(t.Data["GridExternalName"]))
612 } 619 return t.Data["GridExternalName"];
613 if (t.UserID == userID && !m_GridName.Equals(t.GridExternalName))
614 return t.GridExternalName;
615 }
616 620
617 return string.Empty; 621 return string.Empty;
618 } 622 }
@@ -683,17 +687,60 @@ namespace OpenSim.Services.HypergridService
683 return exception; 687 return exception;
684 } 688 }
685 689
690 private void StoreTravelInfo(TravelingAgentInfo travel)
691 {
692 if (travel == null)
693 return;
694
695 HGTravelingData hgt = new HGTravelingData();
696 hgt.SessionID = travel.SessionID;
697 hgt.UserID = travel.UserID;
698 hgt.Data = new Dictionary<string, string>();
699 hgt.Data["GridExternalName"] = travel.GridExternalName;
700 hgt.Data["ServiceToken"] = travel.ServiceToken;
701 hgt.Data["ClientIPAddress"] = travel.ClientIPAddress;
702 hgt.Data["MyIPAddress"] = travel.MyIpAddress;
703
704 m_Database.Store(hgt);
705 }
686 #endregion 706 #endregion
687 707
688 } 708 }
689 709
690 class TravelingAgentInfo 710 class TravelingAgentInfo
691 { 711 {
712 public UUID SessionID;
692 public UUID UserID; 713 public UUID UserID;
693 public string GridExternalName = string.Empty; 714 public string GridExternalName = string.Empty;
694 public string ServiceToken = string.Empty; 715 public string ServiceToken = string.Empty;
695 public string ClientIPAddress = string.Empty; // as seen from this user agent service 716 public string ClientIPAddress = string.Empty; // as seen from this user agent service
696 public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper 717 public string MyIpAddress = string.Empty; // the user agent service's external IP, as seen from the next gatekeeper
718
719 public TravelingAgentInfo(HGTravelingData t)
720 {
721 if (t.Data != null)
722 {
723 SessionID = new UUID(t.SessionID);
724 UserID = new UUID(t.UserID);
725 GridExternalName = t.Data["GridExternalName"];
726 ServiceToken = t.Data["ServiceToken"];
727 ClientIPAddress = t.Data["ClientIPAddress"];
728 MyIpAddress = t.Data["MyIPAddress"];
729 }
730 }
731
732 public TravelingAgentInfo(TravelingAgentInfo old)
733 {
734 if (old != null)
735 {
736 SessionID = old.SessionID;
737 UserID = old.UserID;
738 GridExternalName = old.GridExternalName;
739 ServiceToken = old.ServiceToken;
740 ClientIPAddress = old.ClientIPAddress;
741 MyIpAddress = old.MyIpAddress;
742 }
743 }
697 } 744 }
698 745
699} 746}
diff --git a/OpenSim/Services/HypergridService/UserAgentServiceBase.cs b/OpenSim/Services/HypergridService/UserAgentServiceBase.cs
new file mode 100644
index 0000000..a00e5a6
--- /dev/null
+++ b/OpenSim/Services/HypergridService/UserAgentServiceBase.cs
@@ -0,0 +1,84 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using Nini.Config;
31using OpenSim.Framework;
32using OpenSim.Data;
33using OpenSim.Services.Interfaces;
34using OpenSim.Services.Base;
35
36namespace OpenSim.Services.HypergridService
37{
38 public class UserAgentServiceBase : ServiceBase
39 {
40 protected IHGTravelingData m_Database = null;
41
42 public UserAgentServiceBase(IConfigSource config)
43 : base(config)
44 {
45 string dllName = String.Empty;
46 string connString = String.Empty;
47 string realm = "hg_traveling_data";
48
49 //
50 // Try reading the [DatabaseService] section, if it exists
51 //
52 IConfig dbConfig = config.Configs["DatabaseService"];
53 if (dbConfig != null)
54 {
55 if (dllName == String.Empty)
56 dllName = dbConfig.GetString("StorageProvider", String.Empty);
57 if (connString == String.Empty)
58 connString = dbConfig.GetString("ConnectionString", String.Empty);
59 }
60
61 //
62 // [UserAgentService] section overrides [DatabaseService], if it exists
63 //
64 IConfig gridConfig = config.Configs["UserAgentService"];
65 if (gridConfig != null)
66 {
67 dllName = gridConfig.GetString("StorageProvider", dllName);
68 connString = gridConfig.GetString("ConnectionString", connString);
69 realm = gridConfig.GetString("Realm", realm);
70 }
71
72 //
73 // We tried, but this doesn't exist. We can't proceed.
74 //
75 if (dllName.Equals(String.Empty))
76 throw new Exception("No StorageProvider configured");
77
78 m_Database = LoadPlugin<IHGTravelingData>(dllName, new Object[] { connString, realm });
79 if (m_Database == null)
80 throw new Exception("Could not find a storage interface in the given module");
81
82 }
83 }
84}
diff --git a/OpenSim/Services/Interfaces/IAgentPreferencesService.cs b/OpenSim/Services/Interfaces/IAgentPreferencesService.cs
new file mode 100644
index 0000000..3b4fda2
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IAgentPreferencesService.cs
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31
32namespace OpenSim.Services.Interfaces
33{
34 public class AgentPrefs
35 {
36 public AgentPrefs(UUID principalID)
37 {
38 PrincipalID = principalID;
39 }
40
41 public AgentPrefs(Dictionary<string, string> kvp)
42 {
43 if (kvp.ContainsKey("PrincipalID"))
44 UUID.TryParse(kvp["PrincipalID"], out PrincipalID);
45 if (kvp.ContainsKey("AccessPrefs"))
46 AccessPrefs = kvp["AccessPrefs"];
47 if (kvp.ContainsKey("HoverHeight"))
48 HoverHeight = double.Parse(kvp["HoverHeight"]);
49 if (kvp.ContainsKey("Language"))
50 Language = kvp["Language"];
51 if (kvp.ContainsKey("LanguageIsPublic"))
52 LanguageIsPublic = bool.Parse(kvp["LanguageIsPublic"]);
53 if (kvp.ContainsKey("PermEveryone"))
54 PermEveryone = int.Parse(kvp["PermEveryone"]);
55 if (kvp.ContainsKey("PermGroup"))
56 PermGroup = int.Parse(kvp["PermGroup"]);
57 if (kvp.ContainsKey("PermNextOwner"))
58 PermNextOwner = int.Parse(kvp["PermNextOwner"]);
59 }
60
61 public AgentPrefs(Dictionary<string, object> kvp)
62 {
63 if (kvp.ContainsKey("PrincipalID"))
64 UUID.TryParse(kvp["PrincipalID"].ToString(), out PrincipalID);
65 if (kvp.ContainsKey("AccessPrefs"))
66 AccessPrefs = kvp["AccessPrefs"].ToString();
67 if (kvp.ContainsKey("HoverHeight"))
68 HoverHeight = double.Parse(kvp["HoverHeight"].ToString());
69 if (kvp.ContainsKey("Language"))
70 Language = kvp["Language"].ToString();
71 if (kvp.ContainsKey("LanguageIsPublic"))
72 LanguageIsPublic = bool.Parse(kvp["LanguageIsPublic"].ToString());
73 if (kvp.ContainsKey("PermEveryone"))
74 PermEveryone = int.Parse(kvp["PermEveryone"].ToString());
75 if (kvp.ContainsKey("PermGroup"))
76 PermGroup = int.Parse(kvp["PermGroup"].ToString());
77 if (kvp.ContainsKey("PermNextOwner"))
78 PermNextOwner = int.Parse(kvp["PermNextOwner"].ToString());
79 }
80
81 public Dictionary<string, object> ToKeyValuePairs()
82 {
83 Dictionary<string, object> result = new Dictionary<string, object>();
84 result["PrincipalID"] = PrincipalID.ToString();
85 result["AccessPrefs"] = AccessPrefs.ToString();
86 result["HoverHeight"] = HoverHeight.ToString();
87 result["Language"] = Language.ToString();
88 result["LanguageIsPublic"] = LanguageIsPublic.ToString();
89 result["PermEveryone"] = PermEveryone.ToString();
90 result["PermGroup"] = PermGroup.ToString();
91 result["PermNextOwner"] = PermNextOwner.ToString();
92 return result;
93 }
94
95 public UUID PrincipalID = UUID.Zero;
96 public string AccessPrefs = "M";
97 //public int GodLevel; // *TODO: Implement GodLevel (Unused by the viewer, afaict - 6/11/2015)
98 public double HoverHeight = 0.0;
99 public string Language = "en-us";
100 public bool LanguageIsPublic = true;
101 // DefaultObjectPermMasks
102 public int PermEveryone = 0;
103 public int PermGroup = 0;
104 public int PermNextOwner = 532480;
105 }
106
107 public interface IAgentPreferencesService
108 {
109 AgentPrefs GetAgentPreferences(UUID principalID);
110 bool StoreAgentPreferences(AgentPrefs data);
111
112 string GetLang(UUID principalID);
113 }
114}
115
diff --git a/OpenSim/Services/Interfaces/IAssetService.cs b/OpenSim/Services/Interfaces/IAssetService.cs
index 3c469c6..28c3315 100644
--- a/OpenSim/Services/Interfaces/IAssetService.cs
+++ b/OpenSim/Services/Interfaces/IAssetService.cs
@@ -75,6 +75,13 @@ namespace OpenSim.Services.Interfaces
75 /// </param> 75 /// </param>
76 /// <returns>True if the id was parseable, false otherwise</returns> 76 /// <returns>True if the id was parseable, false otherwise</returns>
77 bool Get(string id, Object sender, AssetRetrieved handler); 77 bool Get(string id, Object sender, AssetRetrieved handler);
78
79 /// <summary>
80 /// Check if assets exist in the database.
81 /// </summary>
82 /// <param name="ids">The assets' IDs</param>
83 /// <returns>For each asset: true if it exists, false otherwise</returns>
84 bool[] AssetsExist(string[] ids);
78 85
79 /// <summary> 86 /// <summary>
80 /// Creates a new asset 87 /// Creates a new asset
@@ -83,7 +90,7 @@ namespace OpenSim.Services.Interfaces
83 /// Returns a random ID if none is passed via the asset argument. 90 /// Returns a random ID if none is passed via the asset argument.
84 /// </remarks> 91 /// </remarks>
85 /// <param name="asset"></param> 92 /// <param name="asset"></param>
86 /// <returns></returns> 93 /// <returns>The Asset ID, or string.Empty if an error occurred</returns>
87 string Store(AssetBase asset); 94 string Store(AssetBase asset);
88 95
89 /// <summary> 96 /// <summary>
diff --git a/OpenSim/Services/Interfaces/IAvatarService.cs b/OpenSim/Services/Interfaces/IAvatarService.cs
index 863fd93..892e0b4 100644
--- a/OpenSim/Services/Interfaces/IAvatarService.cs
+++ b/OpenSim/Services/Interfaces/IAvatarService.cs
@@ -162,10 +162,15 @@ namespace OpenSim.Services.Interfaces
162 } 162 }
163 163
164 // Visual Params 164 // Visual Params
165 string[] vps = new string[AvatarAppearance.VISUALPARAM_COUNT]; 165 //string[] vps = new string[AvatarAppearance.VISUALPARAM_COUNT];
166 //byte[] binary = appearance.VisualParams;
167
168 // for (int i = 0 ; i < AvatarAppearance.VISUALPARAM_COUNT ; i++)
169
166 byte[] binary = appearance.VisualParams; 170 byte[] binary = appearance.VisualParams;
171 string[] vps = new string[binary.Length];
167 172
168 for (int i = 0 ; i < AvatarAppearance.VISUALPARAM_COUNT ; i++) 173 for (int i = 0; i < binary.Length; i++)
169 { 174 {
170 vps[i] = binary[i].ToString(); 175 vps[i] = binary[i].ToString();
171 } 176 }
@@ -174,11 +179,18 @@ namespace OpenSim.Services.Interfaces
174 179
175 // Attachments 180 // Attachments
176 List<AvatarAttachment> attachments = appearance.GetAttachments(); 181 List<AvatarAttachment> attachments = appearance.GetAttachments();
182 Dictionary<int, List<string>> atts = new Dictionary<int, List<string>>();
177 foreach (AvatarAttachment attach in attachments) 183 foreach (AvatarAttachment attach in attachments)
178 { 184 {
179 if (attach.ItemID != UUID.Zero) 185 if (attach.ItemID != UUID.Zero)
180 Data["_ap_" + attach.AttachPoint] = attach.ItemID.ToString(); 186 {
187 if (!atts.ContainsKey(attach.AttachPoint))
188 atts[attach.AttachPoint] = new List<string>();
189 atts[attach.AttachPoint].Add(attach.ItemID.ToString());
190 }
181 } 191 }
192 foreach (KeyValuePair<int, List<string>> kvp in atts)
193 Data["_ap_" + kvp.Key] = string.Join(",", kvp.Value.ToArray());
182 } 194 }
183 195
184 public AvatarAppearance ToAvatarAppearance() 196 public AvatarAppearance ToAvatarAppearance()
@@ -195,7 +207,13 @@ namespace OpenSim.Services.Interfaces
195 appearance.Serial = Int32.Parse(Data["Serial"]); 207 appearance.Serial = Int32.Parse(Data["Serial"]);
196 208
197 if (Data.ContainsKey("AvatarHeight")) 209 if (Data.ContainsKey("AvatarHeight"))
198 appearance.AvatarHeight = float.Parse(Data["AvatarHeight"]); 210 {
211 float h = float.Parse(Data["AvatarHeight"]);
212 if( h == 0f)
213 h = 1.9f;
214
215 appearance.AvatarHeight = h;
216 }
199 217
200 // Legacy Wearables 218 // Legacy Wearables
201 if (Data.ContainsKey("BodyItem")) 219 if (Data.ContainsKey("BodyItem"))
@@ -266,9 +284,13 @@ namespace OpenSim.Services.Interfaces
266 if (Data.ContainsKey("VisualParams")) 284 if (Data.ContainsKey("VisualParams"))
267 { 285 {
268 string[] vps = Data["VisualParams"].Split(new char[] {','}); 286 string[] vps = Data["VisualParams"].Split(new char[] {','});
269 byte[] binary = new byte[AvatarAppearance.VISUALPARAM_COUNT]; 287 //byte[] binary = new byte[AvatarAppearance.VISUALPARAM_COUNT];
270 288
271 for (int i = 0 ; i < vps.Length && i < binary.Length ; i++) 289 //for (int i = 0 ; i < vps.Length && i < binary.Length ; i++)
290
291 byte[] binary = new byte[vps.Length];
292
293 for (int i = 0; i < vps.Length; i++)
272 binary[i] = (byte)Convert.ToInt32(vps[i]); 294 binary[i] = (byte)Convert.ToInt32(vps[i]);
273 295
274 appearance.VisualParams = binary; 296 appearance.VisualParams = binary;
@@ -304,10 +326,16 @@ namespace OpenSim.Services.Interfaces
304 if (!Int32.TryParse(pointStr, out point)) 326 if (!Int32.TryParse(pointStr, out point))
305 continue; 327 continue;
306 328
307 UUID uuid = UUID.Zero; 329 List<string> idList = new List<string>(_kvp.Value.Split(new char[] {','}));
308 UUID.TryParse(_kvp.Value, out uuid);
309 330
310 appearance.SetAttachment(point, uuid, UUID.Zero); 331 appearance.SetAttachment(point, UUID.Zero, UUID.Zero);
332 foreach (string id in idList)
333 {
334 UUID uuid = UUID.Zero;
335 UUID.TryParse(id, out uuid);
336
337 appearance.SetAttachment(point | 0x80, uuid, UUID.Zero);
338 }
311 } 339 }
312 340
313 if (appearance.Wearables[AvatarWearable.BODY].Count == 0) 341 if (appearance.Wearables[AvatarWearable.BODY].Count == 0)
diff --git a/OpenSim/Services/Interfaces/IBakedTextureService.cs b/OpenSim/Services/Interfaces/IBakedTextureService.cs
new file mode 100644
index 0000000..69df4a0
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IBakedTextureService.cs
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30
31namespace OpenSim.Services.Interfaces
32{
33 public interface IBakedTextureService
34 {
35 string Get(string id);
36 void Store(string id, string data);
37 }
38}
diff --git a/OpenSim/Services/Interfaces/IBansService.cs b/OpenSim/Services/Interfaces/IBansService.cs
new file mode 100644
index 0000000..8fd3521
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IBansService.cs
@@ -0,0 +1,48 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27using System;
28using System.Collections.Generic;
29
30using OpenSim.Framework;
31using OpenMetaverse;
32
33namespace OpenSim.Services.Interfaces
34{
35 public interface IBansService
36 {
37 /// <summary>
38 /// Are any of the given arguments banned from the grid?
39 /// </summary>
40 /// <param name="userID"></param>
41 /// <param name="ip"></param>
42 /// <param name="id0"></param>
43 /// <param name="origin"></param>
44 /// <returns></returns>
45 bool IsBanned(string userID, string ip, string id0, string origin);
46 }
47
48}
diff --git a/OpenSim/Services/Interfaces/IEstateDataService.cs b/OpenSim/Services/Interfaces/IEstateDataService.cs
new file mode 100644
index 0000000..719563d
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IEstateDataService.cs
@@ -0,0 +1,115 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenSim.Framework;
31using OpenMetaverse;
32
33namespace OpenSim.Services.Interfaces
34{
35 public interface IEstateDataService
36 {
37 /// <summary>
38 /// Load estate settings for a region.
39 /// </summary>
40 /// <param name="regionID"></param>
41 /// <param name="create">If true, then an estate is created if one is not found.</param>
42 /// <returns></returns>
43 EstateSettings LoadEstateSettings(UUID regionID, bool create);
44
45 /// <summary>
46 /// Load estate settings for an estate ID.
47 /// </summary>
48 /// <param name="estateID"></param>
49 /// <returns></returns>
50 EstateSettings LoadEstateSettings(int estateID);
51
52 /// <summary>
53 /// Create a new estate.
54 /// </summary>
55 /// <returns>
56 /// A <see cref="EstateSettings"/>
57 /// </returns>
58 EstateSettings CreateNewEstate();
59
60 /// <summary>
61 /// Load/Get all estate settings.
62 /// </summary>
63 /// <returns>An empty list if no estates were found.</returns>
64 List<EstateSettings> LoadEstateSettingsAll();
65
66 /// <summary>
67 /// Store estate settings.
68 /// </summary>
69 /// <remarks>
70 /// This is also called by EstateSettings.Save()</remarks>
71 /// <param name="es"></param>
72 void StoreEstateSettings(EstateSettings es);
73
74 /// <summary>
75 /// Get estate IDs.
76 /// </summary>
77 /// <param name="search">Name of estate to search for. This is the exact name, no parttern matching is done.</param>
78 /// <returns></returns>
79 List<int> GetEstates(string search);
80
81 /// <summary>
82 /// Get the IDs of all estates owned by the given user.
83 /// </summary>
84 /// <returns>An empty list if no estates were found.</returns>
85 List<int> GetEstatesByOwner(UUID ownerID);
86
87 /// <summary>
88 /// Get the IDs of all estates.
89 /// </summary>
90 /// <returns>An empty list if no estates were found.</returns>
91 List<int> GetEstatesAll();
92
93 /// <summary>
94 /// Link a region to an estate.
95 /// </summary>
96 /// <param name="regionID"></param>
97 /// <param name="estateID"></param>
98 /// <returns>true if the link succeeded, false otherwise</returns>
99 bool LinkRegion(UUID regionID, int estateID);
100
101 /// <summary>
102 /// Get the UUIDs of all the regions in an estate.
103 /// </summary>
104 /// <param name="estateID"></param>
105 /// <returns></returns>
106 List<UUID> GetRegions(int estateID);
107
108 /// <summary>
109 /// Delete an estate
110 /// </summary>
111 /// <param name="estateID"></param>
112 /// <returns>true if the delete succeeded, false otherwise</returns>
113 bool DeleteEstate(int estateID);
114 }
115} \ No newline at end of file
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs
index d7da056..f5f1f75 100644
--- a/OpenSim/Services/Interfaces/IGridService.cs
+++ b/OpenSim/Services/Interfaces/IGridService.cs
@@ -26,12 +26,17 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Net; 31using System.Net;
31using System.Net.Sockets; 32using System.Net.Sockets;
33using System.Reflection;
34
32using OpenSim.Framework; 35using OpenSim.Framework;
33using OpenMetaverse; 36using OpenMetaverse;
34 37
38using log4net;
39
35namespace OpenSim.Services.Interfaces 40namespace OpenSim.Services.Interfaces
36{ 41{
37 public interface IGridService 42 public interface IGridService
@@ -97,6 +102,7 @@ namespace OpenSim.Services.Interfaces
97 List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax); 102 List<GridRegion> GetRegionRange(UUID scopeID, int xmin, int xmax, int ymin, int ymax);
98 103
99 List<GridRegion> GetDefaultRegions(UUID scopeID); 104 List<GridRegion> GetDefaultRegions(UUID scopeID);
105 List<GridRegion> GetDefaultHypergridRegions(UUID scopeID);
100 List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y); 106 List<GridRegion> GetFallbackRegions(UUID scopeID, int x, int y);
101 List<GridRegion> GetHyperlinks(UUID scopeID); 107 List<GridRegion> GetHyperlinks(UUID scopeID);
102 108
@@ -114,19 +120,28 @@ namespace OpenSim.Services.Interfaces
114 /// <param name='scopeID'></param> 120 /// <param name='scopeID'></param>
115 /// <param name='regionID'></param> 121 /// <param name='regionID'></param>
116 int GetRegionFlags(UUID scopeID, UUID regionID); 122 int GetRegionFlags(UUID scopeID, UUID regionID);
123
124 Dictionary<string,object> GetExtraFeatures();
125 }
126
127 public interface IHypergridLinker
128 {
129 GridRegion TryLinkRegionToCoords(UUID scopeID, string mapName, int xloc, int yloc, UUID ownerID, out string reason);
130 bool TryUnlinkRegion(string mapName);
117 } 131 }
118 132
119 public class GridRegion 133 public class GridRegion
120 { 134 {
135// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
136
137#pragma warning disable 414
138 private static readonly string LogHeader = "[GRID REGION]";
139#pragma warning restore 414
140
121 /// <summary> 141 /// <summary>
122 /// The port by which http communication occurs with the region 142 /// The port by which http communication occurs with the region
123 /// </summary> 143 /// </summary>
124 public uint HttpPort 144 public uint HttpPort { get; set; }
125 {
126 get { return m_httpPort; }
127 set { m_httpPort = value; }
128 }
129 protected uint m_httpPort;
130 145
131 /// <summary> 146 /// <summary>
132 /// A well-formed URI for the host region server (namely "http://" + ExternalHostName) 147 /// A well-formed URI for the host region server (namely "http://" + ExternalHostName)
@@ -134,14 +149,17 @@ namespace OpenSim.Services.Interfaces
134 public string ServerURI 149 public string ServerURI
135 { 150 {
136 get { 151 get {
137 if ( m_serverURI != string.Empty ) { 152 if (!String.IsNullOrEmpty(m_serverURI)) {
138 return m_serverURI; 153 return m_serverURI;
139 } else { 154 } else {
140 return "http://" + m_externalHostName + ":" + m_httpPort + "/"; 155 if (HttpPort == 0)
156 return "http://" + m_externalHostName + "/";
157 else
158 return "http://" + m_externalHostName + ":" + HttpPort + "/";
141 } 159 }
142 } 160 }
143 set { 161 set {
144 if ( value.EndsWith("/") ) { 162 if (value.EndsWith("/")) {
145 m_serverURI = value; 163 m_serverURI = value;
146 } else { 164 } else {
147 m_serverURI = value + '/'; 165 m_serverURI = value + '/';
@@ -150,6 +168,16 @@ namespace OpenSim.Services.Interfaces
150 } 168 }
151 protected string m_serverURI; 169 protected string m_serverURI;
152 170
171 /// <summary>
172 /// Provides direct access to the 'm_serverURI' field, without returning a generated URL if m_serverURI is missing.
173 /// </summary>
174 public string RawServerURI
175 {
176 get { return m_serverURI; }
177 set { m_serverURI = value; }
178 }
179
180
153 public string RegionName 181 public string RegionName
154 { 182 {
155 get { return m_regionName; } 183 get { return m_regionName; }
@@ -157,22 +185,34 @@ namespace OpenSim.Services.Interfaces
157 } 185 }
158 protected string m_regionName = String.Empty; 186 protected string m_regionName = String.Empty;
159 187
188 /// <summary>
189 /// Region flags.
190 /// </summary>
191 /// <remarks>
192 /// If not set (chiefly if a robust service is running code pre OpenSim 0.8.1) then this will be null and
193 /// should be ignored. If you require flags information please use the separate IGridService.GetRegionFlags() call
194 /// XXX: This field is currently ignored when used in RegisterRegion, but could potentially be
195 /// used to set flags at this point.
196 /// </remarks>
197 public OpenSim.Framework.RegionFlags? RegionFlags { get; set; }
198
160 protected string m_externalHostName; 199 protected string m_externalHostName;
161 200
162 protected IPEndPoint m_internalEndPoint; 201 protected IPEndPoint m_internalEndPoint;
163 202
164 /// <summary> 203 /// <summary>
165 /// The co-ordinate of this region. 204 /// The co-ordinate of this region in region units.
166 /// </summary> 205 /// </summary>
167 public int RegionCoordX { get { return RegionLocX / (int)Constants.RegionSize; } } 206 public int RegionCoordX { get { return (int)Util.WorldToRegionLoc((uint)RegionLocX); } }
168 207
169 /// <summary> 208 /// <summary>
170 /// The co-ordinate of this region 209 /// The co-ordinate of this region in region units
171 /// </summary> 210 /// </summary>
172 public int RegionCoordY { get { return RegionLocY / (int)Constants.RegionSize; } } 211 public int RegionCoordY { get { return (int)Util.WorldToRegionLoc((uint)RegionLocY); } }
173 212
174 /// <summary> 213 /// <summary>
175 /// The location of this region in meters. 214 /// The location of this region in meters.
215 /// DANGER DANGER! Note that this name means something different in RegionInfo.
176 /// </summary> 216 /// </summary>
177 public int RegionLocX 217 public int RegionLocX
178 { 218 {
@@ -181,8 +221,12 @@ namespace OpenSim.Services.Interfaces
181 } 221 }
182 protected int m_regionLocX; 222 protected int m_regionLocX;
183 223
224 public int RegionSizeX { get; set; }
225 public int RegionSizeY { get; set; }
226
184 /// <summary> 227 /// <summary>
185 /// The location of this region in meters. 228 /// The location of this region in meters.
229 /// DANGER DANGER! Note that this name means something different in RegionInfo.
186 /// </summary> 230 /// </summary>
187 public int RegionLocY 231 public int RegionLocY
188 { 232 {
@@ -211,13 +255,18 @@ namespace OpenSim.Services.Interfaces
211 255
212 public GridRegion() 256 public GridRegion()
213 { 257 {
258 RegionSizeX = (int)Constants.RegionSize;
259 RegionSizeY = (int)Constants.RegionSize;
214 m_serverURI = string.Empty; 260 m_serverURI = string.Empty;
215 } 261 }
216 262
263 /*
217 public GridRegion(int regionLocX, int regionLocY, IPEndPoint internalEndPoint, string externalUri) 264 public GridRegion(int regionLocX, int regionLocY, IPEndPoint internalEndPoint, string externalUri)
218 { 265 {
219 m_regionLocX = regionLocX; 266 m_regionLocX = regionLocX;
220 m_regionLocY = regionLocY; 267 m_regionLocY = regionLocY;
268 RegionSizeX = (int)Constants.RegionSize;
269 RegionSizeY = (int)Constants.RegionSize;
221 270
222 m_internalEndPoint = internalEndPoint; 271 m_internalEndPoint = internalEndPoint;
223 m_externalHostName = externalUri; 272 m_externalHostName = externalUri;
@@ -227,26 +276,33 @@ namespace OpenSim.Services.Interfaces
227 { 276 {
228 m_regionLocX = regionLocX; 277 m_regionLocX = regionLocX;
229 m_regionLocY = regionLocY; 278 m_regionLocY = regionLocY;
279 RegionSizeX = (int)Constants.RegionSize;
280 RegionSizeY = (int)Constants.RegionSize;
230 281
231 m_externalHostName = externalUri; 282 m_externalHostName = externalUri;
232 283
233 m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)port); 284 m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)port);
234 } 285 }
286 */
235 287
236 public GridRegion(uint xcell, uint ycell) 288 public GridRegion(uint xcell, uint ycell)
237 { 289 {
238 m_regionLocX = (int)(xcell * Constants.RegionSize); 290 m_regionLocX = (int)Util.RegionToWorldLoc(xcell);
239 m_regionLocY = (int)(ycell * Constants.RegionSize); 291 m_regionLocY = (int)Util.RegionToWorldLoc(ycell);
292 RegionSizeX = (int)Constants.RegionSize;
293 RegionSizeY = (int)Constants.RegionSize;
240 } 294 }
241 295
242 public GridRegion(RegionInfo ConvertFrom) 296 public GridRegion(RegionInfo ConvertFrom)
243 { 297 {
244 m_regionName = ConvertFrom.RegionName; 298 m_regionName = ConvertFrom.RegionName;
245 m_regionLocX = (int)(ConvertFrom.RegionLocX * Constants.RegionSize); 299 m_regionLocX = (int)(ConvertFrom.WorldLocX);
246 m_regionLocY = (int)(ConvertFrom.RegionLocY * Constants.RegionSize); 300 m_regionLocY = (int)(ConvertFrom.WorldLocY);
301 RegionSizeX = (int)ConvertFrom.RegionSizeX;
302 RegionSizeY = (int)ConvertFrom.RegionSizeY;
247 m_internalEndPoint = ConvertFrom.InternalEndPoint; 303 m_internalEndPoint = ConvertFrom.InternalEndPoint;
248 m_externalHostName = ConvertFrom.ExternalHostName; 304 m_externalHostName = ConvertFrom.ExternalHostName;
249 m_httpPort = ConvertFrom.HttpPort; 305 HttpPort = ConvertFrom.HttpPort;
250 RegionID = ConvertFrom.RegionID; 306 RegionID = ConvertFrom.RegionID;
251 ServerURI = ConvertFrom.ServerURI; 307 ServerURI = ConvertFrom.ServerURI;
252 TerrainImage = ConvertFrom.RegionSettings.TerrainImageID; 308 TerrainImage = ConvertFrom.RegionSettings.TerrainImageID;
@@ -260,11 +316,14 @@ namespace OpenSim.Services.Interfaces
260 public GridRegion(GridRegion ConvertFrom) 316 public GridRegion(GridRegion ConvertFrom)
261 { 317 {
262 m_regionName = ConvertFrom.RegionName; 318 m_regionName = ConvertFrom.RegionName;
319 RegionFlags = ConvertFrom.RegionFlags;
263 m_regionLocX = ConvertFrom.RegionLocX; 320 m_regionLocX = ConvertFrom.RegionLocX;
264 m_regionLocY = ConvertFrom.RegionLocY; 321 m_regionLocY = ConvertFrom.RegionLocY;
322 RegionSizeX = ConvertFrom.RegionSizeX;
323 RegionSizeY = ConvertFrom.RegionSizeY;
265 m_internalEndPoint = ConvertFrom.InternalEndPoint; 324 m_internalEndPoint = ConvertFrom.InternalEndPoint;
266 m_externalHostName = ConvertFrom.ExternalHostName; 325 m_externalHostName = ConvertFrom.ExternalHostName;
267 m_httpPort = ConvertFrom.HttpPort; 326 HttpPort = ConvertFrom.HttpPort;
268 RegionID = ConvertFrom.RegionID; 327 RegionID = ConvertFrom.RegionID;
269 ServerURI = ConvertFrom.ServerURI; 328 ServerURI = ConvertFrom.ServerURI;
270 TerrainImage = ConvertFrom.TerrainImage; 329 TerrainImage = ConvertFrom.TerrainImage;
@@ -274,8 +333,112 @@ namespace OpenSim.Services.Interfaces
274 RegionSecret = ConvertFrom.RegionSecret; 333 RegionSecret = ConvertFrom.RegionSecret;
275 EstateOwner = ConvertFrom.EstateOwner; 334 EstateOwner = ConvertFrom.EstateOwner;
276 } 335 }
336
337 public GridRegion(Dictionary<string, object> kvp)
338 {
339 if (kvp.ContainsKey("uuid"))
340 RegionID = new UUID((string)kvp["uuid"]);
341
342 if (kvp.ContainsKey("locX"))
343 RegionLocX = Convert.ToInt32((string)kvp["locX"]);
344
345 if (kvp.ContainsKey("locY"))
346 RegionLocY = Convert.ToInt32((string)kvp["locY"]);
347
348 if (kvp.ContainsKey("sizeX"))
349 RegionSizeX = Convert.ToInt32((string)kvp["sizeX"]);
350 else
351 RegionSizeX = (int)Constants.RegionSize;
352
353 if (kvp.ContainsKey("sizeY"))
354 RegionSizeY = Convert.ToInt32((string)kvp["sizeY"]);
355 else
356 RegionSizeX = (int)Constants.RegionSize;
357
358 if (kvp.ContainsKey("regionName"))
359 RegionName = (string)kvp["regionName"];
360
361 if (kvp.ContainsKey("flags") && kvp["flags"] != null)
362 RegionFlags = (OpenSim.Framework.RegionFlags?)Convert.ToInt32((string)kvp["flags"]);
363
364 if (kvp.ContainsKey("serverIP"))
365 {
366 //int port = 0;
367 //Int32.TryParse((string)kvp["serverPort"], out port);
368 //IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["serverIP"]), port);
369 ExternalHostName = (string)kvp["serverIP"];
370 }
371 else
372 ExternalHostName = "127.0.0.1";
373
374 if (kvp.ContainsKey("serverPort"))
375 {
376 Int32 port = 0;
377 Int32.TryParse((string)kvp["serverPort"], out port);
378 InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port);
379 }
380
381 if (kvp.ContainsKey("serverHttpPort"))
382 {
383 UInt32 port = 0;
384 UInt32.TryParse((string)kvp["serverHttpPort"], out port);
385 HttpPort = port;
386 }
387
388 if (kvp.ContainsKey("serverURI"))
389 ServerURI = (string)kvp["serverURI"];
390
391 if (kvp.ContainsKey("regionMapTexture"))
392 UUID.TryParse((string)kvp["regionMapTexture"], out TerrainImage);
393
394 if (kvp.ContainsKey("parcelMapTexture"))
395 UUID.TryParse((string)kvp["parcelMapTexture"], out ParcelImage);
396
397 if (kvp.ContainsKey("access"))
398 Access = Byte.Parse((string)kvp["access"]);
399
400 if (kvp.ContainsKey("regionSecret"))
401 RegionSecret =(string)kvp["regionSecret"];
402
403 if (kvp.ContainsKey("owner_uuid"))
404 EstateOwner = new UUID(kvp["owner_uuid"].ToString());
405
406 if (kvp.ContainsKey("Token"))
407 Token = kvp["Token"].ToString();
408
409 // m_log.DebugFormat("{0} New GridRegion. id={1}, loc=<{2},{3}>, size=<{4},{5}>",
410 // LogHeader, RegionID, RegionLocX, RegionLocY, RegionSizeX, RegionSizeY);
411 }
412
413 public Dictionary<string, object> ToKeyValuePairs()
414 {
415 Dictionary<string, object> kvp = new Dictionary<string, object>();
416 kvp["uuid"] = RegionID.ToString();
417 kvp["locX"] = RegionLocX.ToString();
418 kvp["locY"] = RegionLocY.ToString();
419 kvp["sizeX"] = RegionSizeX.ToString();
420 kvp["sizeY"] = RegionSizeY.ToString();
421 kvp["regionName"] = RegionName;
277 422
278 # region Definition of equality 423 if (RegionFlags != null)
424 kvp["flags"] = ((int)RegionFlags).ToString();
425
426 kvp["serverIP"] = ExternalHostName; //ExternalEndPoint.Address.ToString();
427 kvp["serverHttpPort"] = HttpPort.ToString();
428 kvp["serverURI"] = ServerURI;
429 kvp["serverPort"] = InternalEndPoint.Port.ToString();
430 kvp["regionMapTexture"] = TerrainImage.ToString();
431 kvp["parcelMapTexture"] = ParcelImage.ToString();
432 kvp["access"] = Access.ToString();
433 kvp["regionSecret"] = RegionSecret;
434 kvp["owner_uuid"] = EstateOwner.ToString();
435 kvp["Token"] = Token.ToString();
436 // Maturity doesn't seem to exist in the DB
437
438 return kvp;
439 }
440
441 #region Definition of equality
279 442
280 /// <summary> 443 /// <summary>
281 /// Define equality as two regions having the same, non-zero UUID. 444 /// Define equality as two regions having the same, non-zero UUID.
@@ -362,86 +525,5 @@ namespace OpenSim.Services.Interfaces
362 { 525 {
363 get { return Util.UIntsToLong((uint)RegionLocX, (uint)RegionLocY); } 526 get { return Util.UIntsToLong((uint)RegionLocX, (uint)RegionLocY); }
364 } 527 }
365
366 public Dictionary<string, object> ToKeyValuePairs()
367 {
368 Dictionary<string, object> kvp = new Dictionary<string, object>();
369 kvp["uuid"] = RegionID.ToString();
370 kvp["locX"] = RegionLocX.ToString();
371 kvp["locY"] = RegionLocY.ToString();
372 kvp["regionName"] = RegionName;
373 kvp["serverIP"] = ExternalHostName; //ExternalEndPoint.Address.ToString();
374 kvp["serverHttpPort"] = HttpPort.ToString();
375 kvp["serverURI"] = ServerURI;
376 kvp["serverPort"] = InternalEndPoint.Port.ToString();
377 kvp["regionMapTexture"] = TerrainImage.ToString();
378 kvp["parcelMapTexture"] = ParcelImage.ToString();
379 kvp["access"] = Access.ToString();
380 kvp["regionSecret"] = RegionSecret;
381 kvp["owner_uuid"] = EstateOwner.ToString();
382 kvp["Token"] = Token.ToString();
383 // Maturity doesn't seem to exist in the DB
384 return kvp;
385 }
386
387 public GridRegion(Dictionary<string, object> kvp)
388 {
389 if (kvp.ContainsKey("uuid"))
390 RegionID = new UUID((string)kvp["uuid"]);
391
392 if (kvp.ContainsKey("locX"))
393 RegionLocX = Convert.ToInt32((string)kvp["locX"]);
394
395 if (kvp.ContainsKey("locY"))
396 RegionLocY = Convert.ToInt32((string)kvp["locY"]);
397
398 if (kvp.ContainsKey("regionName"))
399 RegionName = (string)kvp["regionName"];
400
401 if (kvp.ContainsKey("serverIP"))
402 {
403 //int port = 0;
404 //Int32.TryParse((string)kvp["serverPort"], out port);
405 //IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["serverIP"]), port);
406 ExternalHostName = (string)kvp["serverIP"];
407 }
408 else
409 ExternalHostName = "127.0.0.1";
410
411 if (kvp.ContainsKey("serverPort"))
412 {
413 Int32 port = 0;
414 Int32.TryParse((string)kvp["serverPort"], out port);
415 InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port);
416 }
417
418 if (kvp.ContainsKey("serverHttpPort"))
419 {
420 UInt32 port = 0;
421 UInt32.TryParse((string)kvp["serverHttpPort"], out port);
422 HttpPort = port;
423 }
424
425 if (kvp.ContainsKey("serverURI"))
426 ServerURI = (string)kvp["serverURI"];
427
428 if (kvp.ContainsKey("regionMapTexture"))
429 UUID.TryParse((string)kvp["regionMapTexture"], out TerrainImage);
430
431 if (kvp.ContainsKey("parcelMapTexture"))
432 UUID.TryParse((string)kvp["parcelMapTexture"], out ParcelImage);
433
434 if (kvp.ContainsKey("access"))
435 Access = Byte.Parse((string)kvp["access"]);
436
437 if (kvp.ContainsKey("regionSecret"))
438 RegionSecret =(string)kvp["regionSecret"];
439
440 if (kvp.ContainsKey("owner_uuid"))
441 EstateOwner = new UUID(kvp["owner_uuid"].ToString());
442
443 if (kvp.ContainsKey("Token"))
444 Token = kvp["Token"].ToString();
445 }
446 } 528 }
447} 529} \ No newline at end of file
diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs
index 3dc877a..5e012fb 100644
--- a/OpenSim/Services/Interfaces/IHypergridServices.cs
+++ b/OpenSim/Services/Interfaces/IHypergridServices.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -37,31 +37,71 @@ namespace OpenSim.Services.Interfaces
37 public interface IGatekeeperService 37 public interface IGatekeeperService
38 { 38 {
39 bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason); 39 bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string externalName, out string imageURL, out string reason);
40 GridRegion GetHyperlinkRegion(UUID regionID); 40
41 /// <summary>
42 /// Returns the region a Hypergrid visitor should enter.
43 /// </summary>
44 /// <remarks>
45 /// Usually the returned region will be the requested region. But the grid can choose to
46 /// redirect the user to another region: e.g., a default gateway region.
47 /// </remarks>
48 /// <param name="regionID">The region the visitor *wants* to enter</param>
49 /// <param name="agentID">The visitor's User ID. Will be missing (UUID.Zero) in older OpenSims.</param>
50 /// <param name="agentHomeURI">The visitor's Home URI. Will be missing (null) in older OpenSims.</param>
51 /// <param name="message">[out] A message to show to the user (optional, may be null)</param>
52 /// <returns>The region the visitor should enter, or null if no region can be found / is allowed</returns>
53 GridRegion GetHyperlinkRegion(UUID regionID, UUID agentID, string agentHomeURI, out string message);
41 54
42 bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination, out string reason); 55 bool LoginAgent(GridRegion source, AgentCircuitData aCircuit, GridRegion destination, out string reason);
43 56
44 } 57 }
45 58
46 /// <summary>
47 /// HG1.5 only
48 /// </summary>
49 public interface IUserAgentService 59 public interface IUserAgentService
50 { 60 {
51 // called by login service only 61 bool LoginAgentToGrid(GridRegion source, AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, bool fromLogin, out string reason);
52 bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, IPEndPoint clientIP, out string reason); 62
53 // called by simulators
54 bool LoginAgentToGrid(AgentCircuitData agent, GridRegion gatekeeper, GridRegion finalDestination, out string reason);
55 void LogoutAgent(UUID userID, UUID sessionID); 63 void LogoutAgent(UUID userID, UUID sessionID);
64
65 /// <summary>
66 /// Returns the home region of a remote user.
67 /// </summary>
68 /// <returns>On success: the user's home region. If the user doesn't exist: null.</returns>
69 /// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
56 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt); 70 GridRegion GetHomeRegion(UUID userID, out Vector3 position, out Vector3 lookAt);
71
72 /// <summary>
73 /// Returns the Server URLs of a remote user.
74 /// </summary>
75 /// <returns>On success: the user's Server URLs. If the user doesn't exist: an empty dictionary.</returns>
76 /// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
57 Dictionary<string, object> GetServerURLs(UUID userID); 77 Dictionary<string, object> GetServerURLs(UUID userID);
58 Dictionary<string,object> GetUserInfo(UUID userID);
59 78
79 /// <summary>
80 /// Returns the UserInfo of a remote user.
81 /// </summary>
82 /// <returns>On success: the user's UserInfo. If the user doesn't exist: an empty dictionary.</returns>
83 /// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
84 Dictionary<string, object> GetUserInfo(UUID userID);
85
86 /// <summary>
87 /// Returns the current location of a remote user.
88 /// </summary>
89 /// <returns>On success: the user's Server URLs. If the user doesn't exist: "".</returns>
90 /// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
60 string LocateUser(UUID userID); 91 string LocateUser(UUID userID);
61 // Tries to get the universal user identifier for the targetUserId 92
62 // on behalf of the userID 93 /// <summary>
94 /// Returns the Universal User Identifier for 'targetUserID' on behalf of 'userID'.
95 /// </summary>
96 /// <returns>On success: the user's UUI. If the user doesn't exist: "".</returns>
97 /// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
63 string GetUUI(UUID userID, UUID targetUserID); 98 string GetUUI(UUID userID, UUID targetUserID);
64 99
100 /// <summary>
101 /// Returns the remote user that has the given name.
102 /// </summary>
103 /// <returns>On success: the user's UUID. If the user doesn't exist: UUID.Zero.</returns>
104 /// <remarks>Throws an exception if an error occurs (e.g., can't contact the server).</remarks>
65 UUID GetUUID(String first, String last); 105 UUID GetUUID(String first, String last);
66 106
67 // Returns the local friends online 107 // Returns the local friends online
diff --git a/OpenSim/Services/Interfaces/IInventoryService.cs b/OpenSim/Services/Interfaces/IInventoryService.cs
index a8bfe47..4289bba 100644
--- a/OpenSim/Services/Interfaces/IInventoryService.cs
+++ b/OpenSim/Services/Interfaces/IInventoryService.cs
@@ -55,23 +55,6 @@ namespace OpenSim.Services.Interfaces
55 List<InventoryFolderBase> GetInventorySkeleton(UUID userId); 55 List<InventoryFolderBase> GetInventorySkeleton(UUID userId);
56 56
57 /// <summary> 57 /// <summary>
58 /// Synchronous inventory fetch.
59 /// </summary>
60 /// <param name="userID"></param>
61 /// <returns></returns>
62 [Obsolete]
63 InventoryCollection GetUserInventory(UUID userID);
64
65 /// <summary>
66 /// Request the inventory for a user. This is an asynchronous operation that will call the callback when the
67 /// inventory has been received
68 /// </summary>
69 /// <param name="userID"></param>
70 /// <param name="callback"></param>
71 [Obsolete]
72 void GetUserInventory(UUID userID, InventoryReceiptCallback callback);
73
74 /// <summary>
75 /// Retrieve the root inventory folder for the given user. 58 /// Retrieve the root inventory folder for the given user.
76 /// </summary> 59 /// </summary>
77 /// <param name="userID"></param> 60 /// <param name="userID"></param>
@@ -84,15 +67,23 @@ namespace OpenSim.Services.Interfaces
84 /// <param name="userID"></param> 67 /// <param name="userID"></param>
85 /// <param name="type"></param> 68 /// <param name="type"></param>
86 /// <returns></returns> 69 /// <returns></returns>
87 InventoryFolderBase GetFolderForType(UUID userID, AssetType type); 70 InventoryFolderBase GetFolderForType(UUID userID, FolderType type);
88 71
89 /// <summary> 72 /// <summary>
90 /// Gets everything (folders and items) inside a folder 73 /// Gets everything (folders and items) inside a folder
91 /// </summary> 74 /// </summary>
92 /// <param name="userId"></param> 75 /// <param name="userId"></param>
93 /// <param name="folderID"></param> 76 /// <param name="folderID"></param>
94 /// <returns></returns> 77 /// <returns>Inventory content. null if the request failed.</returns>
95 InventoryCollection GetFolderContent(UUID userID, UUID folderID); 78 InventoryCollection GetFolderContent(UUID userID, UUID folderID);
79
80 /// <summary>
81 /// Gets everything (folders and items) inside a folder
82 /// </summary>
83 /// <param name="userId"></param>
84 /// <param name="folderIDs"></param>
85 /// <returns>Inventory content.</returns>
86 InventoryCollection[] GetMultipleFoldersContent(UUID userID, UUID[] folderIDs);
96 87
97 /// <summary> 88 /// <summary>
98 /// Gets the items inside a folder 89 /// Gets the items inside a folder
@@ -173,6 +164,13 @@ namespace OpenSim.Services.Interfaces
173 InventoryItemBase GetItem(InventoryItemBase item); 164 InventoryItemBase GetItem(InventoryItemBase item);
174 165
175 /// <summary> 166 /// <summary>
167 /// Get multiple items, given by their UUIDs
168 /// </summary>
169 /// <param name="item"></param>
170 /// <returns>null if no item was found, otherwise the found item</returns>
171 InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] ids);
172
173 /// <summary>
176 /// Get a folder, given by its UUID 174 /// Get a folder, given by its UUID
177 /// </summary> 175 /// </summary>
178 /// <param name="folder"></param> 176 /// <param name="folder"></param>
diff --git a/OpenSim/Services/Interfaces/IMapImageService.cs b/OpenSim/Services/Interfaces/IMapImageService.cs
index a7b2cf1..78daa5f 100644
--- a/OpenSim/Services/Interfaces/IMapImageService.cs
+++ b/OpenSim/Services/Interfaces/IMapImageService.cs
@@ -35,6 +35,7 @@ namespace OpenSim.Services.Interfaces
35 { 35 {
36 //List<MapBlockData> GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY); 36 //List<MapBlockData> GetMapBlocks(UUID scopeID, int minX, int minY, int maxX, int maxY);
37 bool AddMapTile(int x, int y, byte[] imageData, out string reason); 37 bool AddMapTile(int x, int y, byte[] imageData, out string reason);
38 bool RemoveMapTile(int x, int y, out string reason);
38 byte[] GetMapTile(string fileName, out string format); 39 byte[] GetMapTile(string fileName, out string format);
39 } 40 }
40} 41}
diff --git a/OpenSim/Services/Interfaces/IOfflineIMService.cs b/OpenSim/Services/Interfaces/IOfflineIMService.cs
index 2848967..588aaaf 100644
--- a/OpenSim/Services/Interfaces/IOfflineIMService.cs
+++ b/OpenSim/Services/Interfaces/IOfflineIMService.cs
@@ -35,7 +35,14 @@ namespace OpenSim.Services.Interfaces
35 public interface IOfflineIMService 35 public interface IOfflineIMService
36 { 36 {
37 List<GridInstantMessage> GetMessages(UUID principalID); 37 List<GridInstantMessage> GetMessages(UUID principalID);
38
38 bool StoreMessage(GridInstantMessage im, out string reason); 39 bool StoreMessage(GridInstantMessage im, out string reason);
40
41 /// <summary>
42 /// Delete messages to or from this user (or group).
43 /// </summary>
44 /// <param name="userID">A user or group ID</param>
45 void DeleteMessages(UUID userID);
39 } 46 }
40 47
41 public class OfflineIMDataUtils 48 public class OfflineIMDataUtils
diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs
index b10a85c..8a25509 100644
--- a/OpenSim/Services/Interfaces/ISimulationService.cs
+++ b/OpenSim/Services/Interfaces/ISimulationService.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic;
29using OpenSim.Framework; 30using OpenSim.Framework;
30using OpenMetaverse; 31using OpenMetaverse;
31 32
@@ -33,6 +34,20 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion;
33 34
34namespace OpenSim.Services.Interfaces 35namespace OpenSim.Services.Interfaces
35{ 36{
37 public class EntityTransferContext
38 {
39 public EntityTransferContext()
40 {
41 InboundVersion = VersionInfo.SimulationServiceVersionAcceptedMax;
42 OutboundVersion = VersionInfo.SimulationServiceVersionSupportedMax;
43 VariableWearablesSupported = false;
44 }
45
46 public float InboundVersion { get; set; }
47 public float OutboundVersion { get; set; }
48 public bool VariableWearablesSupported { get; set; }
49 }
50
36 public interface ISimulationService 51 public interface ISimulationService
37 { 52 {
38 /// <summary> 53 /// <summary>
@@ -53,11 +68,13 @@ namespace OpenSim.Services.Interfaces
53 /// <summary> 68 /// <summary>
54 /// Ask the simulator hosting the destination to create an agent on that region. 69 /// Ask the simulator hosting the destination to create an agent on that region.
55 /// </summary> 70 /// </summary>
71 /// <param name="source">The region that the user is coming from. Will be null if the user
72 /// logged-in directly, or arrived from a simulator that doesn't send this parameter.</param>
56 /// <param name="destination"></param> 73 /// <param name="destination"></param>
57 /// <param name="aCircuit"></param> 74 /// <param name="aCircuit"></param>
58 /// <param name="flags"></param> 75 /// <param name="flags"></param>
59 /// <param name="reason">Reason message in the event of a failure.</param> 76 /// <param name="reason">Reason message in the event of a failure.</param>
60 bool CreateAgent(GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason); 77 bool CreateAgent(GridRegion source, GridRegion destination, AgentCircuitData aCircuit, uint flags, out string reason);
61 78
62 /// <summary> 79 /// <summary>
63 /// Full child agent update. 80 /// Full child agent update.
@@ -75,9 +92,21 @@ namespace OpenSim.Services.Interfaces
75 /// <returns></returns> 92 /// <returns></returns>
76 bool UpdateAgent(GridRegion destination, AgentPosition data); 93 bool UpdateAgent(GridRegion destination, AgentPosition data);
77 94
78 bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent); 95 /// <summary>
79 96 /// Returns whether a propspective user is allowed to visit the region.
80 bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason); 97 /// </summary>
98 /// <param name="destination">Desired destination</param>
99 /// <param name="agentID">The visitor's User ID</param>
100 /// <param name="agentHomeURI">The visitor's Home URI. Will be missing (null) in older OpenSims.</param>
101 /// <param name="viaTeleport">True: via teleport; False: via cross (walking)</param>
102 /// <param name="position">Position in the region</param>
103 /// <param name="sversion">
104 /// Version that the requesting simulator is runing. If null then no version check is carried out.
105 /// </param>
106 /// <param name="version">Version that the target simulator is running</param>
107 /// <param name="reason">[out] Optional error message</param>
108 /// <returns>True: ok; False: not allowed</returns>
109 bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List<UUID> features, EntityTransferContext ctx, out string reason);
81 110
82 /// <summary> 111 /// <summary>
83 /// Message from receiving region to departing region, telling it got contacted by the client. 112 /// Message from receiving region to departing region, telling it got contacted by the client.
@@ -95,7 +124,7 @@ namespace OpenSim.Services.Interfaces
95 /// <param name="regionHandle"></param> 124 /// <param name="regionHandle"></param>
96 /// <param name="id"></param> 125 /// <param name="id"></param>
97 /// <returns></returns> 126 /// <returns></returns>
98 bool CloseAgent(GridRegion destination, UUID id); 127 bool CloseAgent(GridRegion destination, UUID id, string auth_token);
99 128
100 #endregion Agents 129 #endregion Agents
101 130
diff --git a/OpenSim/Services/Interfaces/IUserAccountService.cs b/OpenSim/Services/Interfaces/IUserAccountService.cs
index 1b85980..2f7702c 100644
--- a/OpenSim/Services/Interfaces/IUserAccountService.cs
+++ b/OpenSim/Services/Interfaces/IUserAccountService.cs
@@ -189,5 +189,7 @@ namespace OpenSim.Services.Interfaces
189 /// <param name="data"></param> 189 /// <param name="data"></param>
190 /// <returns></returns> 190 /// <returns></returns>
191 bool StoreUserAccount(UserAccount data); 191 bool StoreUserAccount(UserAccount data);
192
193 void InvalidateCache(UUID userID);
192 } 194 }
193} 195}
diff --git a/OpenSim/Services/Interfaces/IUserManagement.cs b/OpenSim/Services/Interfaces/IUserManagement.cs
new file mode 100644
index 0000000..9e560d5
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IUserManagement.cs
@@ -0,0 +1,97 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30
31using OpenMetaverse;
32
33namespace OpenSim.Services.Interfaces
34{
35 /// <summary>
36 /// This maintains the relationship between a UUID and a user name.
37 /// </summary>
38 public interface IUserManagement
39 {
40 string GetUserName(UUID uuid);
41 string GetUserHomeURL(UUID uuid);
42 string GetUserUUI(UUID uuid);
43 bool GetUserUUI(UUID userID, out string uui);
44 string GetUserServerURL(UUID uuid, string serverType);
45
46 /// <summary>
47 /// Get user ID by the given name.
48 /// </summary>
49 /// <param name="name"></param>
50 /// <returns>UUID.Zero if no user with that name is found or if the name is "Unknown User"</returns>
51 UUID GetUserIdByName(string name);
52
53 /// <summary>
54 /// Get user ID by the given name.
55 /// </summary>
56 /// <param name="firstName"></param>
57 /// <param name="lastName"></param>
58 /// <returns>UUID.Zero if no user with that name is found or if the name is "Unknown User"</returns>
59 UUID GetUserIdByName(string firstName, string lastName);
60
61 /// <summary>
62 /// Add a user.
63 /// </summary>
64 /// <remarks>
65 /// If an account is found for the UUID, then the names in this will be used rather than any information
66 /// extracted from creatorData.
67 /// </remarks>
68 /// <param name="uuid"></param>
69 /// <param name="creatorData">The creator data for this user.</param>
70 void AddUser(UUID uuid, string creatorData);
71
72 /// <summary>
73 /// Add a user.
74 /// </summary>
75 /// <remarks>
76 /// The UUID is related to the name without any other checks being performed, such as user account presence.
77 /// </remarks>
78 /// <param name="uuid"></param>
79 /// <param name="firstName"></param>
80 /// <param name="lastName"></param>
81 void AddUser(UUID uuid, string firstName, string lastName);
82
83 /// <summary>
84 /// Add a user.
85 /// </summary>
86 /// <remarks>
87 /// The arguments apart from uuid are formed into a creatorData string and processing proceeds as for the
88 /// AddUser(UUID uuid, string creatorData) method.
89 /// </remarks>
90 /// <param name="uuid"></param>
91 /// <param name="firstName"></param>
92 /// <param name="profileURL"></param>
93 void AddUser(UUID uuid, string firstName, string lastName, string homeURL);
94
95 bool IsLocalGridUser(UUID uuid);
96 }
97}
diff --git a/OpenSim/Services/Interfaces/IUserProfilesService.cs b/OpenSim/Services/Interfaces/IUserProfilesService.cs
new file mode 100644
index 0000000..121baa8
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IUserProfilesService.cs
@@ -0,0 +1,80 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using OpenSim.Framework;
30using OpenMetaverse;
31using OpenMetaverse.StructuredData;
32
33namespace OpenSim.Services.Interfaces
34{
35 public interface IUserProfilesService
36 {
37 #region Classifieds
38 OSD AvatarClassifiedsRequest(UUID creatorId);
39 bool ClassifiedUpdate(UserClassifiedAdd ad, ref string result);
40 bool ClassifiedInfoRequest(ref UserClassifiedAdd ad, ref string result);
41 bool ClassifiedDelete(UUID recordId);
42 #endregion Classifieds
43
44 #region Picks
45 OSD AvatarPicksRequest(UUID creatorId);
46 bool PickInfoRequest(ref UserProfilePick pick, ref string result);
47 bool PicksUpdate(ref UserProfilePick pick, ref string result);
48 bool PicksDelete(UUID pickId);
49 #endregion Picks
50
51 #region Notes
52 bool AvatarNotesRequest(ref UserProfileNotes note);
53 bool NotesUpdate(ref UserProfileNotes note, ref string result);
54 #endregion Notes
55
56 #region Profile Properties
57 bool AvatarPropertiesRequest(ref UserProfileProperties prop, ref string result);
58 bool AvatarPropertiesUpdate(ref UserProfileProperties prop, ref string result);
59 #endregion Profile Properties
60
61 #region User Preferences
62 bool UserPreferencesRequest(ref UserPreferences pref, ref string result);
63 bool UserPreferencesUpdate(ref UserPreferences pref, ref string result);
64 #endregion User Preferences
65
66 #region Interests
67 bool AvatarInterestsUpdate(UserProfileProperties prop, ref string result);
68 #endregion Interests
69
70 #region Utility
71 OSD AvatarImageAssetsRequest(UUID avatarId);
72 #endregion Utility
73
74 #region UserData
75 bool RequestUserAppData(ref UserAppData prop, ref string result);
76 bool SetUserAppData(UserAppData prop, ref string result);
77 #endregion UserData
78 }
79}
80
diff --git a/OpenSim/Services/Interfaces/OpenProfileClient.cs b/OpenSim/Services/Interfaces/OpenProfileClient.cs
new file mode 100644
index 0000000..bda8151
--- /dev/null
+++ b/OpenSim/Services/Interfaces/OpenProfileClient.cs
@@ -0,0 +1,134 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Net;
32using System.Net.Sockets;
33using System.Reflection;
34using System.Text;
35using System.Xml;
36using log4net;
37using OpenMetaverse;
38using OpenSim.Framework;
39
40namespace OpenSim.Services.UserProfilesService
41{
42 /// <summary>
43 /// A client for accessing a profile server using the OpenProfile protocol.
44 /// </summary>
45 /// <remarks>
46 /// This class was adapted from the full OpenProfile class. Since it's only a client, and not a server,
47 /// it's much simpler.
48 /// </remarks>
49 public class OpenProfileClient
50 {
51// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private string m_serverURI;
54
55 /// <summary>
56 /// Creates a client for accessing a foreign grid's profile server using the OpenProfile protocol.
57 /// </summary>
58 /// <param name="serverURI">The grid's profile server URL</param>
59 public OpenProfileClient(string serverURI)
60 {
61 m_serverURI = serverURI;
62 }
63
64 /// <summary>
65 /// Gets an avatar's profile using the OpenProfile protocol.
66 /// </summary>
67 /// <param name="props">On success, this will contain the avatar's profile</param>
68 /// <returns>Success/failure</returns>
69 /// <remarks>
70 /// There are two profile modules currently in use in OpenSim: the older one is OpenProfile, and the newer
71 /// one is UserProfileModule (this file). This method attempts to read an avatar's profile from a foreign
72 /// grid using the OpenProfile protocol.
73 /// </remarks>
74 public bool RequestAvatarPropertiesUsingOpenProfile(ref UserProfileProperties props)
75 {
76 Hashtable ReqHash = new Hashtable();
77 ReqHash["avatar_id"] = props.UserId.ToString();
78
79 Hashtable profileData = XMLRPCRequester.SendRequest(ReqHash, "avatar_properties_request", m_serverURI);
80
81 if (profileData == null)
82 return false;
83 if (!profileData.ContainsKey("data"))
84 return false;
85
86 ArrayList dataArray = (ArrayList)profileData["data"];
87
88 if (dataArray == null || dataArray[0] == null)
89 return false;
90 profileData = (Hashtable)dataArray[0];
91
92 props.WebUrl = string.Empty;
93 props.AboutText = String.Empty;
94 props.FirstLifeText = String.Empty;
95 props.ImageId = UUID.Zero;
96 props.FirstLifeImageId = UUID.Zero;
97 props.PartnerId = UUID.Zero;
98
99 if (profileData["ProfileUrl"] != null)
100 props.WebUrl = profileData["ProfileUrl"].ToString();
101 if (profileData["AboutText"] != null)
102 props.AboutText = profileData["AboutText"].ToString();
103 if (profileData["FirstLifeAboutText"] != null)
104 props.FirstLifeText = profileData["FirstLifeAboutText"].ToString();
105 if (profileData["Image"] != null)
106 props.ImageId = new UUID(profileData["Image"].ToString());
107 if (profileData["FirstLifeImage"] != null)
108 props.FirstLifeImageId = new UUID(profileData["FirstLifeImage"].ToString());
109 if (profileData["Partner"] != null)
110 props.PartnerId = new UUID(profileData["Partner"].ToString());
111
112 props.WantToMask = 0;
113 props.WantToText = String.Empty;
114 props.SkillsMask = 0;
115 props.SkillsText = String.Empty;
116 props.Language = String.Empty;
117
118 if (profileData["wantmask"] != null)
119 props.WantToMask = Convert.ToInt32(profileData["wantmask"].ToString());
120 if (profileData["wanttext"] != null)
121 props.WantToText = profileData["wanttext"].ToString();
122
123 if (profileData["skillsmask"] != null)
124 props.SkillsMask = Convert.ToInt32(profileData["skillsmask"].ToString());
125 if (profileData["skillstext"] != null)
126 props.SkillsText = profileData["skillstext"].ToString();
127
128 if (profileData["languages"] != null)
129 props.Language = profileData["languages"].ToString();
130
131 return true;
132 }
133 }
134} \ No newline at end of file
diff --git a/OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs b/OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs
index 4723553..01cafbf 100644
--- a/OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/InventoryService/LibraryService.cs b/OpenSim/Services/InventoryService/LibraryService.cs
index f90895b..c4a5572 100644
--- a/OpenSim/Services/InventoryService/LibraryService.cs
+++ b/OpenSim/Services/InventoryService/LibraryService.cs
@@ -38,6 +38,7 @@ using OpenSim.Services.Interfaces;
38using log4net; 38using log4net;
39using Nini.Config; 39using Nini.Config;
40using OpenMetaverse; 40using OpenMetaverse;
41using PermissionMask = OpenSim.Framework.PermissionMask;
41 42
42namespace OpenSim.Services.InventoryService 43namespace OpenSim.Services.InventoryService
43{ 44{
diff --git a/OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs b/OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs
index 41ad9f8..ec89097 100644
--- a/OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs
index 7bad4b0..b75193f 100644
--- a/OpenSim/Services/InventoryService/XInventoryService.cs
+++ b/OpenSim/Services/InventoryService/XInventoryService.cs
@@ -111,40 +111,48 @@ namespace OpenSim.Services.InventoryService
111 111
112 if (rootFolder == null) 112 if (rootFolder == null)
113 { 113 {
114 rootFolder = ConvertToOpenSim(CreateFolder(principalID, UUID.Zero, (int)AssetType.RootFolder, "My Inventory")); 114 rootFolder = ConvertToOpenSim(CreateFolder(principalID, UUID.Zero, (int)FolderType.Root, InventoryFolderBase.ROOT_FOLDER_NAME));
115 result = true; 115 result = true;
116 } 116 }
117 117
118 XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootFolder.ID); 118 XInventoryFolder[] sysFolders = GetSystemFolders(principalID, rootFolder.ID);
119 119
120 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Animation) return true; return false; })) 120 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Animation) return true; return false; }))
121 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Animation, "Animations"); 121 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Animation, "Animations");
122 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Bodypart) return true; return false; })) 122 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.BodyPart) return true; return false; }))
123 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Bodypart, "Body Parts"); 123 CreateFolder(principalID, rootFolder.ID, (int)FolderType.BodyPart, "Body Parts");
124 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.CallingCard) return true; return false; })) 124 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.CallingCard) return true; return false; }))
125 CreateFolder(principalID, rootFolder.ID, (int)AssetType.CallingCard, "Calling Cards"); 125 {
126 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Clothing) return true; return false; })) 126 XInventoryFolder folder = CreateFolder(principalID, rootFolder.ID, (int)FolderType.CallingCard, "Calling Cards");
127 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Clothing, "Clothing"); 127 folder = CreateFolder(principalID, folder.folderID, (int)FolderType.CallingCard, "Friends");
128 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Gesture) return true; return false; })) 128 CreateFolder(principalID, folder.folderID, (int)FolderType.CallingCard, "All");
129 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Gesture, "Gestures"); 129 }
130 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Landmark) return true; return false; })) 130 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Clothing) return true; return false; }))
131 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Landmark, "Landmarks"); 131 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Clothing, "Clothing");
132 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.LostAndFoundFolder) return true; return false; })) 132 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.CurrentOutfit) return true; return false; }))
133 CreateFolder(principalID, rootFolder.ID, (int)AssetType.LostAndFoundFolder, "Lost And Found"); 133 CreateFolder(principalID, rootFolder.ID, (int)FolderType.CurrentOutfit, "Current Outfit");
134 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Notecard) return true; return false; })) 134 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Favorites) return true; return false; }))
135 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Notecard, "Notecards"); 135 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Favorites, "Favorites");
136 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Object) return true; return false; })) 136 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Gesture) return true; return false; }))
137 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Object, "Objects"); 137 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Gesture, "Gestures");
138 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.SnapshotFolder) return true; return false; })) 138 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Landmark) return true; return false; }))
139 CreateFolder(principalID, rootFolder.ID, (int)AssetType.SnapshotFolder, "Photo Album"); 139 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Landmark, "Landmarks");
140 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.LSLText) return true; return false; })) 140 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.LostAndFound) return true; return false; }))
141 CreateFolder(principalID, rootFolder.ID, (int)AssetType.LSLText, "Scripts"); 141 CreateFolder(principalID, rootFolder.ID, (int)FolderType.LostAndFound, "Lost And Found");
142 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Sound) return true; return false; })) 142 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Notecard) return true; return false; }))
143 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Sound, "Sounds"); 143 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Notecard, "Notecards");
144 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Texture) return true; return false; })) 144 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Object) return true; return false; }))
145 CreateFolder(principalID, rootFolder.ID, (int)AssetType.Texture, "Textures"); 145 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Object, "Objects");
146 if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.TrashFolder) return true; return false; })) 146 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Snapshot) return true; return false; }))
147 CreateFolder(principalID, rootFolder.ID, (int)AssetType.TrashFolder, "Trash"); 147 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Snapshot, "Photo Album");
148 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.LSLText) return true; return false; }))
149 CreateFolder(principalID, rootFolder.ID, (int)FolderType.LSLText, "Scripts");
150 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Sound) return true; return false; }))
151 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Sound, "Sounds");
152 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Texture) return true; return false; }))
153 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Texture, "Textures");
154 if (!Array.Exists(sysFolders, delegate(XInventoryFolder f) { if (f.type == (int)FolderType.Trash) return true; return false; }))
155 CreateFolder(principalID, rootFolder.ID, (int)FolderType.Trash, "Trash");
148 156
149 return result; 157 return result;
150 } 158 }
@@ -220,7 +228,7 @@ namespace OpenSim.Services.InventoryService
220 XInventoryFolder root = null; 228 XInventoryFolder root = null;
221 foreach (XInventoryFolder folder in folders) 229 foreach (XInventoryFolder folder in folders)
222 { 230 {
223 if (folder.folderName == "My Inventory") 231 if (folder.folderName == InventoryFolderBase.ROOT_FOLDER_NAME)
224 { 232 {
225 root = folder; 233 root = folder;
226 break; 234 break;
@@ -233,7 +241,7 @@ namespace OpenSim.Services.InventoryService
233 return ConvertToOpenSim(root); 241 return ConvertToOpenSim(root);
234 } 242 }
235 243
236 public virtual InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) 244 public virtual InventoryFolderBase GetFolderForType(UUID principalID, FolderType type)
237 { 245 {
238// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID); 246// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID);
239 247
@@ -251,11 +259,11 @@ namespace OpenSim.Services.InventoryService
251 return GetSystemFolderForType(rootFolder, type); 259 return GetSystemFolderForType(rootFolder, type);
252 } 260 }
253 261
254 private InventoryFolderBase GetSystemFolderForType(InventoryFolderBase rootFolder, AssetType type) 262 private InventoryFolderBase GetSystemFolderForType(InventoryFolderBase rootFolder, FolderType type)
255 { 263 {
256// m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID); 264 //m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0}", type);
257 265
258 if (type == AssetType.RootFolder) 266 if (type == FolderType.Root)
259 return rootFolder; 267 return rootFolder;
260 268
261 XInventoryFolder[] folders = m_Database.GetFolders( 269 XInventoryFolder[] folders = m_Database.GetFolders(
@@ -264,13 +272,13 @@ namespace OpenSim.Services.InventoryService
264 272
265 if (folders.Length == 0) 273 if (folders.Length == 0)
266 { 274 {
267// m_log.WarnFormat("[XINVENTORY SERVICE]: Found no folder for type {0} for user {1}", type, principalID); 275 //m_log.WarnFormat("[XINVENTORY SERVICE]: Found no folder for type {0} ", type);
268 return null; 276 return null;
269 } 277 }
270 278
271// m_log.DebugFormat( 279 //m_log.DebugFormat(
272// "[XINVENTORY SERVICE]: Found folder {0} {1} for type {2} for user {3}", 280 // "[XINVENTORY SERVICE]: Found folder {0} {1} for type {2}",
273// folders[0].folderName, folders[0].folderID, type, principalID); 281 // folders[0].folderName, folders[0].folderID, type);
274 282
275 return ConvertToOpenSim(folders[0]); 283 return ConvertToOpenSim(folders[0]);
276 } 284 }
@@ -283,7 +291,7 @@ namespace OpenSim.Services.InventoryService
283 // 291 //
284 //m_log.DebugFormat("[XINVENTORY SERVICE]: Fetch contents for folder {0}", folderID.ToString()); 292 //m_log.DebugFormat("[XINVENTORY SERVICE]: Fetch contents for folder {0}", folderID.ToString());
285 InventoryCollection inventory = new InventoryCollection(); 293 InventoryCollection inventory = new InventoryCollection();
286 inventory.UserID = principalID; 294 inventory.OwnerID = principalID;
287 inventory.Folders = new List<InventoryFolderBase>(); 295 inventory.Folders = new List<InventoryFolderBase>();
288 inventory.Items = new List<InventoryItemBase>(); 296 inventory.Items = new List<InventoryItemBase>();
289 297
@@ -307,8 +315,27 @@ namespace OpenSim.Services.InventoryService
307 inventory.Items.Add(ConvertToOpenSim(i)); 315 inventory.Items.Add(ConvertToOpenSim(i));
308 } 316 }
309 317
318 InventoryFolderBase f = new InventoryFolderBase(folderID, principalID);
319 f = GetFolder(f);
320 if (f != null)
321 {
322 inventory.Version = f.Version;
323 inventory.OwnerID = f.Owner;
324 }
325 inventory.FolderID = folderID;
326
310 return inventory; 327 return inventory;
311 } 328 }
329
330 public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs)
331 {
332 InventoryCollection[] multiple = new InventoryCollection[folderIDs.Length];
333 int i = 0;
334 foreach (UUID fid in folderIDs)
335 multiple[i++] = GetFolderContent(principalID, fid);
336
337 return multiple;
338 }
312 339
313 public virtual List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) 340 public virtual List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
314 { 341 {
@@ -336,7 +363,7 @@ namespace OpenSim.Services.InventoryService
336 if (check != null) 363 if (check != null)
337 return false; 364 return false;
338 365
339 if (folder.Type != (short)AssetType.Folder && folder.Type != (short)AssetType.Unknown) 366 if (folder.Type != (short)FolderType.None)
340 { 367 {
341 InventoryFolderBase rootFolder = GetRootFolder(folder.Owner); 368 InventoryFolderBase rootFolder = GetRootFolder(folder.Owner);
342 369
@@ -353,7 +380,7 @@ namespace OpenSim.Services.InventoryService
353 if (folder.ParentID == rootFolder.ID) 380 if (folder.ParentID == rootFolder.ID)
354 { 381 {
355 InventoryFolderBase existingSystemFolder 382 InventoryFolderBase existingSystemFolder
356 = GetSystemFolderForType(rootFolder, (AssetType)folder.Type); 383 = GetSystemFolderForType(rootFolder, (FolderType)folder.Type);
357 384
358 if (existingSystemFolder != null) 385 if (existingSystemFolder != null)
359 { 386 {
@@ -380,8 +407,8 @@ namespace OpenSim.Services.InventoryService
380 if (check == null) 407 if (check == null)
381 return AddFolder(folder); 408 return AddFolder(folder);
382 409
383 if ((check.Type != (short)AssetType.Unknown || xFolder.type != (short)AssetType.Unknown) 410 if ((check.Type != (short)FolderType.None || xFolder.type != (short)FolderType.None)
384 && (check.Type != (short)AssetType.OutfitFolder || xFolder.type != (short)AssetType.OutfitFolder)) 411 && (check.Type != (short)FolderType.Outfit || xFolder.type != (short)FolderType.Outfit))
385 { 412 {
386 if (xFolder.version < check.Version) 413 if (xFolder.version < check.Version)
387 { 414 {
@@ -583,6 +610,21 @@ namespace OpenSim.Services.InventoryService
583 return ConvertToOpenSim(items[0]); 610 return ConvertToOpenSim(items[0]);
584 } 611 }
585 612
613 public virtual InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] ids)
614 {
615 InventoryItemBase[] items = new InventoryItemBase[ids.Length];
616 int i = 0;
617 InventoryItemBase item = new InventoryItemBase();
618 item.Owner = userID;
619 foreach (UUID id in ids)
620 {
621 item.ID = id;
622 items[i++] = GetItem(item);
623 }
624
625 return items;
626 }
627
586 public virtual InventoryFolderBase GetFolder(InventoryFolderBase folder) 628 public virtual InventoryFolderBase GetFolder(InventoryFolderBase folder)
587 { 629 {
588 XInventoryFolder[] folders = m_Database.GetFolders( 630 XInventoryFolder[] folders = m_Database.GetFolders(
@@ -615,34 +657,6 @@ namespace OpenSim.Services.InventoryService
615 return m_Database.GetAssetPermissions(principalID, assetID); 657 return m_Database.GetAssetPermissions(principalID, assetID);
616 } 658 }
617 659
618 public virtual InventoryCollection GetUserInventory(UUID userID)
619 {
620 InventoryCollection userInventory = new InventoryCollection();
621 userInventory.UserID = userID;
622 userInventory.Folders = new List<InventoryFolderBase>();
623 userInventory.Items = new List<InventoryItemBase>();
624
625 List<InventoryFolderBase> skel = GetInventorySkeleton(userID);
626 if (skel != null)
627 {
628 foreach (InventoryFolderBase f in skel)
629 {
630 InventoryCollection c = GetFolderContent(userID, f.ID);
631 if (c != null && c.Items != null && c.Items.Count > 0)
632 userInventory.Items.AddRange(c.Items);
633 if (c != null && c.Folders != null && c.Folders.Count > 0)
634 userInventory.Folders.AddRange(c.Folders);
635 }
636 }
637 m_log.DebugFormat("[XINVENTORY SERVICE]: GetUserInventory for user {0} returning {1} folders and {2} items",
638 userID, userInventory.Folders.Count, userInventory.Items.Count);
639 return userInventory;
640 }
641
642 public void GetUserInventory(UUID userID, InventoryReceiptCallback callback)
643 {
644 }
645
646 // Unused. 660 // Unused.
647 // 661 //
648 public bool HasInventoryForUser(UUID userID) 662 public bool HasInventoryForUser(UUID userID)
@@ -658,9 +672,9 @@ namespace OpenSim.Services.InventoryService
658 672
659 newFolder.ParentID = folder.parentFolderID; 673 newFolder.ParentID = folder.parentFolderID;
660 newFolder.Type = (short)folder.type; 674 newFolder.Type = (short)folder.type;
661 // Viewer can't understand anything that's not in it's LLFolderType enum 675 //// Viewer can't understand anything that's not in it's LLFolderType enum
662 if (newFolder.Type == 100) 676 //if (newFolder.Type == InventoryItemBase.SUITCASE_FOLDER_TYPE)
663 newFolder.Type = -1; 677 // newFolder.Type = InventoryItemBase.SUITCASE_FOLDER_FAKE_TYPE;
664 newFolder.Version = (ushort)folder.version; 678 newFolder.Version = (ushort)folder.version;
665 newFolder.Name = folder.folderName; 679 newFolder.Name = folder.folderName;
666 newFolder.Owner = folder.agentID; 680 newFolder.Owner = folder.agentID;
@@ -751,7 +765,7 @@ namespace OpenSim.Services.InventoryService
751 if (folder.Length < 1) 765 if (folder.Length < 1)
752 return false; 766 return false;
753 767
754 if (folder[0].type == (int)AssetType.TrashFolder) 768 if (folder[0].type == (int)FolderType.Trash)
755 return true; 769 return true;
756 770
757 UUID parentFolder = folder[0].parentFolderID; 771 UUID parentFolder = folder[0].parentFolderID;
@@ -762,9 +776,9 @@ namespace OpenSim.Services.InventoryService
762 if (parent.Length < 1) 776 if (parent.Length < 1)
763 return false; 777 return false;
764 778
765 if (parent[0].type == (int)AssetType.TrashFolder) 779 if (parent[0].type == (int)FolderType.Trash)
766 return true; 780 return true;
767 if (parent[0].type == (int)AssetType.RootFolder) 781 if (parent[0].type == (int)FolderType.Root)
768 return false; 782 return false;
769 783
770 parentFolder = parent[0].parentFolderID; 784 parentFolder = parent[0].parentFolderID;
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index 9ec744f..c3756d0 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -190,6 +190,8 @@ namespace OpenSim.Services.LLLoginService
190 private BuddyList m_buddyList = null; 190 private BuddyList m_buddyList = null;
191 191
192 private string currency; 192 private string currency;
193 private string classifiedFee;
194 private int maxAgentGroups;
193 195
194 static LLLoginResponse() 196 static LLLoginResponse()
195 { 197 {
@@ -226,8 +228,8 @@ namespace OpenSim.Services.LLLoginService
226 public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, 228 public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo,
227 GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService, 229 GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
228 string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message, 230 string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message,
229 GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency, 231 GridRegion home, IPEndPoint clientIP, string mapTileURL, string searchURL, string currency,
230 string DSTZone) 232 string DSTZone, string destinationsURL, string avatarsURL, string classifiedFee, int maxAgentGroups)
231 : this() 233 : this()
232 { 234 {
233 FillOutInventoryData(invSkel, libService); 235 FillOutInventoryData(invSkel, libService);
@@ -246,14 +248,19 @@ namespace OpenSim.Services.LLLoginService
246 MapTileURL = mapTileURL; 248 MapTileURL = mapTileURL;
247 ProfileURL = profileURL; 249 ProfileURL = profileURL;
248 OpenIDURL = openIDURL; 250 OpenIDURL = openIDURL;
251 DestinationsURL = destinationsURL;
252 AvatarsURL = avatarsURL;
249 253
250 SearchURL = searchURL; 254 SearchURL = searchURL;
251 Currency = currency; 255 Currency = currency;
256 ClassifiedFee = classifiedFee;
257 MaxAgentGroups = maxAgentGroups;
252 258
253 FillOutHomeData(pinfo, home); 259 FillOutHomeData(pinfo, home);
254 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z); 260 LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z);
255 261
256 FillOutRegionData(destination); 262 FillOutRegionData(destination);
263 m_log.DebugFormat("[LOGIN RESPONSE] LLLoginResponse create. sizeX={0}, sizeY={1}", RegionSizeX, RegionSizeY);
257 264
258 FillOutSeedCap(aCircuit, destination, clientIP); 265 FillOutSeedCap(aCircuit, destination, clientIP);
259 266
@@ -356,7 +363,8 @@ namespace OpenSim.Services.LLLoginService
356 363
357 private void FillOutHomeData(GridUserInfo pinfo, GridRegion home) 364 private void FillOutHomeData(GridUserInfo pinfo, GridRegion home)
358 { 365 {
359 int x = 1000 * (int)Constants.RegionSize, y = 1000 * (int)Constants.RegionSize; 366 int x = (int)Util.RegionToWorldLoc(1000);
367 int y = (int)Util.RegionToWorldLoc(1000);
360 if (home != null) 368 if (home != null)
361 { 369 {
362 x = home.RegionLocX; 370 x = home.RegionLocX;
@@ -379,6 +387,8 @@ namespace OpenSim.Services.LLLoginService
379 SimPort = (uint)endPoint.Port; 387 SimPort = (uint)endPoint.Port;
380 RegionX = (uint)destination.RegionLocX; 388 RegionX = (uint)destination.RegionLocX;
381 RegionY = (uint)destination.RegionLocY; 389 RegionY = (uint)destination.RegionLocY;
390 RegionSizeX = destination.RegionSizeX;
391 RegionSizeY = destination.RegionSizeY;
382 } 392 }
383 393
384 private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient) 394 private void FillOutSeedCap(AgentCircuitData aCircuit, GridRegion destination, IPEndPoint ipepClient)
@@ -428,10 +438,23 @@ namespace OpenSim.Services.LLLoginService
428 ErrorReason = "key"; 438 ErrorReason = "key";
429 welcomeMessage = "Welcome to OpenSim!"; 439 welcomeMessage = "Welcome to OpenSim!";
430 seedCapability = String.Empty; 440 seedCapability = String.Empty;
431 home = "{'region_handle':[r" + (1000*Constants.RegionSize).ToString() + ",r" + (1000*Constants.RegionSize).ToString() + "], 'position':[r" + 441 home = "{'region_handle':["
432 userProfile.homepos.X.ToString() + ",r" + userProfile.homepos.Y.ToString() + ",r" + 442 + "r" + Util.RegionToWorldLoc(1000).ToString()
433 userProfile.homepos.Z.ToString() + "], 'look_at':[r" + userProfile.homelookat.X.ToString() + ",r" + 443 + ","
434 userProfile.homelookat.Y.ToString() + ",r" + userProfile.homelookat.Z.ToString() + "]}"; 444 + "r" + Util.RegionToWorldLoc(1000).ToString()
445 + "], 'position':["
446 + "r" + userProfile.homepos.X.ToString()
447 + ","
448 + "r" + userProfile.homepos.Y.ToString()
449 + ","
450 + "r" + userProfile.homepos.Z.ToString()
451 + "], 'look_at':["
452 + "r" + userProfile.homelookat.X.ToString()
453 + ","
454 + "r" + userProfile.homelookat.Y.ToString()
455 + ","
456 + "r" + userProfile.homelookat.Z.ToString()
457 + "]}";
435 lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]"; 458 lookAt = "[r0.99949799999999999756,r0.03166859999999999814,r0]";
436 RegionX = (uint) 255232; 459 RegionX = (uint) 255232;
437 RegionY = (uint) 254976; 460 RegionY = (uint) 254976;
@@ -461,6 +484,8 @@ namespace OpenSim.Services.LLLoginService
461 searchURL = String.Empty; 484 searchURL = String.Empty;
462 485
463 currency = String.Empty; 486 currency = String.Empty;
487 ClassifiedFee = "0";
488 MaxAgentGroups = 42;
464 } 489 }
465 490
466 491
@@ -520,9 +545,13 @@ namespace OpenSim.Services.LLLoginService
520 responseData["seed_capability"] = seedCapability; 545 responseData["seed_capability"] = seedCapability;
521 responseData["home"] = home; 546 responseData["home"] = home;
522 responseData["look_at"] = lookAt; 547 responseData["look_at"] = lookAt;
548 responseData["max-agent-groups"] = MaxAgentGroups;
523 responseData["message"] = welcomeMessage; 549 responseData["message"] = welcomeMessage;
524 responseData["region_x"] = (Int32)(RegionX); 550 responseData["region_x"] = (Int32)(RegionX);
525 responseData["region_y"] = (Int32)(RegionY); 551 responseData["region_y"] = (Int32)(RegionY);
552 responseData["region_size_x"] = (Int32)RegionSizeX;
553 responseData["region_size_y"] = (Int32)RegionSizeY;
554 m_log.DebugFormat("[LOGIN RESPONSE] returning sizeX={0}, sizeY={1}", RegionSizeX, RegionSizeY);
526 555
527 if (searchURL != String.Empty) 556 if (searchURL != String.Empty)
528 responseData["search"] = searchURL; 557 responseData["search"] = searchURL;
@@ -533,6 +562,12 @@ namespace OpenSim.Services.LLLoginService
533 if (profileURL != String.Empty) 562 if (profileURL != String.Empty)
534 responseData["profile-server-url"] = profileURL; 563 responseData["profile-server-url"] = profileURL;
535 564
565 if (DestinationsURL != String.Empty)
566 responseData["destination_guide_url"] = DestinationsURL;
567
568 if (AvatarsURL != String.Empty)
569 responseData["avatar_picker_url"] = AvatarsURL;
570
536 // We need to send an openid_token back in the response too 571 // We need to send an openid_token back in the response too
537 if (openIDURL != String.Empty) 572 if (openIDURL != String.Empty)
538 responseData["openid_url"] = openIDURL; 573 responseData["openid_url"] = openIDURL;
@@ -547,6 +582,9 @@ namespace OpenSim.Services.LLLoginService
547 // responseData["real_currency"] = currency; 582 // responseData["real_currency"] = currency;
548 responseData["currency"] = currency; 583 responseData["currency"] = currency;
549 } 584 }
585
586 if (ClassifiedFee != String.Empty)
587 responseData["classified_fee"] = ClassifiedFee;
550 588
551 responseData["login"] = "true"; 589 responseData["login"] = "true";
552 590
@@ -635,6 +673,7 @@ namespace OpenSim.Services.LLLoginService
635 map["seed_capability"] = OSD.FromString(seedCapability); 673 map["seed_capability"] = OSD.FromString(seedCapability);
636 map["home"] = OSD.FromString(home); 674 map["home"] = OSD.FromString(home);
637 map["look_at"] = OSD.FromString(lookAt); 675 map["look_at"] = OSD.FromString(lookAt);
676 map["max-agent-groups"] = OSD.FromInteger(MaxAgentGroups);
638 map["message"] = OSD.FromString(welcomeMessage); 677 map["message"] = OSD.FromString(welcomeMessage);
639 map["region_x"] = OSD.FromInteger(RegionX); 678 map["region_x"] = OSD.FromInteger(RegionX);
640 map["region_y"] = OSD.FromInteger(RegionY); 679 map["region_y"] = OSD.FromInteger(RegionY);
@@ -651,6 +690,9 @@ namespace OpenSim.Services.LLLoginService
651 if (searchURL != String.Empty) 690 if (searchURL != String.Empty)
652 map["search"] = OSD.FromString(searchURL); 691 map["search"] = OSD.FromString(searchURL);
653 692
693 if (ClassifiedFee != String.Empty)
694 map["classified_fee"] = OSD.FromString(ClassifiedFee);
695
654 if (m_buddyList != null) 696 if (m_buddyList != null)
655 { 697 {
656 map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray()); 698 map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray());
@@ -746,7 +788,7 @@ namespace OpenSim.Services.LLLoginService
746 Hashtable TempHash; 788 Hashtable TempHash;
747 foreach (InventoryFolderBase InvFolder in folders) 789 foreach (InventoryFolderBase InvFolder in folders)
748 { 790 {
749 if (InvFolder.ParentID == UUID.Zero && InvFolder.Name == "My Inventory") 791 if (InvFolder.ParentID == UUID.Zero && InvFolder.Name == InventoryFolderBase.ROOT_FOLDER_NAME)
750 { 792 {
751 rootID = InvFolder.ID; 793 rootID = InvFolder.ID;
752 } 794 }
@@ -900,6 +942,9 @@ namespace OpenSim.Services.LLLoginService
900 set { regionY = value; } 942 set { regionY = value; }
901 } 943 }
902 944
945 public int RegionSizeX { get; private set; }
946 public int RegionSizeY { get; private set; }
947
903 public string SunTexture 948 public string SunTexture
904 { 949 {
905 get { return sunTexture; } 950 get { return sunTexture; }
@@ -1056,6 +1101,28 @@ namespace OpenSim.Services.LLLoginService
1056 set { currency = value; } 1101 set { currency = value; }
1057 } 1102 }
1058 1103
1104 public string ClassifiedFee
1105 {
1106 get { return classifiedFee; }
1107 set { classifiedFee = value; }
1108 }
1109
1110 public int MaxAgentGroups
1111 {
1112 get { return maxAgentGroups; }
1113 set { maxAgentGroups = value; }
1114 }
1115
1116 public string DestinationsURL
1117 {
1118 get; set;
1119 }
1120
1121 public string AvatarsURL
1122 {
1123 get; set;
1124 }
1125
1059 #endregion 1126 #endregion
1060 1127
1061 public class UserInfo 1128 public class UserInfo
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index 59fb559..0b38738 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -50,12 +50,15 @@ namespace OpenSim.Services.LLLoginService
50 public class LLLoginService : ILoginService 50 public class LLLoginService : ILoginService
51 { 51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 private static readonly string LogHeader = "[LLOGIN SERVICE]";
54
53 private static bool Initialized = false; 55 private static bool Initialized = false;
54 56
55 protected IUserAccountService m_UserAccountService; 57 protected IUserAccountService m_UserAccountService;
56 protected IGridUserService m_GridUserService; 58 protected IGridUserService m_GridUserService;
57 protected IAuthenticationService m_AuthenticationService; 59 protected IAuthenticationService m_AuthenticationService;
58 protected IInventoryService m_InventoryService; 60 protected IInventoryService m_InventoryService;
61 protected IInventoryService m_HGInventoryService;
59 protected IGridService m_GridService; 62 protected IGridService m_GridService;
60 protected IPresenceService m_PresenceService; 63 protected IPresenceService m_PresenceService;
61 protected ISimulationService m_LocalSimulationService; 64 protected ISimulationService m_LocalSimulationService;
@@ -74,14 +77,15 @@ namespace OpenSim.Services.LLLoginService
74 protected string m_GatekeeperURL; 77 protected string m_GatekeeperURL;
75 protected bool m_AllowRemoteSetLoginLevel; 78 protected bool m_AllowRemoteSetLoginLevel;
76 protected string m_MapTileURL; 79 protected string m_MapTileURL;
77 protected string m_ProfileURL;
78 protected string m_OpenIDURL;
79 protected string m_SearchURL; 80 protected string m_SearchURL;
80 protected string m_Currency; 81 protected string m_Currency;
81 82 protected string m_ClassifiedFee;
83 protected int m_MaxAgentGroups;
84 protected string m_DestinationGuide;
85 protected string m_AvatarPicker;
82 protected string m_AllowedClients; 86 protected string m_AllowedClients;
83 protected string m_DeniedClients; 87 protected string m_DeniedClients;
84 88 protected string m_MessageUrl;
85 protected string m_DSTZone; 89 protected string m_DSTZone;
86 90
87 IConfig m_LoginServerConfig; 91 IConfig m_LoginServerConfig;
@@ -110,18 +114,29 @@ namespace OpenSim.Services.LLLoginService
110 m_RequireInventory = m_LoginServerConfig.GetBoolean("RequireInventory", true); 114 m_RequireInventory = m_LoginServerConfig.GetBoolean("RequireInventory", true);
111 m_AllowRemoteSetLoginLevel = m_LoginServerConfig.GetBoolean("AllowRemoteSetLoginLevel", false); 115 m_AllowRemoteSetLoginLevel = m_LoginServerConfig.GetBoolean("AllowRemoteSetLoginLevel", false);
112 m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0); 116 m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0);
113 m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); 117 m_GatekeeperURL = Util.GetConfigVarFromSections<string>(config, "GatekeeperURI",
118 new string[] { "Startup", "Hypergrid", "LoginService" }, String.Empty);
114 m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty); 119 m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty);
115 m_ProfileURL = m_LoginServerConfig.GetString("ProfileServerURL", string.Empty);
116 m_OpenIDURL = m_LoginServerConfig.GetString("OpenIDServerURL", String.Empty);
117 m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty); 120 m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty);
118 m_Currency = m_LoginServerConfig.GetString("Currency", string.Empty); 121 m_Currency = m_LoginServerConfig.GetString("Currency", string.Empty);
122 m_ClassifiedFee = m_LoginServerConfig.GetString("ClassifiedFee", string.Empty);
123 m_DestinationGuide = m_LoginServerConfig.GetString ("DestinationGuide", string.Empty);
124 m_AvatarPicker = m_LoginServerConfig.GetString ("AvatarPicker", string.Empty);
119 125
120 m_AllowedClients = m_LoginServerConfig.GetString("AllowedClients", string.Empty); 126 string[] possibleAccessControlConfigSections = new string[] { "AccessControl", "LoginService" };
121 m_DeniedClients = m_LoginServerConfig.GetString("DeniedClients", string.Empty); 127 m_AllowedClients = Util.GetConfigVarFromSections<string>(
128 config, "AllowedClients", possibleAccessControlConfigSections, string.Empty);
129 m_DeniedClients = Util.GetConfigVarFromSections<string>(
130 config, "DeniedClients", possibleAccessControlConfigSections, string.Empty);
122 131
132 m_MessageUrl = m_LoginServerConfig.GetString("MessageUrl", string.Empty);
123 m_DSTZone = m_LoginServerConfig.GetString("DSTZone", "America/Los_Angeles;Pacific Standard Time"); 133 m_DSTZone = m_LoginServerConfig.GetString("DSTZone", "America/Los_Angeles;Pacific Standard Time");
124 134
135 IConfig groupConfig = config.Configs["Groups"];
136 if (groupConfig != null)
137 m_MaxAgentGroups = groupConfig.GetInt("MaxAgentGroups", 42);
138
139
125 // Clean up some of these vars 140 // Clean up some of these vars
126 if (m_MapTileURL != String.Empty) 141 if (m_MapTileURL != String.Empty)
127 { 142 {
@@ -156,6 +171,15 @@ namespace OpenSim.Services.LLLoginService
156 if (agentService != string.Empty) 171 if (agentService != string.Empty)
157 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(agentService, args); 172 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(agentService, args);
158 173
174 // Get the Hypergrid inventory service (exists only if Hypergrid is enabled)
175 string hgInvServicePlugin = m_LoginServerConfig.GetString("HGInventoryServicePlugin", String.Empty);
176 if (hgInvServicePlugin != string.Empty)
177 {
178 string hgInvServiceArg = m_LoginServerConfig.GetString("HGInventoryServiceConstructorArg", String.Empty);
179 Object[] args2 = new Object[] { config, hgInvServiceArg };
180 m_HGInventoryService = ServerUtils.LoadPlugin<IInventoryService>(hgInvServicePlugin, args2);
181 }
182
159 // 183 //
160 // deal with the services given as argument 184 // deal with the services given as argument
161 // 185 //
@@ -241,6 +265,7 @@ namespace OpenSim.Services.LLLoginService
241 { 265 {
242 bool success = false; 266 bool success = false;
243 UUID session = UUID.Random(); 267 UUID session = UUID.Random();
268 string processedMessage;
244 269
245 m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} at {2} using viewer {3}, channel {4}, IP {5}, Mac {6}, Id0 {7}", 270 m_log.InfoFormat("[LLOGIN SERVICE]: Login request for {0} {1} at {2} using viewer {3}, channel {4}, IP {5}, Mac {6}, Id0 {7}",
246 firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0); 271 firstName, lastName, startLocation, clientVersion, channel, clientIP.Address.ToString(), mac, id0);
@@ -341,6 +366,13 @@ namespace OpenSim.Services.LLLoginService
341 return LLFailedLoginResponse.InventoryProblem; 366 return LLFailedLoginResponse.InventoryProblem;
342 } 367 }
343 368
369 if (m_HGInventoryService != null)
370 {
371 // Give the Suitcase service a chance to create the suitcase folder.
372 // (If we're not using the Suitcase inventory service then this won't do anything.)
373 m_HGInventoryService.GetRootFolder(account.PrincipalID);
374 }
375
344 List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID); 376 List<InventoryFolderBase> inventorySkel = m_InventoryService.GetInventorySkeleton(account.PrincipalID);
345 if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel != null && inventorySkel.Count == 0))) 377 if (m_RequireInventory && ((inventorySkel == null) || (inventorySkel != null && inventorySkel.Count == 0)))
346 { 378 {
@@ -375,13 +407,33 @@ namespace OpenSim.Services.LLLoginService
375 // 407 //
376 GridRegion home = null; 408 GridRegion home = null;
377 GridUserInfo guinfo = m_GridUserService.LoggedIn(account.PrincipalID.ToString()); 409 GridUserInfo guinfo = m_GridUserService.LoggedIn(account.PrincipalID.ToString());
378 if (guinfo != null && (guinfo.HomeRegionID != UUID.Zero) && m_GridService != null) 410
411 // We are only going to complain about no home if the user actually tries to login there, to avoid
412 // spamming the console.
413 if (guinfo != null)
379 { 414 {
380 home = m_GridService.GetRegionByUUID(scopeID, guinfo.HomeRegionID); 415 if (guinfo.HomeRegionID == UUID.Zero && startLocation == "home")
416 {
417 m_log.WarnFormat(
418 "[LLOGIN SERVICE]: User {0} tried to login to a 'home' start location but they have none set",
419 account.Name);
420 }
421 else if (m_GridService != null)
422 {
423 home = m_GridService.GetRegionByUUID(scopeID, guinfo.HomeRegionID);
424
425 if (home == null && startLocation == "home")
426 {
427 m_log.WarnFormat(
428 "[LLOGIN SERVICE]: User {0} tried to login to a 'home' start location with ID {1} but this was not found.",
429 account.Name, guinfo.HomeRegionID);
430 }
431 }
381 } 432 }
382 if (guinfo == null) 433 else
383 { 434 {
384 // something went wrong, make something up, so that we don't have to test this anywhere else 435 // something went wrong, make something up, so that we don't have to test this anywhere else
436 m_log.DebugFormat("{0} Failed to fetch GridUserInfo. Creating empty GridUserInfo as home", LogHeader);
385 guinfo = new GridUserInfo(); 437 guinfo = new GridUserInfo();
386 guinfo.LastPosition = guinfo.HomePosition = new Vector3(128, 128, 30); 438 guinfo.LastPosition = guinfo.HomePosition = new Vector3(128, 128, 30);
387 } 439 }
@@ -448,16 +500,28 @@ namespace OpenSim.Services.LLLoginService
448 // 500 //
449 // Finally, fill out the response and return it 501 // Finally, fill out the response and return it
450 // 502 //
503 if (m_MessageUrl != String.Empty)
504 {
505 WebClient client = new WebClient();
506 processedMessage = client.DownloadString(m_MessageUrl);
507 }
508 else
509 {
510 processedMessage = m_WelcomeMessage;
511 }
512 processedMessage = processedMessage.Replace("\\n", "\n").Replace("<USERNAME>", firstName + " " + lastName);
513
451 LLLoginResponse response 514 LLLoginResponse response
452 = new LLLoginResponse( 515 = new LLLoginResponse(
453 account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, 516 account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
454 where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, 517 where, startLocation, position, lookAt, gestures, processedMessage, home, clientIP,
455 m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency, m_DSTZone); 518 m_MapTileURL, m_SearchURL, m_Currency, m_DSTZone,
519 m_DestinationGuide, m_AvatarPicker, m_ClassifiedFee, m_MaxAgentGroups);
456 520
457 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to {0} {1}", firstName, lastName); 521 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to {0} {1}", firstName, lastName);
458 522
459 return response; 523 return response;
460 } 524 }
461 catch (Exception e) 525 catch (Exception e)
462 { 526 {
463 m_log.WarnFormat("[LLOGIN SERVICE]: Exception processing login for {0} {1}: {2} {3}", firstName, lastName, e.ToString(), e.StackTrace); 527 m_log.WarnFormat("[LLOGIN SERVICE]: Exception processing login for {0} {1}: {2} {3}", firstName, lastName, e.ToString(), e.StackTrace);
@@ -498,10 +562,6 @@ namespace OpenSim.Services.LLLoginService
498 562
499 if (home == null) 563 if (home == null)
500 { 564 {
501 m_log.WarnFormat(
502 "[LLOGIN SERVICE]: User {0} {1} tried to login to a 'home' start location but they have none set",
503 account.FirstName, account.LastName);
504
505 tryDefaults = true; 565 tryDefaults = true;
506 } 566 }
507 else 567 else
@@ -576,7 +636,7 @@ namespace OpenSim.Services.LLLoginService
576 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34 636 // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34
577 where = "url"; 637 where = "url";
578 GridRegion region = null; 638 GridRegion region = null;
579 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+)&(?<y>\d+)&(?<z>\d+)$"); 639 Regex reURI = new Regex(@"^uri:(?<region>[^&]+)&(?<x>\d+[.]?\d*)&(?<y>\d+[.]?\d*)&(?<z>\d+[.]?\d*)$");
580 Match uriMatch = reURI.Match(startLocation); 640 Match uriMatch = reURI.Match(startLocation);
581 if (uriMatch == null) 641 if (uriMatch == null)
582 { 642 {
@@ -645,8 +705,7 @@ namespace OpenSim.Services.LLLoginService
645 if (parts.Length > 1) 705 if (parts.Length > 1)
646 UInt32.TryParse(parts[1], out port); 706 UInt32.TryParse(parts[1], out port);
647 707
648// GridRegion region = FindForeignRegion(domainName, port, regionName, out gatekeeper); 708 region = FindForeignRegion(domainName, port, regionName, account, out gatekeeper);
649 region = FindForeignRegion(domainName, port, regionName, out gatekeeper);
650 return region; 709 return region;
651 } 710 }
652 } 711 }
@@ -673,7 +732,7 @@ namespace OpenSim.Services.LLLoginService
673 private GridRegion FindAlternativeRegion(UUID scopeID) 732 private GridRegion FindAlternativeRegion(UUID scopeID)
674 { 733 {
675 List<GridRegion> hyperlinks = null; 734 List<GridRegion> hyperlinks = null;
676 List<GridRegion> regions = m_GridService.GetFallbackRegions(scopeID, 1000 * (int)Constants.RegionSize, 1000 * (int)Constants.RegionSize); 735 List<GridRegion> regions = m_GridService.GetFallbackRegions(scopeID, (int)Util.RegionToWorldLoc(1000), (int)Util.RegionToWorldLoc(1000));
677 if (regions != null && regions.Count > 0) 736 if (regions != null && regions.Count > 0)
678 { 737 {
679 hyperlinks = m_GridService.GetHyperlinks(scopeID); 738 hyperlinks = m_GridService.GetHyperlinks(scopeID);
@@ -695,7 +754,7 @@ namespace OpenSim.Services.LLLoginService
695 return null; 754 return null;
696 } 755 }
697 756
698 private GridRegion FindForeignRegion(string domainName, uint port, string regionName, out GridRegion gatekeeper) 757 private GridRegion FindForeignRegion(string domainName, uint port, string regionName, UserAccount account, out GridRegion gatekeeper)
699 { 758 {
700 m_log.Debug("[LLLOGIN SERVICE]: attempting to findforeignregion " + domainName + ":" + port.ToString() + ":" + regionName); 759 m_log.Debug("[LLLOGIN SERVICE]: attempting to findforeignregion " + domainName + ":" + port.ToString() + ":" + regionName);
701 gatekeeper = new GridRegion(); 760 gatekeeper = new GridRegion();
@@ -707,9 +766,14 @@ namespace OpenSim.Services.LLLoginService
707 UUID regionID; 766 UUID regionID;
708 ulong handle; 767 ulong handle;
709 string imageURL = string.Empty, reason = string.Empty; 768 string imageURL = string.Empty, reason = string.Empty;
769 string message;
710 if (m_GatekeeperConnector.LinkRegion(gatekeeper, out regionID, out handle, out domainName, out imageURL, out reason)) 770 if (m_GatekeeperConnector.LinkRegion(gatekeeper, out regionID, out handle, out domainName, out imageURL, out reason))
711 { 771 {
712 GridRegion destination = m_GatekeeperConnector.GetHyperlinkRegion(gatekeeper, regionID); 772 string homeURI = null;
773 if (account.ServiceURLs != null && account.ServiceURLs.ContainsKey("HomeURI"))
774 homeURI = (string)account.ServiceURLs["HomeURI"];
775
776 GridRegion destination = m_GatekeeperConnector.GetHyperlinkRegion(gatekeeper, regionID, account.PrincipalID, homeURI, out message);
713 return destination; 777 return destination;
714 } 778 }
715 779
@@ -858,13 +922,6 @@ namespace OpenSim.Services.LLLoginService
858 SetServiceURLs(aCircuit, account); 922 SetServiceURLs(aCircuit, account);
859 923
860 return aCircuit; 924 return aCircuit;
861
862 //m_UserAgentService.LoginAgentToGrid(aCircuit, GatekeeperServiceConnector, region, out reason);
863 //if (simConnector.CreateAgent(region, aCircuit, 0, out reason))
864 // return aCircuit;
865
866 //return null;
867
868 } 925 }
869 926
870 private void SetServiceURLs(AgentCircuitData aCircuit, UserAccount account) 927 private void SetServiceURLs(AgentCircuitData aCircuit, UserAccount account)
@@ -899,7 +956,7 @@ namespace OpenSim.Services.LLLoginService
899 if (!keyValue.EndsWith("/")) 956 if (!keyValue.EndsWith("/"))
900 keyValue = keyValue + "/"; 957 keyValue = keyValue + "/";
901 958
902 if (!account.ServiceURLs.ContainsKey(keyName) || (account.ServiceURLs.ContainsKey(keyName) && account.ServiceURLs[keyName] != keyValue)) 959 if (!account.ServiceURLs.ContainsKey(keyName) || (account.ServiceURLs.ContainsKey(keyName) && (string)account.ServiceURLs[keyName] != keyValue))
903 { 960 {
904 account.ServiceURLs[keyName] = keyValue; 961 account.ServiceURLs[keyName] = keyValue;
905 newUrls = true; 962 newUrls = true;
@@ -909,6 +966,13 @@ namespace OpenSim.Services.LLLoginService
909 m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]); 966 m_log.DebugFormat("[LLLOGIN SERVICE]: found new key {0} {1}", keyName, aCircuit.ServiceURLs[keyName]);
910 } 967 }
911 968
969 if (!account.ServiceURLs.ContainsKey("GatekeeperURI") && !string.IsNullOrEmpty(m_GatekeeperURL))
970 {
971 m_log.DebugFormat("[LLLOGIN SERVICE]: adding gatekeeper uri {0}", m_GatekeeperURL);
972 account.ServiceURLs["GatekeeperURI"] = m_GatekeeperURL;
973 newUrls = true;
974 }
975
912 // The grid operator decided to override the defaults in the 976 // The grid operator decided to override the defaults in the
913 // [LoginService] configuration. Let's store the correct ones. 977 // [LoginService] configuration. Let's store the correct ones.
914 if (newUrls) 978 if (newUrls)
@@ -919,13 +983,20 @@ namespace OpenSim.Services.LLLoginService
919 983
920 private bool LaunchAgentDirectly(ISimulationService simConnector, GridRegion region, AgentCircuitData aCircuit, TeleportFlags flags, out string reason) 984 private bool LaunchAgentDirectly(ISimulationService simConnector, GridRegion region, AgentCircuitData aCircuit, TeleportFlags flags, out string reason)
921 { 985 {
922 return simConnector.CreateAgent(region, aCircuit, (uint)flags, out reason); 986 EntityTransferContext ctx = new EntityTransferContext();
987
988 if (!simConnector.QueryAccess(
989 region, aCircuit.AgentID, null, true, aCircuit.startpos, new List<UUID>(), ctx, out reason))
990 return false;
991
992 return simConnector.CreateAgent(null, region, aCircuit, (uint)flags, out reason);
923 } 993 }
924 994
925 private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason) 995 private bool LaunchAgentIndirectly(GridRegion gatekeeper, GridRegion destination, AgentCircuitData aCircuit, IPEndPoint clientIP, out string reason)
926 { 996 {
927 m_log.Debug("[LLOGIN SERVICE] Launching agent at " + destination.RegionName); 997 m_log.Debug("[LLOGIN SERVICE]: Launching agent at " + destination.RegionName);
928 if (m_UserAgentService.LoginAgentToGrid(aCircuit, gatekeeper, destination, clientIP, out reason)) 998
999 if (m_UserAgentService.LoginAgentToGrid(null, aCircuit, gatekeeper, destination, true, out reason))
929 return true; 1000 return true;
930 return false; 1001 return false;
931 } 1002 }
@@ -961,14 +1032,25 @@ namespace OpenSim.Services.LLLoginService
961 // or fixing critical issues 1032 // or fixing critical issues
962 // 1033 //
963 if (cmd.Length > 2) 1034 if (cmd.Length > 2)
964 Int32.TryParse(cmd[2], out m_MinLoginLevel); 1035 {
1036 if (Int32.TryParse(cmd[2], out m_MinLoginLevel))
1037 MainConsole.Instance.OutputFormat("Set minimum login level to {0}", m_MinLoginLevel);
1038 else
1039 MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid login level", cmd[2]);
1040 }
965 break; 1041 break;
966 case "reset": 1042
1043 case "reset":
967 m_MinLoginLevel = 0; 1044 m_MinLoginLevel = 0;
1045 MainConsole.Instance.OutputFormat("Reset min login level to {0}", m_MinLoginLevel);
968 break; 1046 break;
1047
969 case "text": 1048 case "text":
970 if (cmd.Length > 2) 1049 if (cmd.Length > 2)
1050 {
971 m_WelcomeMessage = cmd[2]; 1051 m_WelcomeMessage = cmd[2];
1052 MainConsole.Instance.OutputFormat("Login welcome message set to '{0}'", m_WelcomeMessage);
1053 }
972 break; 1054 break;
973 } 1055 }
974 } 1056 }
diff --git a/OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs b/OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs
index 62c6e0f..5c150e3 100644
--- a/OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs
index a85ee70..a816411 100644
--- a/OpenSim/Services/MapImageService/MapImageService.cs
+++ b/OpenSim/Services/MapImageService/MapImageService.cs
@@ -36,6 +36,7 @@ using System.Drawing.Imaging;
36using System.IO; 36using System.IO;
37using System.Net; 37using System.Net;
38using System.Reflection; 38using System.Reflection;
39using System.Threading;
39 40
40using Nini.Config; 41using Nini.Config;
41using log4net; 42using log4net;
@@ -53,6 +54,9 @@ namespace OpenSim.Services.MapImageService
53 private static readonly ILog m_log = 54 private static readonly ILog m_log =
54 LogManager.GetLogger( 55 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType); 56 MethodBase.GetCurrentMethod().DeclaringType);
57#pragma warning disable 414
58 private string LogHeader = "[MAP IMAGE SERVICE]";
59#pragma warning restore 414
56 60
57 private const int ZOOM_LEVELS = 8; 61 private const int ZOOM_LEVELS = 8;
58 private const int IMAGE_WIDTH = 256; 62 private const int IMAGE_WIDTH = 256;
@@ -86,7 +90,7 @@ namespace OpenSim.Services.MapImageService
86 { 90 {
87 Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH); 91 Bitmap waterTile = new Bitmap(IMAGE_WIDTH, IMAGE_WIDTH);
88 FillImage(waterTile, m_Watercolor); 92 FillImage(waterTile, m_Watercolor);
89 waterTile.Save(m_WaterTileFile); 93 waterTile.Save(m_WaterTileFile, ImageFormat.Jpeg);
90 } 94 }
91 } 95 }
92 } 96 }
@@ -112,28 +116,106 @@ namespace OpenSim.Services.MapImageService
112 reason = e.Message; 116 reason = e.Message;
113 return false; 117 return false;
114 } 118 }
119 }
120
121 return UpdateMultiResolutionFilesAsync(x, y, out reason);
122 }
115 123
116 // Also save in png format? 124 public bool RemoveMapTile(int x, int y, out string reason)
125 {
126 reason = String.Empty;
127 string fileName = GetFileName(1, x, y);
117 128
118 // Stitch seven more aggregate tiles together 129 lock (m_Sync)
119 for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++) 130 {
131 try
132 {
133 File.Delete(fileName);
134 }
135 catch (Exception e)
120 { 136 {
121 // Calculate the width (in full resolution tiles) and bottom-left 137 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to save delete file {0}: {1}", fileName, e);
122 // corner of the current zoom level 138 reason = e.Message;
123 int width = (int)Math.Pow(2, (double)(zoomLevel - 1)); 139 return false;
124 int x1 = x - (x % width); 140 }
125 int y1 = y - (y % width); 141 }
142
143 return UpdateMultiResolutionFilesAsync(x, y, out reason);
144 }
126 145
127 if (!CreateTile(zoomLevel, x1, y1)) 146 // When large varregions start up, they can send piles of new map tiles. This causes
147 // this multi-resolution routine to be called a zillion times an causes much CPU
148 // time to be spent creating multi-resolution tiles that will be replaced when
149 // the next maptile arrives.
150 private class mapToMultiRez
151 {
152 public int xx;
153 public int yy;
154 public mapToMultiRez(int pX, int pY)
155 {
156 xx = pX;
157 yy = pY;
158 }
159 };
160 private Queue<mapToMultiRez> multiRezToBuild = new Queue<mapToMultiRez>();
161 private bool UpdateMultiResolutionFilesAsync(int x, int y, out string reason)
162 {
163 reason = String.Empty;
164 lock (multiRezToBuild)
165 {
166 // m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y);
167 multiRezToBuild.Enqueue(new mapToMultiRez(x, y));
168 if (multiRezToBuild.Count == 1)
169 Util.FireAndForget(
170 DoUpdateMultiResolutionFilesAsync, null, "MapImageService.DoUpdateMultiResolutionFilesAsync");
171 }
172
173 return true;
174 }
175
176 private void DoUpdateMultiResolutionFilesAsync(object o)
177 {
178 // This sleep causes the FireAndForget thread to be different than the invocation thread.
179 // It also allows other tiles to be uploaded so the multi-rez images are more likely
180 // to be correct.
181 Thread.Sleep(1 * 1000);
182
183 while (multiRezToBuild.Count > 0)
184 {
185 mapToMultiRez toMultiRez = null;
186 lock (multiRezToBuild)
187 {
188 if (multiRezToBuild.Count > 0)
189 toMultiRez = multiRezToBuild.Dequeue();
190 }
191 if (toMultiRez != null)
192 {
193 int x = toMultiRez.xx;
194 int y = toMultiRez.yy;
195 // m_log.DebugFormat("{0} DoUpdateMultiResolutionFilesAsync: doing build for <{1},{2}>", LogHeader, x, y);
196
197 // Stitch seven more aggregate tiles together
198 for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++)
128 { 199 {
129 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0} at zoom level {1}", fileName, zoomLevel); 200 // Calculate the width (in full resolution tiles) and bottom-left
130 reason = string.Format("Map tile at zoom level {0} failed", zoomLevel); 201 // corner of the current zoom level
131 return false; 202 int width = (int)Math.Pow(2, (double)(zoomLevel - 1));
203 int x1 = x - (x % width);
204 int y1 = y - (y % width);
205
206 lock (m_Sync) // must lock the reading and writing of the maptile files
207 {
208 if (!CreateTile(zoomLevel, x1, y1))
209 {
210 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel);
211 return;
212 }
213 }
132 } 214 }
133 } 215 }
134 } 216 }
135 217
136 return true; 218 return;
137 } 219 }
138 220
139 public byte[] GetMapTile(string fileName, out string format) 221 public byte[] GetMapTile(string fileName, out string format)
diff --git a/OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs b/OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs
index 23eb664..e779238 100644
--- a/OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/PresenceService/PresenceService.cs b/OpenSim/Services/PresenceService/PresenceService.cs
index ed2703e..b5ca4d5 100644
--- a/OpenSim/Services/PresenceService/PresenceService.cs
+++ b/OpenSim/Services/PresenceService/PresenceService.cs
@@ -41,9 +41,7 @@ namespace OpenSim.Services.PresenceService
41{ 41{
42 public class PresenceService : PresenceServiceBase, IPresenceService 42 public class PresenceService : PresenceServiceBase, IPresenceService
43 { 43 {
44 private static readonly ILog m_log = 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType);
47 45
48 protected bool m_allowDuplicatePresences = false; 46 protected bool m_allowDuplicatePresences = false;
49 47
@@ -55,19 +53,15 @@ namespace OpenSim.Services.PresenceService
55 IConfig presenceConfig = config.Configs["PresenceService"]; 53 IConfig presenceConfig = config.Configs["PresenceService"];
56 if (presenceConfig != null) 54 if (presenceConfig != null)
57 { 55 {
58 m_allowDuplicatePresences = 56 m_allowDuplicatePresences = presenceConfig.GetBoolean("AllowDuplicatePresences", m_allowDuplicatePresences);
59 presenceConfig.GetBoolean("AllowDuplicatePresences",
60 m_allowDuplicatePresences);
61 } 57 }
62 } 58 }
63 59
64 public bool LoginAgent(string userID, UUID sessionID, 60 public bool LoginAgent(string userID, UUID sessionID, UUID secureSessionID)
65 UUID secureSessionID)
66 { 61 {
67 //PresenceData[] d = m_Database.Get("UserID", userID); 62 PresenceData prevUser = GetUser(userID);
68 //m_Database.Get("UserID", userID);
69 63
70 if (!m_allowDuplicatePresences) 64 if (!m_allowDuplicatePresences && (prevUser != null))
71 m_Database.Delete("UserID", userID.ToString()); 65 m_Database.Delete("UserID", userID.ToString());
72 66
73 PresenceData data = new PresenceData(); 67 PresenceData data = new PresenceData();
@@ -80,19 +74,41 @@ namespace OpenSim.Services.PresenceService
80 74
81 m_Database.Store(data); 75 m_Database.Store(data);
82 76
83 m_log.DebugFormat("[PRESENCE SERVICE]: LoginAgent {0} with session {1} and ssession {2}", 77 string prevUserStr = "";
84 userID, sessionID, secureSessionID); 78 if (prevUser != null)
79 prevUserStr = string.Format(". This user was already logged-in: session {0}, region {1}", prevUser.SessionID, prevUser.RegionID);
80
81 m_log.DebugFormat("[PRESENCE SERVICE]: LoginAgent: session {0}, user {1}, region {2}, secure session {3}{4}",
82 data.SessionID, data.UserID, data.RegionID, secureSessionID, prevUserStr);
83
85 return true; 84 return true;
86 } 85 }
87 86
88 public bool LogoutAgent(UUID sessionID) 87 public bool LogoutAgent(UUID sessionID)
89 { 88 {
90 m_log.DebugFormat("[PRESENCE SERVICE]: Session {0} logout", sessionID); 89 PresenceInfo presence = GetAgent(sessionID);
90
91 m_log.InfoFormat("[PRESENCE SERVICE]: LogoutAgent: session {0}, user {1}, region {2}",
92 sessionID,
93 (presence == null) ? null : presence.UserID,
94 (presence == null) ? null : presence.RegionID.ToString());
95
91 return m_Database.Delete("SessionID", sessionID.ToString()); 96 return m_Database.Delete("SessionID", sessionID.ToString());
92 } 97 }
93 98
94 public bool LogoutRegionAgents(UUID regionID) 99 public bool LogoutRegionAgents(UUID regionID)
95 { 100 {
101 PresenceData[] prevSessions = GetRegionAgents(regionID);
102
103 if ((prevSessions == null) || (prevSessions.Length == 0))
104 return true;
105
106 m_log.DebugFormat("[PRESENCE SERVICE]: Logout users in region {0}: {1}", regionID,
107 string.Join(", ", Array.ConvertAll(prevSessions, session => session.UserID)));
108
109 // There's a small chance that LogoutRegionAgents() will logout different users than the
110 // list that was logged above, but it's unlikely and not worth dealing with.
111
96 m_Database.LogoutRegionAgents(regionID); 112 m_Database.LogoutRegionAgents(regionID);
97 113
98 return true; 114 return true;
@@ -101,20 +117,26 @@ namespace OpenSim.Services.PresenceService
101 117
102 public bool ReportAgent(UUID sessionID, UUID regionID) 118 public bool ReportAgent(UUID sessionID, UUID regionID)
103 { 119 {
104// m_log.DebugFormat("[PRESENCE SERVICE]: ReportAgent with session {0} in region {1}", sessionID, regionID);
105 try 120 try
106 { 121 {
107 PresenceData pdata = m_Database.Get(sessionID); 122 PresenceData presence = m_Database.Get(sessionID);
108 if (pdata == null) 123
109 return false; 124 bool success;
110 if (pdata.Data == null) 125 if (presence == null)
111 return false; 126 success = false;
127 else
128 success = m_Database.ReportAgent(sessionID, regionID);
112 129
113 return m_Database.ReportAgent(sessionID, regionID); 130 m_log.DebugFormat("[PRESENCE SERVICE]: ReportAgent{0}: session {1}, user {2}, region {3}. Previously: {4}",
131 success ? "" : " failed",
132 sessionID, (presence == null) ? null : presence.UserID, regionID,
133 (presence == null) ? "not logged-in" : "region " + presence.RegionID);
134
135 return success;
114 } 136 }
115 catch (Exception e) 137 catch (Exception e)
116 { 138 {
117 m_log.DebugFormat("[PRESENCE SERVICE]: ReportAgent threw exception {0}", e.StackTrace); 139 m_log.Debug(string.Format("[PRESENCE SERVICE]: ReportAgent for session {0} threw exception ", sessionID), e);
118 return false; 140 return false;
119 } 141 }
120 } 142 }
@@ -139,8 +161,7 @@ namespace OpenSim.Services.PresenceService
139 161
140 foreach (string userIDStr in userIDs) 162 foreach (string userIDStr in userIDs)
141 { 163 {
142 PresenceData[] data = m_Database.Get("UserID", 164 PresenceData[] data = m_Database.Get("UserID", userIDStr);
143 userIDStr);
144 165
145 foreach (PresenceData d in data) 166 foreach (PresenceData d in data)
146 { 167 {
@@ -158,5 +179,23 @@ namespace OpenSim.Services.PresenceService
158 179
159 return info.ToArray(); 180 return info.ToArray();
160 } 181 }
182
183 /// <summary>
184 /// Return the user's Presence. This only really works well if !AllowDuplicatePresences, but that's the default.
185 /// </summary>
186 private PresenceData GetUser(string userID)
187 {
188 PresenceData[] data = m_Database.Get("UserID", userID);
189 if (data.Length > 0)
190 return data[0];
191 else
192 return null;
193 }
194
195 private PresenceData[] GetRegionAgents(UUID regionID)
196 {
197 return m_Database.Get("RegionID", regionID.ToString());
198 }
199
161 } 200 }
162} \ No newline at end of file 201} \ No newline at end of file
diff --git a/OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs b/OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs
index 8c03dd7..4fd21a8 100644
--- a/OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs b/OpenSim/Services/SimulationService/SimulationDataService.cs
index 504fcaf..d9684c4 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationDataService.cs
+++ b/OpenSim/Services/SimulationService/SimulationDataService.cs
@@ -29,7 +29,6 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using OpenMetaverse; 30using OpenMetaverse;
31using log4net; 31using log4net;
32using Mono.Addins;
33using Nini.Config; 32using Nini.Config;
34using System.Reflection; 33using System.Reflection;
35using OpenSim.Services.Base; 34using OpenSim.Services.Base;
@@ -39,7 +38,7 @@ using OpenSim.Framework;
39using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
41 40
42namespace OpenSim.Services.Connectors 41namespace OpenSim.Services.SimulationService
43{ 42{
44 public class SimulationDataService : ServiceBase, ISimulationDataService 43 public class SimulationDataService : ServiceBase, ISimulationDataService
45 { 44 {
@@ -100,6 +99,11 @@ namespace OpenSim.Services.Connectors
100 return m_database.LoadObjects(regionUUID); 99 return m_database.LoadObjects(regionUUID);
101 } 100 }
102 101
102 public void StoreTerrain(TerrainData terrain, UUID regionID)
103 {
104 m_database.StoreTerrain(terrain, regionID);
105 }
106
103 public void StoreTerrain(double[,] terrain, UUID regionID) 107 public void StoreTerrain(double[,] terrain, UUID regionID)
104 { 108 {
105 m_database.StoreTerrain(terrain, regionID); 109 m_database.StoreTerrain(terrain, regionID);
@@ -110,6 +114,11 @@ namespace OpenSim.Services.Connectors
110 return m_database.LoadTerrain(regionID); 114 return m_database.LoadTerrain(regionID);
111 } 115 }
112 116
117 public TerrainData LoadTerrain(UUID regionID, int pSizeX, int pSizeY, int pSizeZ)
118 {
119 return m_database.LoadTerrain(regionID, pSizeX, pSizeY, pSizeZ);
120 }
121
113 public void StoreLandObject(ILandObject Parcel) 122 public void StoreLandObject(ILandObject Parcel)
114 { 123 {
115 m_database.StoreLandObject(Parcel); 124 m_database.StoreLandObject(Parcel);
diff --git a/OpenSim/Services/UserAccountService/AgentPreferencesService.cs b/OpenSim/Services/UserAccountService/AgentPreferencesService.cs
new file mode 100644
index 0000000..1808ee5
--- /dev/null
+++ b/OpenSim/Services/UserAccountService/AgentPreferencesService.cs
@@ -0,0 +1,82 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using OpenSim.Data;
35using OpenSim.Framework;
36using OpenSim.Services.Interfaces;
37
38namespace OpenSim.Services.UserAccountService
39{
40 public class AgentPreferencesService : AgentPreferencesServiceBase, IAgentPreferencesService
41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 public AgentPreferencesService(IConfigSource config) : base(config)
45 {
46 m_log.Debug("[AGENT PREFERENCES SERVICE]: Starting agent preferences service");
47 }
48
49 public AgentPrefs GetAgentPreferences(UUID principalID)
50 {
51 AgentPreferencesData d = m_Database.GetPrefs(principalID);
52 AgentPrefs prefs = (d == null) ? new AgentPrefs(principalID) : new AgentPrefs(d.Data);
53 return prefs;
54 }
55
56 public bool StoreAgentPreferences(AgentPrefs data)
57 {
58 AgentPreferencesData d = new AgentPreferencesData();
59 d.Data = new Dictionary<string, string>();
60 d.Data["PrincipalID"] = data.PrincipalID.ToString();
61 d.Data["AccessPrefs"] = data.AccessPrefs;
62 d.Data["HoverHeight"] = data.HoverHeight.ToString();
63 d.Data["Language"] = data.Language;
64 d.Data["LanguageIsPublic"] = (data.LanguageIsPublic ? "1" : "0");
65 d.Data["PermEveryone"] = data.PermEveryone.ToString();
66 d.Data["PermGroup"] = data.PermGroup.ToString();
67 d.Data["PermNextOwner"] = data.PermNextOwner.ToString();
68 return m_Database.Store(d);
69 }
70
71 public string GetLang(UUID principalID)
72 {
73 AgentPrefs data = GetAgentPreferences(principalID);
74 if (data != null)
75 {
76 if (data.LanguageIsPublic)
77 return data.Language;
78 }
79 return "en-us";
80 }
81 }
82}
diff --git a/OpenSim/Services/UserAccountService/AgentPreferencesServiceBase.cs b/OpenSim/Services/UserAccountService/AgentPreferencesServiceBase.cs
new file mode 100644
index 0000000..5974349
--- /dev/null
+++ b/OpenSim/Services/UserAccountService/AgentPreferencesServiceBase.cs
@@ -0,0 +1,73 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using Nini.Config;
31using OpenSim.Data;
32using OpenSim.Services.Interfaces;
33using OpenSim.Services.Base;
34
35namespace OpenSim.Services.UserAccountService
36{
37 public class AgentPreferencesServiceBase: ServiceBase
38 {
39 protected IAgentPreferencesData m_Database = null;
40
41 public AgentPreferencesServiceBase(IConfigSource config) : base(config)
42 {
43 string dllName = String.Empty;
44 string connString = String.Empty;
45 string realm = "AgentPrefs";
46
47 IConfig dbConfig = config.Configs["DatabaseService"];
48 if (dbConfig != null)
49 {
50 dllName = dbConfig.GetString("StorageProvider", String.Empty);
51 connString = dbConfig.GetString("ConnectionString", String.Empty);
52 }
53
54 IConfig userConfig = config.Configs["AgentPreferencesService"];
55 if (userConfig == null)
56 throw new Exception("No AgentPreferencesService configuration");
57
58 dllName = userConfig.GetString("StorageProvider", dllName);
59
60 if (dllName == String.Empty)
61 throw new Exception("No StorageProvider configured");
62
63 connString = userConfig.GetString("ConnectionString", connString);
64
65 realm = userConfig.GetString("Realm", realm);
66
67 m_Database = LoadPlugin<IAgentPreferencesData>(dllName, new Object[] {connString, realm});
68
69 if (m_Database == null)
70 throw new Exception("Could not find a storage interface in the given module");
71 }
72 }
73}
diff --git a/OpenSim/Services/UserAccountService/GridUserService.cs b/OpenSim/Services/UserAccountService/GridUserService.cs
index 43fa04b..80a9d9d 100644
--- a/OpenSim/Services/UserAccountService/GridUserService.cs
+++ b/OpenSim/Services/UserAccountService/GridUserService.cs
@@ -43,15 +43,117 @@ namespace OpenSim.Services.UserAccountService
43 public class GridUserService : GridUserServiceBase, IGridUserService 43 public class GridUserService : GridUserServiceBase, IGridUserService
44 { 44 {
45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 45 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 private static bool m_Initialized;
46 47
47 public GridUserService(IConfigSource config) : base(config) 48 public GridUserService(IConfigSource config) : base(config)
48 { 49 {
49 m_log.Debug("[USER GRID SERVICE]: Starting user grid service"); 50 m_log.Debug("[GRID USER SERVICE]: Starting user grid service");
51
52 if (!m_Initialized)
53 {
54 m_Initialized = true;
55
56 MainConsole.Instance.Commands.AddCommand(
57 "Users", false,
58 "show grid user",
59 "show grid user <ID>",
60 "Show grid user entry or entries that match or start with the given ID. This will normally be a UUID.",
61 "This is for debug purposes to see what data is found for a particular user id.",
62 HandleShowGridUser);
63
64 MainConsole.Instance.Commands.AddCommand(
65 "Users", false,
66 "show grid users online",
67 "show grid users online",
68 "Show number of grid users registered as online.",
69 "This number may not be accurate as a region may crash or not be cleanly shutdown and leave grid users shown as online\n."
70 + "For this reason, users online for more than 5 days are not currently counted",
71 HandleShowGridUsersOnline);
72 }
73 }
74
75 protected void HandleShowGridUser(string module, string[] cmdparams)
76 {
77 if (cmdparams.Length != 4)
78 {
79 MainConsole.Instance.Output("Usage: show grid user <UUID>");
80 return;
81 }
82
83 GridUserData[] data = m_Database.GetAll(cmdparams[3]);
84
85 foreach (GridUserData gu in data)
86 {
87 ConsoleDisplayList cdl = new ConsoleDisplayList();
88
89 cdl.AddRow("User ID", gu.UserID);
90
91 foreach (KeyValuePair<string,string> kvp in gu.Data)
92 cdl.AddRow(kvp.Key, kvp.Value);
93
94 MainConsole.Instance.Output(cdl.ToString());
95 }
96
97 MainConsole.Instance.OutputFormat("Entries: {0}", data.Length);
98 }
99
100 protected void HandleShowGridUsersOnline(string module, string[] cmdparams)
101 {
102// if (cmdparams.Length != 4)
103// {
104// MainConsole.Instance.Output("Usage: show grid users online");
105// return;
106// }
107
108// int onlineCount;
109 int onlineRecentlyCount = 0;
110
111 DateTime now = DateTime.UtcNow;
112
113 foreach (GridUserData gu in m_Database.GetAll(""))
114 {
115 if (bool.Parse(gu.Data["Online"]))
116 {
117// onlineCount++;
118
119 int unixLoginTime = int.Parse(gu.Data["Login"]);
120
121 if ((now - Util.ToDateTime(unixLoginTime)).Days < 5)
122 onlineRecentlyCount++;
123 }
124 }
125
126 MainConsole.Instance.OutputFormat("Users online: {0}", onlineRecentlyCount);
127 }
128
129 private GridUserData GetGridUserData(string userID)
130 {
131 GridUserData d = null;
132 if (userID.Length > 36) // it's a UUI
133 {
134 d = m_Database.Get(userID);
135 }
136 else // it's a UUID
137 {
138 GridUserData[] ds = m_Database.GetAll(userID);
139 if (ds == null)
140 return null;
141
142 if (ds.Length > 0)
143 {
144 d = ds[0];
145 foreach (GridUserData dd in ds)
146 if (dd.UserID.Length > d.UserID.Length) // find the longest
147 d = dd;
148 }
149 }
150
151 return d;
50 } 152 }
51 153
52 public virtual GridUserInfo GetGridUserInfo(string userID) 154 public virtual GridUserInfo GetGridUserInfo(string userID)
53 { 155 {
54 GridUserData d = m_Database.Get(userID); 156 GridUserData d = GetGridUserData(userID);
55 157
56 if (d == null) 158 if (d == null)
57 return null; 159 return null;
@@ -73,7 +175,7 @@ namespace OpenSim.Services.UserAccountService
73 return info; 175 return info;
74 } 176 }
75 177
76 public GridUserInfo[] GetGridUserInfo(string[] userIDs) 178 public virtual GridUserInfo[] GetGridUserInfo(string[] userIDs)
77 { 179 {
78 List<GridUserInfo> ret = new List<GridUserInfo>(); 180 List<GridUserInfo> ret = new List<GridUserInfo>();
79 181
@@ -86,7 +188,8 @@ namespace OpenSim.Services.UserAccountService
86 public GridUserInfo LoggedIn(string userID) 188 public GridUserInfo LoggedIn(string userID)
87 { 189 {
88 m_log.DebugFormat("[GRID USER SERVICE]: User {0} is online", userID); 190 m_log.DebugFormat("[GRID USER SERVICE]: User {0} is online", userID);
89 GridUserData d = m_Database.Get(userID); 191
192 GridUserData d = GetGridUserData(userID);
90 193
91 if (d == null) 194 if (d == null)
92 { 195 {
@@ -104,8 +207,9 @@ namespace OpenSim.Services.UserAccountService
104 207
105 public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) 208 public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
106 { 209 {
107 m_log.DebugFormat("[GRID USER SERVICE]: User {0} is offline", userID); 210 m_log.InfoFormat("[GRID USER SERVICE]: User {0} is offline", userID);
108 GridUserData d = m_Database.Get(userID); 211
212 GridUserData d = GetGridUserData(userID);
109 213
110 if (d == null) 214 if (d == null)
111 { 215 {
@@ -124,7 +228,8 @@ namespace OpenSim.Services.UserAccountService
124 228
125 public bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt) 229 public bool SetHome(string userID, UUID homeID, Vector3 homePosition, Vector3 homeLookAt)
126 { 230 {
127 GridUserData d = m_Database.Get(userID); 231 GridUserData d = GetGridUserData(userID);
232
128 if (d == null) 233 if (d == null)
129 { 234 {
130 d = new GridUserData(); 235 d = new GridUserData();
@@ -140,8 +245,10 @@ namespace OpenSim.Services.UserAccountService
140 245
141 public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt) 246 public bool SetLastPosition(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
142 { 247 {
143 //m_log.DebugFormat("[Grid User Service]: SetLastPosition for {0}", userID); 248// m_log.DebugFormat("[GRID USER SERVICE]: SetLastPosition for {0}", userID);
144 GridUserData d = m_Database.Get(userID); 249
250 GridUserData d = GetGridUserData(userID);
251
145 if (d == null) 252 if (d == null)
146 { 253 {
147 d = new GridUserData(); 254 d = new GridUserData();
@@ -155,4 +262,4 @@ namespace OpenSim.Services.UserAccountService
155 return m_Database.Store(d); 262 return m_Database.Store(d);
156 } 263 }
157 } 264 }
158} 265} \ No newline at end of file
diff --git a/OpenSim/Services/UserAccountService/GridUserServiceBase.cs b/OpenSim/Services/UserAccountService/GridUserServiceBase.cs
index 990cb63..8c5f5df 100644
--- a/OpenSim/Services/UserAccountService/GridUserServiceBase.cs
+++ b/OpenSim/Services/UserAccountService/GridUserServiceBase.cs
@@ -60,12 +60,12 @@ namespace OpenSim.Services.UserAccountService
60 // 60 //
61 // [GridUsetService] section overrides [DatabaseService], if it exists 61 // [GridUsetService] section overrides [DatabaseService], if it exists
62 // 62 //
63 IConfig presenceConfig = config.Configs["GridUserService"]; 63 IConfig usersConfig = config.Configs["GridUserService"];
64 if (presenceConfig != null) 64 if (usersConfig != null)
65 { 65 {
66 dllName = presenceConfig.GetString("StorageProvider", dllName); 66 dllName = usersConfig.GetString("StorageProvider", dllName);
67 connString = presenceConfig.GetString("ConnectionString", connString); 67 connString = usersConfig.GetString("ConnectionString", connString);
68 realm = presenceConfig.GetString("Realm", realm); 68 realm = usersConfig.GetString("Realm", realm);
69 } 69 }
70 70
71 // 71 //
diff --git a/OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs b/OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs
index 24e1d16..6ca07a6 100644
--- a/OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs
+++ b/OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
29// Build Number 29// Build Number
30// Revision 30// Revision
31// 31//
32[assembly: AssemblyVersion("0.7.5.*")] 32[assembly: AssemblyVersion("0.8.3.*")]
33[assembly: AssemblyFileVersion("1.0.0.0")] 33
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs
index 5b4d040..2e19ece 100644
--- a/OpenSim/Services/UserAccountService/UserAccountService.cs
+++ b/OpenSim/Services/UserAccountService/UserAccountService.cs
@@ -36,6 +36,7 @@ using OpenSim.Framework;
36using OpenSim.Services.Interfaces; 36using OpenSim.Services.Interfaces;
37using OpenSim.Framework.Console; 37using OpenSim.Framework.Console;
38using GridRegion = OpenSim.Services.Interfaces.GridRegion; 38using GridRegion = OpenSim.Services.Interfaces.GridRegion;
39using PermissionMask = OpenSim.Framework.PermissionMask;
39 40
40namespace OpenSim.Services.UserAccountService 41namespace OpenSim.Services.UserAccountService
41{ 42{
@@ -97,7 +98,12 @@ namespace OpenSim.Services.UserAccountService
97 MainConsole.Instance.Commands.AddCommand("Users", false, 98 MainConsole.Instance.Commands.AddCommand("Users", false,
98 "reset user password", 99 "reset user password",
99 "reset user password [<first> [<last> [<password>]]]", 100 "reset user password [<first> [<last> [<password>]]]",
100 "Reset a user password", HandleResetUserPassword); 101 "Reset a user password", HandleResetUserPassword);
102
103 MainConsole.Instance.Commands.AddCommand("Users", false,
104 "reset user email",
105 "reset user email [<first> [<last> [<email>]]]",
106 "Reset a user email address", HandleResetUserEmail);
101 107
102 MainConsole.Instance.Commands.AddCommand("Users", false, 108 MainConsole.Instance.Commands.AddCommand("Users", false,
103 "set user level", 109 "set user level",
@@ -255,6 +261,10 @@ namespace OpenSim.Services.UserAccountService
255 return MakeUserAccount(d[0]); 261 return MakeUserAccount(d[0]);
256 } 262 }
257 263
264 public void InvalidateCache(UUID userID)
265 {
266 }
267
258 public bool StoreUserAccount(UserAccount data) 268 public bool StoreUserAccount(UserAccount data)
259 { 269 {
260// m_log.DebugFormat( 270// m_log.DebugFormat(
@@ -415,6 +425,43 @@ namespace OpenSim.Services.UserAccountService
415 MainConsole.Instance.OutputFormat("Password reset for user {0} {1}", firstName, lastName); 425 MainConsole.Instance.OutputFormat("Password reset for user {0} {1}", firstName, lastName);
416 } 426 }
417 427
428 protected void HandleResetUserEmail(string module, string[] cmdparams)
429 {
430 string firstName;
431 string lastName;
432 string newEmail;
433
434 if (cmdparams.Length < 4)
435 firstName = MainConsole.Instance.CmdPrompt("First name");
436 else firstName = cmdparams[3];
437
438 if (cmdparams.Length < 5)
439 lastName = MainConsole.Instance.CmdPrompt("Last name");
440 else lastName = cmdparams[4];
441
442 if (cmdparams.Length < 6)
443 newEmail = MainConsole.Instance.PasswdPrompt("New Email");
444 else newEmail = cmdparams[5];
445
446 UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
447 if (account == null)
448 {
449 MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName);
450 return;
451 }
452
453 bool success = false;
454
455 account.Email = newEmail;
456
457 success = StoreUserAccount(account);
458 if (!success)
459 MainConsole.Instance.OutputFormat("Unable to set Email for account {0} {1}.", firstName, lastName);
460 else
461 MainConsole.Instance.OutputFormat("User Email set for user {0} {1} to {2}", firstName, lastName, account.Email);
462 }
463
464
418 protected void HandleSetUserLevel(string module, string[] cmdparams) 465 protected void HandleSetUserLevel(string module, string[] cmdparams)
419 { 466 {
420 string firstName; 467 string firstName;
@@ -475,7 +522,6 @@ namespace OpenSim.Services.UserAccountService
475 { 522 {
476 account.ServiceURLs = new Dictionary<string, object>(); 523 account.ServiceURLs = new Dictionary<string, object>();
477 account.ServiceURLs["HomeURI"] = string.Empty; 524 account.ServiceURLs["HomeURI"] = string.Empty;
478 account.ServiceURLs["GatekeeperURI"] = string.Empty;
479 account.ServiceURLs["InventoryServerURI"] = string.Empty; 525 account.ServiceURLs["InventoryServerURI"] = string.Empty;
480 account.ServiceURLs["AssetServerURI"] = string.Empty; 526 account.ServiceURLs["AssetServerURI"] = string.Empty;
481 } 527 }
@@ -549,7 +595,7 @@ namespace OpenSim.Services.UserAccountService
549 { 595 {
550 m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID); 596 m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID);
551 597
552 InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Bodypart); 598 InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, FolderType.BodyPart);
553 599
554 InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID); 600 InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID);
555 eyes.AssetID = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7"); 601 eyes.AssetID = new UUID("4bb6fa4d-1cd2-498a-a84c-95c1a0e745a7");
@@ -611,7 +657,7 @@ namespace OpenSim.Services.UserAccountService
611 hair.Flags = (uint)WearableType.Hair; 657 hair.Flags = (uint)WearableType.Hair;
612 m_InventoryService.AddItem(hair); 658 m_InventoryService.AddItem(hair);
613 659
614 InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, AssetType.Clothing); 660 InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, FolderType.Clothing);
615 661
616 InventoryItemBase shirt = new InventoryItemBase(UUID.Random(), principalID); 662 InventoryItemBase shirt = new InventoryItemBase(UUID.Random(), principalID);
617 shirt.AssetID = AvatarWearable.DEFAULT_SHIRT_ASSET; 663 shirt.AssetID = AvatarWearable.DEFAULT_SHIRT_ASSET;
@@ -665,4 +711,4 @@ namespace OpenSim.Services.UserAccountService
665 } 711 }
666 } 712 }
667 } 713 }
668} \ No newline at end of file 714}
diff --git a/OpenSim/Services/UserProfilesService/UserProfilesService.cs b/OpenSim/Services/UserProfilesService/UserProfilesService.cs
new file mode 100644
index 0000000..96c13c0
--- /dev/null
+++ b/OpenSim/Services/UserProfilesService/UserProfilesService.cs
@@ -0,0 +1,263 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Text;
31using Nini.Config;
32using log4net;
33using OpenSim.Server.Base;
34using OpenSim.Services.Interfaces;
35using OpenSim.Services.UserAccountService;
36using OpenSim.Data;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40
41namespace OpenSim.Services.ProfilesService
42{
43 public class UserProfilesService: UserProfilesServiceBase, IUserProfilesService
44 {
45 static readonly ILog m_log =
46 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType);
48
49 IUserAccountService userAccounts;
50
51 public UserProfilesService(IConfigSource config, string configName):
52 base(config, configName)
53 {
54 IConfig Config = config.Configs[configName];
55 if (Config == null)
56 {
57 m_log.Warn("[PROFILES SERVICE]: No configuration found!");
58 return;
59 }
60 Object[] args = null;
61
62 args = new Object[] { config };
63 string accountService = Config.GetString("UserAccountService", String.Empty);
64 if (accountService != string.Empty)
65 userAccounts = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
66
67 args = new Object[] { config };
68 }
69
70 #region Classifieds
71 public OSD AvatarClassifiedsRequest(UUID creatorId)
72 {
73 OSDArray records = ProfilesData.GetClassifiedRecords(creatorId);
74
75 return records;
76 }
77
78 public bool ClassifiedUpdate(UserClassifiedAdd ad, ref string result)
79 {
80 if(!ProfilesData.UpdateClassifiedRecord(ad, ref result))
81 {
82 return false;
83 }
84 result = "success";
85 return true;
86 }
87
88 public bool ClassifiedDelete(UUID recordId)
89 {
90 if(ProfilesData.DeleteClassifiedRecord(recordId))
91 return true;
92
93 return false;
94 }
95
96 public bool ClassifiedInfoRequest(ref UserClassifiedAdd ad, ref string result)
97 {
98 if(ProfilesData.GetClassifiedInfo(ref ad, ref result))
99 return true;
100
101 return false;
102 }
103 #endregion Classifieds
104
105 #region Picks
106 public OSD AvatarPicksRequest(UUID creatorId)
107 {
108 OSDArray records = ProfilesData.GetAvatarPicks(creatorId);
109
110 return records;
111 }
112
113 public bool PickInfoRequest(ref UserProfilePick pick, ref string result)
114 {
115 pick = ProfilesData.GetPickInfo(pick.CreatorId, pick.PickId);
116 result = "OK";
117 return true;
118 }
119
120 public bool PicksUpdate(ref UserProfilePick pick, ref string result)
121 {
122 return ProfilesData.UpdatePicksRecord(pick);
123 }
124
125 public bool PicksDelete(UUID pickId)
126 {
127 return ProfilesData.DeletePicksRecord(pickId);
128 }
129 #endregion Picks
130
131 #region Notes
132 public bool AvatarNotesRequest(ref UserProfileNotes note)
133 {
134 return ProfilesData.GetAvatarNotes(ref note);
135 }
136
137 public bool NotesUpdate(ref UserProfileNotes note, ref string result)
138 {
139 return ProfilesData.UpdateAvatarNotes(ref note, ref result);
140 }
141 #endregion Notes
142
143 #region Profile Properties
144 public bool AvatarPropertiesRequest(ref UserProfileProperties prop, ref string result)
145 {
146 return ProfilesData.GetAvatarProperties(ref prop, ref result);
147 }
148
149 public bool AvatarPropertiesUpdate(ref UserProfileProperties prop, ref string result)
150 {
151 return ProfilesData.UpdateAvatarProperties(ref prop, ref result);
152 }
153 #endregion Profile Properties
154
155 #region Interests
156 public bool AvatarInterestsUpdate(UserProfileProperties prop, ref string result)
157 {
158 return ProfilesData.UpdateAvatarInterests(prop, ref result);
159 }
160 #endregion Interests
161
162 #region User Preferences
163 public bool UserPreferencesUpdate(ref UserPreferences pref, ref string result)
164 {
165 if(string.IsNullOrEmpty(pref.EMail))
166 {
167 UserAccount account = new UserAccount();
168 if(userAccounts is UserAccountService.UserAccountService)
169 {
170 try
171 {
172 account = userAccounts.GetUserAccount(UUID.Zero, pref.UserId);
173 if(string.IsNullOrEmpty(account.Email))
174 {
175 pref.EMail = string.Empty;
176 }
177 else
178 pref.EMail = account.Email;
179 }
180 catch
181 {
182 m_log.Error ("[PROFILES SERVICE]: UserAccountService Exception: Could not get user account");
183 result = "UserAccountService settings error in UserProfileService!";
184 return false;
185 }
186 }
187 else
188 {
189 m_log.Error ("[PROFILES SERVICE]: UserAccountService: Could not get user account");
190 result = "UserAccountService settings error in UserProfileService!";
191 return false;
192 }
193 }
194 return ProfilesData.UpdateUserPreferences(ref pref, ref result);
195 }
196
197 public bool UserPreferencesRequest(ref UserPreferences pref, ref string result)
198 {
199 if (!ProfilesData.GetUserPreferences(ref pref, ref result))
200 return false;
201
202 if(string.IsNullOrEmpty(pref.EMail))
203 {
204 UserAccount account = new UserAccount();
205 if(userAccounts is UserAccountService.UserAccountService)
206 {
207 try
208 {
209 account = userAccounts.GetUserAccount(UUID.Zero, pref.UserId);
210 if(string.IsNullOrEmpty(account.Email))
211 {
212 pref.EMail = string.Empty;
213 }
214 else
215 {
216 pref.EMail = account.Email;
217 UserPreferencesUpdate(ref pref, ref result);
218 }
219 }
220 catch
221 {
222 m_log.Error ("[PROFILES SERVICE]: UserAccountService Exception: Could not get user account");
223 result = "UserAccountService settings error in UserProfileService!";
224 return false;
225 }
226 }
227 else
228 {
229 m_log.Error ("[PROFILES SERVICE]: UserAccountService: Could not get user account");
230 result = "UserAccountService settings error in UserProfileService!";
231 return false;
232 }
233 }
234
235 if(string.IsNullOrEmpty(pref.EMail))
236 pref.EMail = "No Email Address On Record";
237
238 return true;
239 }
240 #endregion User Preferences
241
242 #region Utility
243 public OSD AvatarImageAssetsRequest(UUID avatarId)
244 {
245 OSDArray records = ProfilesData.GetUserImageAssets(avatarId);
246 return records;
247 }
248 #endregion Utility
249
250 #region UserData
251 public bool RequestUserAppData(ref UserAppData prop, ref string result)
252 {
253 return ProfilesData.GetUserAppData(ref prop, ref result);
254 }
255
256 public bool SetUserAppData(UserAppData prop, ref string result)
257 {
258 return true;
259 }
260 #endregion UserData
261 }
262}
263
diff --git a/OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs b/OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs
new file mode 100644
index 0000000..c31578f
--- /dev/null
+++ b/OpenSim/Services/UserProfilesService/UserProfilesServiceBase.cs
@@ -0,0 +1,87 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using Nini.Config;
31using log4net;
32using OpenSim.Services.Base;
33using OpenSim.Data;
34
35namespace OpenSim.Services.ProfilesService
36{
37 public class UserProfilesServiceBase: ServiceBase
38 {
39 static readonly ILog m_log =
40 LogManager.GetLogger(
41 MethodBase.GetCurrentMethod().DeclaringType);
42
43 public IProfilesData ProfilesData;
44
45 public string ConfigName
46 {
47 get; private set;
48 }
49
50 public UserProfilesServiceBase(IConfigSource config, string configName):
51 base(config)
52 {
53 if(string.IsNullOrEmpty(configName))
54 {
55 m_log.WarnFormat("[PROFILES SERVICE]: Configuration section not given!");
56 return;
57 }
58
59 string dllName = String.Empty;
60 string connString = null;
61 string realm = String.Empty;
62
63 IConfig dbConfig = config.Configs["DatabaseService"];
64 if (dbConfig != null)
65 {
66 if (dllName == String.Empty)
67 dllName = dbConfig.GetString("StorageProvider", String.Empty);
68 if (string.IsNullOrEmpty(connString))
69 connString = dbConfig.GetString("ConnectionString", String.Empty);
70 }
71
72 IConfig ProfilesConfig = config.Configs[configName];
73 if (ProfilesConfig != null)
74 {
75 dllName = ProfilesConfig.GetString("StorageProvider", dllName);
76 connString = ProfilesConfig.GetString("ConnectionString", connString);
77 realm = ProfilesConfig.GetString("Realm", realm);
78 }
79
80 ProfilesData = LoadPlugin<IProfilesData>(dllName, new Object[] { connString });
81 if (ProfilesData == null)
82 throw new Exception("Could not find a storage interface in the given module");
83
84 }
85 }
86}
87