aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services')
-rw-r--r--OpenSim/Services/AssetService/XAssetService.cs213
-rw-r--r--OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs21
-rw-r--r--OpenSim/Services/GridService/GridService.cs4
-rw-r--r--OpenSim/Services/HypergridService/GatekeeperService.cs5
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs38
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs12
-rw-r--r--OpenSim/Services/UserAccountService/UserAccountService.cs8
7 files changed, 287 insertions, 14 deletions
diff --git a/OpenSim/Services/AssetService/XAssetService.cs b/OpenSim/Services/AssetService/XAssetService.cs
new file mode 100644
index 0000000..d161c58
--- /dev/null
+++ b/OpenSim/Services/AssetService/XAssetService.cs
@@ -0,0 +1,213 @@
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.IO;
31using System.Reflection;
32using Nini.Config;
33using log4net;
34using OpenSim.Framework;
35using OpenSim.Data;
36using OpenSim.Services.Interfaces;
37using OpenMetaverse;
38
39namespace OpenSim.Services.AssetService
40{
41 /// <summary>
42 /// This will be developed into 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>
45 public class XAssetService : AssetServiceBase, IAssetService
46 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 protected static XAssetService m_RootInstance;
50
51 public XAssetService(IConfigSource config) : base(config)
52 {
53 if (m_RootInstance == null)
54 {
55 m_RootInstance = this;
56
57 if (m_AssetLoader != null)
58 {
59 IConfig assetConfig = config.Configs["AssetService"];
60 if (assetConfig == null)
61 throw new Exception("No AssetService configuration");
62
63 string loaderArgs = assetConfig.GetString("AssetLoaderArgs",
64 String.Empty);
65
66 bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true);
67
68 if (assetLoaderEnabled)
69 {
70 m_log.DebugFormat("[XASSET SERVICE]: Loading default asset set from {0}", loaderArgs);
71
72 m_AssetLoader.ForEachDefaultXmlAsset(
73 loaderArgs,
74 delegate(AssetBase a)
75 {
76 AssetBase existingAsset = Get(a.ID);
77// AssetMetadata existingMetadata = GetMetadata(a.ID);
78
79 if (existingAsset == null || Util.SHA1Hash(existingAsset.Data) != Util.SHA1Hash(a.Data))
80 {
81// m_log.DebugFormat("[ASSET]: Storing {0} {1}", a.Name, a.ID);
82 Store(a);
83 }
84 });
85 }
86
87 m_log.Debug("[XASSET SERVICE]: Local asset service enabled");
88 }
89 }
90 }
91
92 public virtual AssetBase Get(string id)
93 {
94// m_log.DebugFormat("[ASSET SERVICE]: Get asset for {0}", id);
95
96 UUID assetID;
97
98 if (!UUID.TryParse(id, out assetID))
99 {
100 m_log.WarnFormat("[XASSET SERVICE]: Could not parse requested asset id {0}", id);
101 return null;
102 }
103
104 try
105 {
106 return m_Database.GetAsset(assetID);
107 }
108 catch (Exception e)
109 {
110 m_log.ErrorFormat("[XASSET SERVICE]: Exception getting asset {0} {1}", assetID, e);
111 return null;
112 }
113 }
114
115 public virtual AssetBase GetCached(string id)
116 {
117 return Get(id);
118 }
119
120 public virtual AssetMetadata GetMetadata(string id)
121 {
122// m_log.DebugFormat("[XASSET SERVICE]: Get asset metadata for {0}", id);
123
124 UUID assetID;
125
126 if (!UUID.TryParse(id, out assetID))
127 return null;
128
129 AssetBase asset = m_Database.GetAsset(assetID);
130 if (asset != null)
131 return asset.Metadata;
132
133 return null;
134 }
135
136 public virtual byte[] GetData(string id)
137 {
138// m_log.DebugFormat("[XASSET SERVICE]: Get asset data for {0}", id);
139
140 UUID assetID;
141
142 if (!UUID.TryParse(id, out assetID))
143 return null;
144
145 AssetBase asset = m_Database.GetAsset(assetID);
146 return asset.Data;
147 }
148
149 public virtual bool Get(string id, Object sender, AssetRetrieved handler)
150 {
151 //m_log.DebugFormat("[XASSET SERVICE]: Get asset async {0}", id);
152
153 UUID assetID;
154
155 if (!UUID.TryParse(id, out assetID))
156 return false;
157
158 AssetBase asset = m_Database.GetAsset(assetID);
159
160 //m_log.DebugFormat("[XASSET SERVICE]: Got asset {0}", asset);
161
162 handler(id, sender, asset);
163
164 return true;
165 }
166
167 public virtual string Store(AssetBase asset)
168 {
169 if (!m_Database.ExistsAsset(asset.FullID))
170 {
171// m_log.DebugFormat(
172// "[XASSET SERVICE]: Storing asset {0} {1}, bytes {2}", asset.Name, asset.FullID, asset.Data.Length);
173 m_Database.StoreAsset(asset);
174 }
175// else
176// {
177// m_log.DebugFormat(
178// "[XASSET SERVICE]: Not storing asset {0} {1}, bytes {2} as it already exists", asset.Name, asset.FullID, asset.Data.Length);
179// }
180
181 return asset.ID;
182 }
183
184 public bool UpdateContent(string id, byte[] data)
185 {
186 return false;
187 }
188
189 public virtual bool Delete(string id)
190 {
191 m_log.DebugFormat("[XASSET SERVICE]: Deleting asset {0}", id);
192 UUID assetID;
193 if (!UUID.TryParse(id, out assetID))
194 return false;
195
196 AssetBase asset = m_Database.GetAsset(assetID);
197 if (asset == null)
198 return false;
199
200 if ((int)(asset.Flags & AssetFlags.Maptile) != 0)
201 {
202 return m_Database.Delete(id);
203 }
204 else
205 {
206 m_log.DebugFormat("[XASSET SERVICE]: Request to delete asset {0}, but flags are not Maptile", id);
207 }
208
209 return false;
210 }
211 }
212}
213
diff --git a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
index bb5d51f..c395178 100644
--- a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs
@@ -45,6 +45,24 @@ namespace OpenSim.Services.Connectors
45 LogManager.GetLogger( 45 LogManager.GetLogger(
46 MethodBase.GetCurrentMethod().DeclaringType); 46 MethodBase.GetCurrentMethod().DeclaringType);
47 47
48 private Dictionary<IAssetService, object> m_endpointSerializer = new Dictionary<IAssetService, object>();
49 private object EndPointLock(IAssetService connector)
50 {
51 lock (m_endpointSerializer)
52 {
53 object eplock = null;
54
55 if (! m_endpointSerializer.TryGetValue(connector, out eplock))
56 {
57 eplock = new object();
58 m_endpointSerializer.Add(connector, eplock);
59 // m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint);
60 }
61
62 return eplock;
63 }
64 }
65
48 private Dictionary<string, IAssetService> m_connectors = new Dictionary<string, IAssetService>(); 66 private Dictionary<string, IAssetService> m_connectors = new Dictionary<string, IAssetService>();
49 67
50 public HGAssetServiceConnector(IConfigSource source) 68 public HGAssetServiceConnector(IConfigSource source)
@@ -197,7 +215,8 @@ namespace OpenSim.Services.Connectors
197 IAssetService connector = GetConnector(url); 215 IAssetService connector = GetConnector(url);
198 // Restore the assetID to a simple UUID 216 // Restore the assetID to a simple UUID
199 asset.ID = assetID; 217 asset.ID = assetID;
200 return connector.Store(asset); 218 lock (EndPointLock(connector))
219 return connector.Store(asset);
201 } 220 }
202 221
203 return String.Empty; 222 return String.Empty;
diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs
index 89f0716..3dc87bc 100644
--- a/OpenSim/Services/GridService/GridService.cs
+++ b/OpenSim/Services/GridService/GridService.cs
@@ -84,14 +84,14 @@ namespace OpenSim.Services.GridService
84 84
85 if (MainConsole.Instance != null) 85 if (MainConsole.Instance != null)
86 { 86 {
87 MainConsole.Instance.Commands.AddCommand("grid", true, 87 MainConsole.Instance.Commands.AddCommand("Regions", true,
88 "show region", 88 "show region",
89 "show region <Region name>", 89 "show region <Region name>",
90 "Show details on a region", 90 "Show details on a region",
91 String.Empty, 91 String.Empty,
92 HandleShowRegion); 92 HandleShowRegion);
93 93
94 MainConsole.Instance.Commands.AddCommand("grid", true, 94 MainConsole.Instance.Commands.AddCommand("Regions", true,
95 "set region flags", 95 "set region flags",
96 "set region flags <Region name> <flags>", 96 "set region flags <Region name> <flags>",
97 "Set database flags for region", 97 "Set database flags for region",
diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs
index 0a59f86..4e38687 100644
--- a/OpenSim/Services/HypergridService/GatekeeperService.cs
+++ b/OpenSim/Services/HypergridService/GatekeeperService.cs
@@ -296,9 +296,10 @@ namespace OpenSim.Services.HypergridService
296 aCircuit.firstname = account.FirstName; 296 aCircuit.firstname = account.FirstName;
297 aCircuit.lastname = account.LastName; 297 aCircuit.lastname = account.LastName;
298 } 298 }
299 if (account == null && !aCircuit.lastname.StartsWith("@")) 299 if (account == null)
300 { 300 {
301 aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname; 301 if (!aCircuit.lastname.StartsWith("@"))
302 aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname;
302 try 303 try
303 { 304 {
304 Uri uri = new Uri(aCircuit.ServiceURLs["HomeURI"].ToString()); 305 Uri uri = new Uri(aCircuit.ServiceURLs["HomeURI"].ToString());
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index de05f28..079bcb1 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -173,6 +173,12 @@ namespace OpenSim.Services.LLLoginService
173 // Web map 173 // Web map
174 private string mapTileURL; 174 private string mapTileURL;
175 175
176 // Web Profiles
177 private string profileURL;
178
179 // OpenID
180 private string openIDURL;
181
176 private string searchURL; 182 private string searchURL;
177 183
178 // Error Flags 184 // Error Flags
@@ -225,7 +231,7 @@ namespace OpenSim.Services.LLLoginService
225 public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, 231 public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo,
226 GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService, 232 GridRegion destination, List<InventoryFolderBase> invSkel, FriendInfo[] friendsList, ILibraryService libService,
227 string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message, 233 string where, string startlocation, Vector3 position, Vector3 lookAt, List<InventoryItemBase> gestures, string message,
228 GridRegion home, IPEndPoint clientIP, string mapTileURL, string searchURL, string currency) 234 GridRegion home, IPEndPoint clientIP, string mapTileURL, string profileURL, string openIDURL, string searchURL, string currency)
229 : this() 235 : this()
230 { 236 {
231 FillOutInventoryData(invSkel, libService); 237 FillOutInventoryData(invSkel, libService);
@@ -242,6 +248,9 @@ namespace OpenSim.Services.LLLoginService
242 BuddList = ConvertFriendListItem(friendsList); 248 BuddList = ConvertFriendListItem(friendsList);
243 StartLocation = where; 249 StartLocation = where;
244 MapTileURL = mapTileURL; 250 MapTileURL = mapTileURL;
251 ProfileURL = profileURL;
252 OpenIDURL = openIDURL;
253
245 SearchURL = searchURL; 254 SearchURL = searchURL;
246 Currency = currency; 255 Currency = currency;
247 256
@@ -390,6 +399,8 @@ namespace OpenSim.Services.LLLoginService
390 InitialOutfitHash["gender"] = "female"; 399 InitialOutfitHash["gender"] = "female";
391 initialOutfit.Add(InitialOutfitHash); 400 initialOutfit.Add(InitialOutfitHash);
392 mapTileURL = String.Empty; 401 mapTileURL = String.Empty;
402 profileURL = String.Empty;
403 openIDURL = String.Empty;
393 searchURL = String.Empty; 404 searchURL = String.Empty;
394 405
395 currency = String.Empty; 406 currency = String.Empty;
@@ -462,6 +473,13 @@ namespace OpenSim.Services.LLLoginService
462 if (mapTileURL != String.Empty) 473 if (mapTileURL != String.Empty)
463 responseData["map-server-url"] = mapTileURL; 474 responseData["map-server-url"] = mapTileURL;
464 475
476 if (profileURL != String.Empty)
477 responseData["profile-server-url"] = profileURL;
478
479 // We need to send an openid_token back in the response too
480 if (openIDURL != String.Empty)
481 responseData["openid_url"] = openIDURL;
482
465 if (m_buddyList != null) 483 if (m_buddyList != null)
466 { 484 {
467 responseData["buddy-list"] = m_buddyList.ToArray(); 485 responseData["buddy-list"] = m_buddyList.ToArray();
@@ -567,6 +585,12 @@ namespace OpenSim.Services.LLLoginService
567 if (mapTileURL != String.Empty) 585 if (mapTileURL != String.Empty)
568 map["map-server-url"] = OSD.FromString(mapTileURL); 586 map["map-server-url"] = OSD.FromString(mapTileURL);
569 587
588 if (profileURL != String.Empty)
589 map["profile-server-url"] = OSD.FromString(profileURL);
590
591 if (openIDURL != String.Empty)
592 map["openid_url"] = OSD.FromString(openIDURL);
593
570 if (searchURL != String.Empty) 594 if (searchURL != String.Empty)
571 map["search"] = OSD.FromString(searchURL); 595 map["search"] = OSD.FromString(searchURL);
572 596
@@ -939,6 +963,18 @@ namespace OpenSim.Services.LLLoginService
939 set { mapTileURL = value; } 963 set { mapTileURL = value; }
940 } 964 }
941 965
966 public string ProfileURL
967 {
968 get { return profileURL; }
969 set { profileURL = value; }
970 }
971
972 public string OpenIDURL
973 {
974 get { return openIDURL; }
975 set { openIDURL = value; }
976 }
977
942 public string SearchURL 978 public string SearchURL
943 { 979 {
944 get { return searchURL; } 980 get { return searchURL; }
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index 6a9b8c6..891c452 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -74,6 +74,8 @@ namespace OpenSim.Services.LLLoginService
74 protected string m_GatekeeperURL; 74 protected string m_GatekeeperURL;
75 protected bool m_AllowRemoteSetLoginLevel; 75 protected bool m_AllowRemoteSetLoginLevel;
76 protected string m_MapTileURL; 76 protected string m_MapTileURL;
77 protected string m_ProfileURL;
78 protected string m_OpenIDURL;
77 protected string m_SearchURL; 79 protected string m_SearchURL;
78 protected string m_Currency; 80 protected string m_Currency;
79 81
@@ -108,6 +110,8 @@ namespace OpenSim.Services.LLLoginService
108 m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0); 110 m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0);
109 m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); 111 m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty);
110 m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty); 112 m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty);
113 m_ProfileURL = m_LoginServerConfig.GetString("ProfileServerURL", string.Empty);
114 m_OpenIDURL = m_LoginServerConfig.GetString("OpenIDServerURL", String.Empty);
111 m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty); 115 m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty);
112 m_Currency = m_LoginServerConfig.GetString("Currency", string.Empty); 116 m_Currency = m_LoginServerConfig.GetString("Currency", string.Empty);
113 117
@@ -420,7 +424,7 @@ namespace OpenSim.Services.LLLoginService
420 // Finally, fill out the response and return it 424 // Finally, fill out the response and return it
421 // 425 //
422 LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, 426 LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService,
423 where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_SearchURL, m_Currency); 427 where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_ProfileURL, m_OpenIDURL, m_SearchURL, m_Currency);
424 428
425 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client."); 429 m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client.");
426 return response; 430 return response;
@@ -896,16 +900,16 @@ namespace OpenSim.Services.LLLoginService
896 private void RegisterCommands() 900 private void RegisterCommands()
897 { 901 {
898 //MainConsole.Instance.Commands.AddCommand 902 //MainConsole.Instance.Commands.AddCommand
899 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login level", 903 MainConsole.Instance.Commands.AddCommand("Users", false, "login level",
900 "login level <level>", 904 "login level <level>",
901 "Set the minimum user level to log in", HandleLoginCommand); 905 "Set the minimum user level to log in", HandleLoginCommand);
902 906
903 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login reset", 907 MainConsole.Instance.Commands.AddCommand("Users", false, "login reset",
904 "login reset", 908 "login reset",
905 "Reset the login level to allow all users", 909 "Reset the login level to allow all users",
906 HandleLoginCommand); 910 HandleLoginCommand);
907 911
908 MainConsole.Instance.Commands.AddCommand("loginservice", false, "login text", 912 MainConsole.Instance.Commands.AddCommand("Users", false, "login text",
909 "login text <text>", 913 "login text <text>",
910 "Set the text users will see on login", HandleLoginCommand); 914 "Set the text users will see on login", HandleLoginCommand);
911 915
diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs
index ad06300..9d0aeef 100644
--- a/OpenSim/Services/UserAccountService/UserAccountService.cs
+++ b/OpenSim/Services/UserAccountService/UserAccountService.cs
@@ -89,17 +89,17 @@ namespace OpenSim.Services.UserAccountService
89 if (m_RootInstance == null && MainConsole.Instance != null) 89 if (m_RootInstance == null && MainConsole.Instance != null)
90 { 90 {
91 m_RootInstance = this; 91 m_RootInstance = this;
92 MainConsole.Instance.Commands.AddCommand("UserService", false, 92 MainConsole.Instance.Commands.AddCommand("Users", false,
93 "create user", 93 "create user",
94 "create user [<first> [<last> [<pass> [<email> [<user id>]]]]]", 94 "create user [<first> [<last> [<pass> [<email> [<user id>]]]]]",
95 "Create a new user", HandleCreateUser); 95 "Create a new user", HandleCreateUser);
96 96
97 MainConsole.Instance.Commands.AddCommand("UserService", false, 97 MainConsole.Instance.Commands.AddCommand("Users", false,
98 "reset user password", 98 "reset user password",
99 "reset user password [<first> [<last> [<password>]]]", 99 "reset user password [<first> [<last> [<password>]]]",
100 "Reset a user password", HandleResetUserPassword); 100 "Reset a user password", HandleResetUserPassword);
101 101
102 MainConsole.Instance.Commands.AddCommand("UserService", false, 102 MainConsole.Instance.Commands.AddCommand("Users", false,
103 "set user level", 103 "set user level",
104 "set user level [<first> [<last> [<level>]]]", 104 "set user level [<first> [<last> [<level>]]]",
105 "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, " 105 "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, "
@@ -107,7 +107,7 @@ namespace OpenSim.Services.UserAccountService
107 + "It will also affect the 'login level' command. ", 107 + "It will also affect the 'login level' command. ",
108 HandleSetUserLevel); 108 HandleSetUserLevel);
109 109
110 MainConsole.Instance.Commands.AddCommand("UserService", false, 110 MainConsole.Instance.Commands.AddCommand("Users", false,
111 "show account", 111 "show account",
112 "show account <first> <last>", 112 "show account <first> <last>",
113 "Show account details for the given user", HandleShowAccount); 113 "Show account details for the given user", HandleShowAccount);