aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/HypergridService
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/HypergridService')
-rw-r--r--OpenSim/Services/HypergridService/GatekeeperService.cs3
-rw-r--r--OpenSim/Services/HypergridService/HGAssetService.cs145
-rw-r--r--OpenSim/Services/HypergridService/HGInventoryService.cs340
-rw-r--r--OpenSim/Services/HypergridService/UserAccountCache.cs105
4 files changed, 592 insertions, 1 deletions
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs
index 9e96163..10e3aee 100644
--- a/OpenSim/Services/HypergridService/GatekeeperService.cs
+++ b/OpenSim/Services/HypergridService/GatekeeperService.cs
@@ -333,7 +333,8 @@ namespace OpenSim.Services.HypergridService
333 333
334 string addressee = parts[0]; 334 string addressee = parts[0];
335 m_log.DebugFormat("[GATEKEEPER SERVICE]: Verifying {0} against {1}", addressee, m_ExternalName); 335 m_log.DebugFormat("[GATEKEEPER SERVICE]: Verifying {0} against {1}", addressee, m_ExternalName);
336 return (addressee == m_ExternalName); 336
337 return string.Equals(addressee, m_ExternalName, StringComparison.OrdinalIgnoreCase);
337 } 338 }
338 339
339 #endregion 340 #endregion
diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs
new file mode 100644
index 0000000..a82d0d1
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGAssetService.cs
@@ -0,0 +1,145 @@
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.IO;
30using System.Reflection;
31using System.Xml;
32
33using Nini.Config;
34using log4net;
35using OpenMetaverse;
36
37using OpenSim.Framework;
38using OpenSim.Framework.Serialization.External;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.AssetService;
42
43namespace OpenSim.Services.HypergridService
44{
45 /// <summary>
46 /// Hypergrid asset service. It serves the IAssetService interface,
47 /// but implements it in ways that are appropriate for inter-grid
48 /// asset exchanges.
49 /// </summary>
50 public class HGAssetService : OpenSim.Services.AssetService.AssetService, IAssetService
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 private string m_ProfileServiceURL;
57 private IUserAccountService m_UserAccountService;
58
59 private UserAccountCache m_Cache;
60
61 public HGAssetService(IConfigSource config) : base(config)
62 {
63 m_log.Debug("[HGAsset Service]: Starting");
64 IConfig assetConfig = config.Configs["HGAssetService"];
65 if (assetConfig == null)
66 throw new Exception("No HGAssetService configuration");
67
68 string userAccountsDll = assetConfig.GetString("UserAccountsService", string.Empty);
69 if (userAccountsDll == string.Empty)
70 throw new Exception("Please specify UserAccountsService in HGAssetService configuration");
71
72 Object[] args = new Object[] { config };
73 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountsDll, args);
74 if (m_UserAccountService == null)
75 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
76
77 m_ProfileServiceURL = assetConfig.GetString("ProfileServerURI", string.Empty);
78
79 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
80 }
81
82 #region IAssetService overrides
83 public override AssetBase Get(string id)
84 {
85 AssetBase asset = base.Get(id);
86
87 if (asset == null)
88 return null;
89
90 if (asset.Metadata.Type == (sbyte)AssetType.Object)
91 asset.Data = AdjustIdentifiers(asset.Data); ;
92
93 AdjustIdentifiers(asset.Metadata);
94
95 return asset;
96 }
97
98 public override AssetMetadata GetMetadata(string id)
99 {
100 AssetMetadata meta = base.GetMetadata(id);
101
102 if (meta == null)
103 return null;
104
105 AdjustIdentifiers(meta);
106
107 return meta;
108 }
109
110 public override byte[] GetData(string id)
111 {
112 byte[] data = base.GetData(id);
113
114 if (data == null)
115 return null;
116
117 return AdjustIdentifiers(data);
118 }
119
120 //public virtual bool Get(string id, Object sender, AssetRetrieved handler)
121
122 public override bool Delete(string id)
123 {
124 // NOGO
125 return false;
126 }
127
128 #endregion
129
130 protected void AdjustIdentifiers(AssetMetadata meta)
131 {
132 UserAccount creator = m_Cache.GetUser(meta.CreatorID);
133 if (creator != null)
134 meta.CreatorID = m_ProfileServiceURL + "/" + meta.CreatorID + ";" + creator.FirstName + " " + creator.LastName;
135 }
136
137 protected byte[] AdjustIdentifiers(byte[] data)
138 {
139 string xml = Utils.BytesToString(data);
140 return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, m_ProfileServiceURL, m_Cache, UUID.Zero));
141 }
142
143 }
144
145}
diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs
new file mode 100644
index 0000000..9ee1ae4
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGInventoryService.cs
@@ -0,0 +1,340 @@
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;
31using log4net;
32using Nini.Config;
33using System.Reflection;
34using OpenSim.Services.Base;
35using OpenSim.Services.Interfaces;
36using OpenSim.Services.InventoryService;
37using OpenSim.Data;
38using OpenSim.Framework;
39using OpenSim.Server.Base;
40
41namespace OpenSim.Services.HypergridService
42{
43 /// <summary>
44 /// Hypergrid inventory service. It serves the IInventoryService interface,
45 /// but implements it in ways that are appropriate for inter-grid
46 /// inventory exchanges. Specifically, it does not performs deletions
47 /// and it responds to GetRootFolder requests with the ID of the
48 /// Suitcase folder, not the actual "My Inventory" folder.
49 /// </summary>
50 public class HGInventoryService : XInventoryService, IInventoryService
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 protected new IXInventoryData m_Database;
57
58 private string m_ProfileServiceURL;
59 private IUserAccountService m_UserAccountService;
60
61 private UserAccountCache m_Cache;
62
63 public HGInventoryService(IConfigSource config)
64 : base(config)
65 {
66 m_log.Debug("[HGInventory Service]: Starting");
67
68 string dllName = String.Empty;
69 string connString = String.Empty;
70 //string realm = "Inventory"; // OSG version doesn't use this
71
72 //
73 // Try reading the [DatabaseService] section, if it exists
74 //
75 IConfig dbConfig = config.Configs["DatabaseService"];
76 if (dbConfig != null)
77 {
78 if (dllName == String.Empty)
79 dllName = dbConfig.GetString("StorageProvider", String.Empty);
80 if (connString == String.Empty)
81 connString = dbConfig.GetString("ConnectionString", String.Empty);
82 }
83
84 //
85 // Try reading the [InventoryService] section, if it exists
86 //
87 IConfig invConfig = config.Configs["HGInventoryService"];
88 if (invConfig != null)
89 {
90 dllName = invConfig.GetString("StorageProvider", dllName);
91 connString = invConfig.GetString("ConnectionString", connString);
92
93 // realm = authConfig.GetString("Realm", realm);
94 string userAccountsDll = invConfig.GetString("UserAccountsService", string.Empty);
95 if (userAccountsDll == string.Empty)
96 throw new Exception("Please specify UserAccountsService in HGInventoryService configuration");
97
98 Object[] args = new Object[] { config };
99 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(userAccountsDll, args);
100 if (m_UserAccountService == null)
101 throw new Exception(String.Format("Unable to create UserAccountService from {0}", userAccountsDll));
102
103 m_ProfileServiceURL = invConfig.GetString("ProfileServerURI", string.Empty);
104
105 m_Cache = UserAccountCache.CreateUserAccountCache(m_UserAccountService);
106 }
107
108 //
109 // We tried, but this doesn't exist. We can't proceed.
110 //
111 if (dllName == String.Empty)
112 throw new Exception("No StorageProvider configured");
113
114 m_Database = LoadPlugin<IXInventoryData>(dllName,
115 new Object[] {connString, String.Empty});
116 if (m_Database == null)
117 throw new Exception("Could not find a storage interface in the given module");
118
119 m_log.Debug("[HG INVENTORY SERVICE]: Starting...");
120 }
121
122 public override bool CreateUserInventory(UUID principalID)
123 {
124 // NOGO
125 return false;
126 }
127
128
129 public override List<InventoryFolderBase> GetInventorySkeleton(UUID principalID)
130 {
131 // NOGO for this inventory service
132 return new List<InventoryFolderBase>();
133 }
134
135 public override InventoryFolderBase GetRootFolder(UUID principalID)
136 {
137 // Warp! Root folder for travelers
138 XInventoryFolder[] folders = m_Database.GetFolders(
139 new string[] { "agentID", "folderName"},
140 new string[] { principalID.ToString(), "My Suitcase" });
141
142 if (folders.Length > 0)
143 return ConvertToOpenSim(folders[0]);
144
145 // make one
146 XInventoryFolder suitcase = CreateFolder(principalID, UUID.Zero, (int)AssetType.Folder, "My Suitcase");
147 return ConvertToOpenSim(suitcase);
148 }
149
150 //private bool CreateSystemFolders(UUID principalID, XInventoryFolder suitcase)
151 //{
152
153 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Animation, "Animations");
154 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Bodypart, "Body Parts");
155 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.CallingCard, "Calling Cards");
156 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Clothing, "Clothing");
157 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Gesture, "Gestures");
158 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Landmark, "Landmarks");
159 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.LostAndFoundFolder, "Lost And Found");
160 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Notecard, "Notecards");
161 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Object, "Objects");
162 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.SnapshotFolder, "Photo Album");
163 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.LSLText, "Scripts");
164 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Sound, "Sounds");
165 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.Texture, "Textures");
166 // CreateFolder(principalID, suitcase.folderID, (int)AssetType.TrashFolder, "Trash");
167
168 // return true;
169 //}
170
171
172 public override InventoryFolderBase GetFolderForType(UUID principalID, AssetType type)
173 {
174 return GetRootFolder(principalID);
175 }
176
177 //
178 // Use the inherited methods
179 //
180 //public InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
181 //{
182 //}
183
184 //public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID)
185 //{
186 //}
187
188 //public override bool AddFolder(InventoryFolderBase folder)
189 //{
190 // // Check if it's under the Suitcase folder
191 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner);
192 // InventoryFolderBase suitcase = GetRootFolder(folder.Owner);
193 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
194
195 // foreach (InventoryFolderBase f in suitDescendents)
196 // if (folder.ParentID == f.ID)
197 // {
198 // XInventoryFolder xFolder = ConvertFromOpenSim(folder);
199 // return m_Database.StoreFolder(xFolder);
200 // }
201 // return false;
202 //}
203
204 private List<InventoryFolderBase> GetDescendents(List<InventoryFolderBase> lst, UUID root)
205 {
206 List<InventoryFolderBase> direct = lst.FindAll(delegate(InventoryFolderBase f) { return f.ParentID == root; });
207 if (direct == null)
208 return new List<InventoryFolderBase>();
209
210 List<InventoryFolderBase> indirect = new List<InventoryFolderBase>();
211 foreach (InventoryFolderBase f in direct)
212 indirect.AddRange(GetDescendents(lst, f.ID));
213
214 direct.AddRange(indirect);
215 return direct;
216 }
217
218 // Use inherited method
219 //public bool UpdateFolder(InventoryFolderBase folder)
220 //{
221 //}
222
223 //public override bool MoveFolder(InventoryFolderBase folder)
224 //{
225 // XInventoryFolder[] x = m_Database.GetFolders(
226 // new string[] { "folderID" },
227 // new string[] { folder.ID.ToString() });
228
229 // if (x.Length == 0)
230 // return false;
231
232 // // Check if it's under the Suitcase folder
233 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(folder.Owner);
234 // InventoryFolderBase suitcase = GetRootFolder(folder.Owner);
235 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
236
237 // foreach (InventoryFolderBase f in suitDescendents)
238 // if (folder.ParentID == f.ID)
239 // {
240 // x[0].parentFolderID = folder.ParentID;
241 // return m_Database.StoreFolder(x[0]);
242 // }
243
244 // return false;
245 //}
246
247 public override bool DeleteFolders(UUID principalID, List<UUID> folderIDs)
248 {
249 // NOGO
250 return false;
251 }
252
253 public override bool PurgeFolder(InventoryFolderBase folder)
254 {
255 // NOGO
256 return false;
257 }
258
259 // Unfortunately we need to use the inherited method because of how DeRez works.
260 // The viewer sends the folderID hard-wired in the derez message
261 //public override bool AddItem(InventoryItemBase item)
262 //{
263 // // Check if it's under the Suitcase folder
264 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner);
265 // InventoryFolderBase suitcase = GetRootFolder(item.Owner);
266 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
267
268 // foreach (InventoryFolderBase f in suitDescendents)
269 // if (item.Folder == f.ID)
270 // return m_Database.StoreItem(ConvertFromOpenSim(item));
271
272 // return false;
273 //}
274
275 //public override bool UpdateItem(InventoryItemBase item)
276 //{
277 // // Check if it's under the Suitcase folder
278 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(item.Owner);
279 // InventoryFolderBase suitcase = GetRootFolder(item.Owner);
280 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
281
282 // foreach (InventoryFolderBase f in suitDescendents)
283 // if (item.Folder == f.ID)
284 // return m_Database.StoreItem(ConvertFromOpenSim(item));
285
286 // return false;
287 //}
288
289 //public override bool MoveItems(UUID principalID, List<InventoryItemBase> items)
290 //{
291 // // Principal is b0rked. *sigh*
292 // //
293 // // Let's assume they all have the same principal
294 // // Check if it's under the Suitcase folder
295 // List<InventoryFolderBase> skel = base.GetInventorySkeleton(items[0].Owner);
296 // InventoryFolderBase suitcase = GetRootFolder(items[0].Owner);
297 // List<InventoryFolderBase> suitDescendents = GetDescendents(skel, suitcase.ID);
298
299 // foreach (InventoryItemBase i in items)
300 // {
301 // foreach (InventoryFolderBase f in suitDescendents)
302 // if (i.Folder == f.ID)
303 // m_Database.MoveItem(i.ID.ToString(), i.Folder.ToString());
304 // }
305
306 // return true;
307 //}
308
309 // Let these pass. Use inherited methods.
310 //public bool DeleteItems(UUID principalID, List<UUID> itemIDs)
311 //{
312 //}
313
314 public override InventoryItemBase GetItem(InventoryItemBase item)
315 {
316 InventoryItemBase it = base.GetItem(item);
317
318 UserAccount user = m_Cache.GetUser(it.CreatorId);
319
320 // Adjust the creator data
321 if (user != null && it != null && (it.CreatorData == null || it.CreatorData == string.Empty))
322 it.CreatorData = m_ProfileServiceURL + "/" + it.CreatorId + ";" + user.FirstName + " " + user.LastName;
323
324 return it;
325 }
326
327 //public InventoryFolderBase GetFolder(InventoryFolderBase folder)
328 //{
329 //}
330
331 //public List<InventoryItemBase> GetActiveGestures(UUID principalID)
332 //{
333 //}
334
335 //public int GetAssetPermissions(UUID principalID, UUID assetID)
336 //{
337 //}
338
339 }
340}
diff --git a/OpenSim/Services/HypergridService/UserAccountCache.cs b/OpenSim/Services/HypergridService/UserAccountCache.cs
new file mode 100644
index 0000000..3e9aea1
--- /dev/null
+++ b/OpenSim/Services/HypergridService/UserAccountCache.cs
@@ -0,0 +1,105 @@
1using System;
2using System.Collections.Generic;
3using System.Reflection;
4
5using log4net;
6using OpenMetaverse;
7
8using OpenSim.Services.Interfaces;
9
10namespace OpenSim.Services.HypergridService
11{
12 public class UserAccountCache : IUserAccountService
13 {
14 private const double CACHE_EXPIRATION_SECONDS = 120000.0; // 33 hours!
15
16 private static readonly ILog m_log =
17 LogManager.GetLogger(
18 MethodBase.GetCurrentMethod().DeclaringType);
19 private ExpiringCache<UUID, UserAccount> m_UUIDCache;
20
21 private IUserAccountService m_UserAccountService;
22
23 private static UserAccountCache m_Singleton;
24
25 public static UserAccountCache CreateUserAccountCache(IUserAccountService u)
26 {
27 if (m_Singleton == null)
28 m_Singleton = new UserAccountCache(u);
29
30 return m_Singleton;
31 }
32
33 private UserAccountCache(IUserAccountService u)
34 {
35 m_UUIDCache = new ExpiringCache<UUID, UserAccount>();
36 m_UserAccountService = u;
37 }
38
39 public void Cache(UUID userID, UserAccount account)
40 {
41 // Cache even null accounts
42 m_UUIDCache.AddOrUpdate(userID, account, CACHE_EXPIRATION_SECONDS);
43
44 //m_log.DebugFormat("[USER CACHE]: cached user {0}", userID);
45 }
46
47 public UserAccount Get(UUID userID, out bool inCache)
48 {
49 UserAccount account = null;
50 inCache = false;
51 if (m_UUIDCache.TryGetValue(userID, out account))
52 {
53 //m_log.DebugFormat("[USER CACHE]: Account {0} {1} found in cache", account.FirstName, account.LastName);
54 inCache = true;
55 return account;
56 }
57
58 return null;
59 }
60
61 public UserAccount GetUser(string id)
62 {
63 UUID uuid = UUID.Zero;
64 UUID.TryParse(id, out uuid);
65 bool inCache = false;
66 UserAccount account = Get(uuid, out inCache);
67 if (!inCache)
68 {
69 account = m_UserAccountService.GetUserAccount(UUID.Zero, uuid);
70 Cache(uuid, account);
71 }
72
73 return account;
74 }
75
76 #region IUserAccountService
77 public UserAccount GetUserAccount(UUID scopeID, UUID userID)
78 {
79 return GetUser(userID.ToString());
80 }
81
82 public UserAccount GetUserAccount(UUID scopeID, string FirstName, string LastName)
83 {
84 return null;
85 }
86
87 public UserAccount GetUserAccount(UUID scopeID, string Email)
88 {
89 return null;
90 }
91
92 public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
93 {
94 return null;
95 }
96
97 public bool StoreUserAccount(UserAccount data)
98 {
99 return false;
100 }
101 #endregion
102
103 }
104
105}