aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services')
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs5
-rw-r--r--OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs120
-rw-r--r--OpenSim/Services/Connectors/Land/LandServiceConnector.cs2
-rw-r--r--OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs11
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs4
-rw-r--r--OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs18
-rw-r--r--OpenSim/Services/Interfaces/IAttachmentsService.cs17
-rw-r--r--OpenSim/Services/Interfaces/IGridService.cs14
-rw-r--r--OpenSim/Services/Interfaces/ISimulationService.cs8
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs6
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginService.cs6
11 files changed, 187 insertions, 24 deletions
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index 470a4dd..3122382 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -144,7 +144,10 @@ namespace OpenSim.Services.AssetService
144 public string Store(AssetBase asset) 144 public string Store(AssetBase asset)
145 { 145 {
146 //m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID); 146 //m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID);
147 m_Database.StoreAsset(asset); 147 if (!m_Database.StoreAsset(asset))
148 {
149 return UUID.Zero.ToString();
150 }
148 151
149 return asset.ID; 152 return asset.ID;
150 } 153 }
diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
index 65b3537..ad18a23 100644
--- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs
@@ -30,6 +30,7 @@ using System;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.IO; 31using System.IO;
32using System.Reflection; 32using System.Reflection;
33using System.Timers;
33using Nini.Config; 34using Nini.Config;
34using OpenSim.Framework; 35using OpenSim.Framework;
35using OpenSim.Framework.Console; 36using OpenSim.Framework.Console;
@@ -48,7 +49,9 @@ namespace OpenSim.Services.Connectors
48 49
49 private string m_ServerURI = String.Empty; 50 private string m_ServerURI = String.Empty;
50 private IImprovedAssetCache m_Cache = null; 51 private IImprovedAssetCache m_Cache = null;
51 52 private int m_retryCounter;
53 private Dictionary<int, List<AssetBase>> m_retryQueue = new Dictionary<int, List<AssetBase>>();
54 private Timer m_retryTimer;
52 public AssetServicesConnector() 55 public AssetServicesConnector()
53 { 56 {
54 } 57 }
@@ -85,6 +88,55 @@ namespace OpenSim.Services.Connectors
85 MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset", 88 MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset",
86 "dump asset <id> <file>", 89 "dump asset <id> <file>",
87 "dump one cached asset", HandleDumpAsset); 90 "dump one cached asset", HandleDumpAsset);
91
92 m_retryTimer = new Timer();
93 m_retryTimer.Elapsed += new ElapsedEventHandler(retryCheck);
94 m_retryTimer.Interval = 60000;
95 }
96
97 protected void retryCheck(object source, ElapsedEventArgs e)
98 {
99 m_retryCounter++;
100 if (m_retryCounter > 60) m_retryCounter -= 60;
101 List<int> keys = new List<int>();
102 foreach (int a in m_retryQueue.Keys)
103 {
104 keys.Add(a);
105 }
106 foreach (int a in keys)
107 {
108 //We exponentially fall back on frequency until we reach one attempt per hour
109 //The net result is that we end up in the queue for roughly 24 hours..
110 //24 hours worth of assets could be a lot, so the hope is that the region admin
111 //will have gotten the asset connector back online quickly!
112
113 int timefactor = a ^ 2;
114 if (timefactor > 60)
115 {
116 timefactor = 60;
117 }
118
119 //First, find out if we care about this timefactor
120 if (timefactor % a == 0)
121 {
122 //Yes, we do!
123 List<AssetBase> retrylist = m_retryQueue[a];
124 m_retryQueue.Remove(a);
125
126 foreach(AssetBase ass in retrylist)
127 {
128 Store(ass); //Store my ass. This function will put it back in the dictionary if it fails
129 }
130 }
131 }
132
133 if (m_retryQueue.Count == 0)
134 {
135 //It might only be one tick per minute, but I have
136 //repented and abandoned my wasteful ways
137 m_retryCounter = 0;
138 m_retryTimer.Stop();
139 }
88 } 140 }
89 141
90 protected void SetCache(IImprovedAssetCache cache) 142 protected void SetCache(IImprovedAssetCache cache)
@@ -99,8 +151,8 @@ namespace OpenSim.Services.Connectors
99 AssetBase asset = null; 151 AssetBase asset = null;
100 if (m_Cache != null) 152 if (m_Cache != null)
101 asset = m_Cache.Get(id); 153 asset = m_Cache.Get(id);
102 154
103 if (asset == null) 155 if (asset == null || asset.Data == null || asset.Data.Length == 0)
104 { 156 {
105 asset = SynchronousRestObjectRequester. 157 asset = SynchronousRestObjectRequester.
106 MakeRequest<int, AssetBase>("GET", uri, 0); 158 MakeRequest<int, AssetBase>("GET", uri, 0);
@@ -177,7 +229,7 @@ namespace OpenSim.Services.Connectors
177 if (m_Cache != null) 229 if (m_Cache != null)
178 asset = m_Cache.Get(id); 230 asset = m_Cache.Get(id);
179 231
180 if (asset == null) 232 if (asset == null || asset.Data == null || asset.Data.Length == 0)
181 { 233 {
182 bool result = false; 234 bool result = false;
183 235
@@ -204,11 +256,10 @@ namespace OpenSim.Services.Connectors
204 256
205 public string Store(AssetBase asset) 257 public string Store(AssetBase asset)
206 { 258 {
259 if (m_Cache != null)
260 m_Cache.Cache(asset);
207 if (asset.Temporary || asset.Local) 261 if (asset.Temporary || asset.Local)
208 { 262 {
209 if (m_Cache != null)
210 m_Cache.Cache(asset);
211
212 return asset.ID; 263 return asset.ID;
213 } 264 }
214 265
@@ -218,24 +269,57 @@ namespace OpenSim.Services.Connectors
218 try 269 try
219 { 270 {
220 newID = SynchronousRestObjectRequester. 271 newID = SynchronousRestObjectRequester.
221 MakeRequest<AssetBase, string>("POST", uri, asset); 272 MakeRequest<AssetBase, string>("POST", uri, asset, 25);
273 if (newID == null || newID == "")
274 {
275 newID = UUID.Zero.ToString();
276 }
222 } 277 }
223 catch (Exception e) 278 catch (Exception e)
224 { 279 {
225 m_log.WarnFormat("[ASSET CONNECTOR]: Unable to send asset {0} to asset server. Reason: {1}", asset.ID, e.Message); 280 newID = UUID.Zero.ToString();
226 } 281 }
227 282
228 if (newID != String.Empty) 283 if (newID == UUID.Zero.ToString())
229 { 284 {
230 // Placing this here, so that this work with old asset servers that don't send any reply back 285 //The asset upload failed, put it in a queue for later
231 // SynchronousRestObjectRequester returns somethins that is not an empty string 286 asset.UploadAttempts++;
232 if (newID != null) 287 if (asset.UploadAttempts > 30)
233 asset.ID = newID; 288 {
234 289 //By this stage we've been in the queue for a good few hours;
235 if (m_Cache != null) 290 //We're going to drop the asset.
236 m_Cache.Cache(asset); 291 m_log.ErrorFormat("[Assets] Dropping asset {0} - Upload has been in the queue for too long.", asset.ID.ToString());
292 }
293 else
294 {
295 if (!m_retryQueue.ContainsKey(asset.UploadAttempts))
296 {
297 m_retryQueue.Add(asset.UploadAttempts, new List<AssetBase>());
298 }
299 List<AssetBase> m_queue = m_retryQueue[asset.UploadAttempts];
300 m_queue.Add(asset);
301 m_log.WarnFormat("[Assets] Upload failed: {0} - Requeuing asset for another run.", asset.ID.ToString());
302 m_retryTimer.Start();
303 }
304 }
305 else
306 {
307 if (asset.UploadAttempts > 0)
308 {
309 m_log.InfoFormat("[Assets] Upload of {0} succeeded after {1} failed attempts", asset.ID.ToString(), asset.UploadAttempts.ToString());
310 }
311 if (newID != String.Empty)
312 {
313 // Placing this here, so that this work with old asset servers that don't send any reply back
314 // SynchronousRestObjectRequester returns somethins that is not an empty string
315 if (newID != null)
316 asset.ID = newID;
317
318 if (m_Cache != null)
319 m_Cache.Cache(asset);
320 }
237 } 321 }
238 return newID; 322 return asset.ID;
239 } 323 }
240 324
241 public bool UpdateContent(string id, byte[] data) 325 public bool UpdateContent(string id, byte[] data)
diff --git a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs
index 4b25ac8..10499e2 100644
--- a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs
@@ -131,4 +131,4 @@ namespace OpenSim.Services.Connectors
131 return landData; 131 return landData;
132 } 132 }
133 } 133 }
134} \ No newline at end of file 134}
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
index 41ebeaf..f1c99ce 100644
--- a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
@@ -300,6 +300,17 @@ namespace OpenSim.Services.Connectors
300 { 300 {
301 pinfo = new PresenceInfo((Dictionary<string, object>)replyData["result"]); 301 pinfo = new PresenceInfo((Dictionary<string, object>)replyData["result"]);
302 } 302 }
303 else
304 {
305 if (replyData["result"].ToString() == "null")
306 return null;
307
308 m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply (result not dictionary) received from presence server when querying for sessionID {0}", sessionID.ToString());
309 }
310 }
311 else
312 {
313 m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply received from presence server when querying for sessionID {0}", sessionID.ToString());
303 } 314 }
304 315
305 return pinfo; 316 return pinfo;
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
index 8076fab..f86eba3 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs
@@ -135,6 +135,8 @@ namespace OpenSim.Services.Connectors.SimianGrid
135 135
136 public string RegisterRegion(UUID scopeID, GridRegion regionInfo) 136 public string RegisterRegion(UUID scopeID, GridRegion regionInfo)
137 { 137 {
138 IPEndPoint ext = regionInfo.ExternalEndPoint;
139 if (ext == null) return "Region registration for " + regionInfo.RegionName + " failed: Could not resolve EndPoint";
138 // Generate and upload our map tile in PNG format to the SimianGrid AddMapTile service 140 // Generate and upload our map tile in PNG format to the SimianGrid AddMapTile service
139 Scene scene; 141 Scene scene;
140 if (m_scenes.TryGetValue(regionInfo.RegionID, out scene)) 142 if (m_scenes.TryGetValue(regionInfo.RegionID, out scene))
@@ -150,7 +152,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
150 { "ServerURI", OSD.FromString(regionInfo.ServerURI) }, 152 { "ServerURI", OSD.FromString(regionInfo.ServerURI) },
151 { "InternalAddress", OSD.FromString(regionInfo.InternalEndPoint.Address.ToString()) }, 153 { "InternalAddress", OSD.FromString(regionInfo.InternalEndPoint.Address.ToString()) },
152 { "InternalPort", OSD.FromInteger(regionInfo.InternalEndPoint.Port) }, 154 { "InternalPort", OSD.FromInteger(regionInfo.InternalEndPoint.Port) },
153 { "ExternalAddress", OSD.FromString(regionInfo.ExternalEndPoint.Address.ToString()) }, 155 { "ExternalAddress", OSD.FromString(ext.Address.ToString()) },
154 { "ExternalPort", OSD.FromInteger(regionInfo.ExternalEndPoint.Port) }, 156 { "ExternalPort", OSD.FromInteger(regionInfo.ExternalEndPoint.Port) },
155 { "MapTexture", OSD.FromUUID(regionInfo.TerrainImage) }, 157 { "MapTexture", OSD.FromUUID(regionInfo.TerrainImage) },
156 { "Access", OSD.FromInteger(regionInfo.Access) }, 158 { "Access", OSD.FromInteger(regionInfo.Access) },
diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
index c4284eb..f855fde 100644
--- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs
@@ -354,7 +354,9 @@ namespace OpenSim.Services.Connectors.Simulation
354 354
355 public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) 355 public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent)
356 { 356 {
357 IPEndPoint ext = destination.ExternalEndPoint;
357 agent = null; 358 agent = null;
359 if (ext == null) return false;
358 // Eventually, we want to use a caps url instead of the agentID 360 // Eventually, we want to use a caps url instead of the agentID
359 string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; 361 string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/";
360 362
@@ -444,13 +446,15 @@ namespace OpenSim.Services.Connectors.Simulation
444 return true; 446 return true;
445 } 447 }
446 448
447 public bool CloseAgent(GridRegion destination, UUID id) 449 private bool CloseAgent(GridRegion destination, UUID id, bool ChildOnly)
448 { 450 {
449 string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; 451 string uri = destination.ServerURI + AgentPath() + id + "/" + destination.RegionID.ToString() + "/";
450 452
451 453
452 WebRequest request = WebRequest.Create(uri); 454 WebRequest request = WebRequest.Create(uri);
453 request.Method = "DELETE"; 455 request.Method = "DELETE";
456 if (ChildOnly)
457 request.Method += "CHILD";
454 request.Timeout = 10000; 458 request.Timeout = 10000;
455 459
456 StreamReader sr = null; 460 StreamReader sr = null;
@@ -483,6 +487,16 @@ namespace OpenSim.Services.Connectors.Simulation
483 return true; 487 return true;
484 } 488 }
485 489
490 public bool CloseChildAgent(GridRegion destination, UUID id)
491 {
492 return CloseAgent(destination, id, true);
493 }
494
495 public bool CloseAgent(GridRegion destination, UUID id)
496 {
497 return CloseAgent(destination, id, false);
498 }
499
486 #endregion Agents 500 #endregion Agents
487 501
488 #region Objects 502 #region Objects
@@ -494,6 +508,8 @@ namespace OpenSim.Services.Connectors.Simulation
494 508
495 public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall) 509 public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall)
496 { 510 {
511 IPEndPoint ext = destination.ExternalEndPoint;
512 if (ext == null) return false;
497 string uri 513 string uri
498 = destination.ServerURI + ObjectPath() + sog.UUID + "/"; 514 = destination.ServerURI + ObjectPath() + sog.UUID + "/";
499 //m_log.Debug(" >>> DoCreateObjectCall <<< " + uri); 515 //m_log.Debug(" >>> DoCreateObjectCall <<< " + uri);
diff --git a/OpenSim/Services/Interfaces/IAttachmentsService.cs b/OpenSim/Services/Interfaces/IAttachmentsService.cs
new file mode 100644
index 0000000..bdde369
--- /dev/null
+++ b/OpenSim/Services/Interfaces/IAttachmentsService.cs
@@ -0,0 +1,17 @@
1////////////////////////////////////////////////////////////////
2//
3// (c) 2009, 2010 Careminster Limited and Melanie Thielker
4//
5// All rights reserved
6//
7using System;
8using Nini.Config;
9
10namespace OpenSim.Services.Interfaces
11{
12 public interface IAttachmentsService
13 {
14 string Get(string id);
15 void Store(string id, string data);
16 }
17}
diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs
index 6d3bff7..a0d270c 100644
--- a/OpenSim/Services/Interfaces/IGridService.cs
+++ b/OpenSim/Services/Interfaces/IGridService.cs
@@ -273,9 +273,13 @@ namespace OpenSim.Services.Interfaces
273 } 273 }
274 catch (SocketException e) 274 catch (SocketException e)
275 { 275 {
276 throw new Exception( 276 /*throw new Exception(
277 "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" + 277 "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" +
278 e + "' attached to this exception", e); 278 e + "' attached to this exception", e);*/
279 // Don't throw a fatal exception here, instead, return Null and handle it in the caller.
280 // Reason is, on systems such as OSgrid it has occured that known hostnames stop
281 // resolving and thus make surrounding regions crash out with this exception.
282 return null;
279 } 283 }
280 284
281 return new IPEndPoint(ia, m_internalEndPoint.Port); 285 return new IPEndPoint(ia, m_internalEndPoint.Port);
@@ -333,6 +337,12 @@ namespace OpenSim.Services.Interfaces
333 if (kvp.ContainsKey("regionName")) 337 if (kvp.ContainsKey("regionName"))
334 RegionName = (string)kvp["regionName"]; 338 RegionName = (string)kvp["regionName"];
335 339
340 if (kvp.ContainsKey("access"))
341 {
342 byte access = Convert.ToByte((string)kvp["access"]);
343 Maturity = (int)Util.ConvertAccessLevelToMaturity(access);
344 }
345
336 if (kvp.ContainsKey("serverIP")) 346 if (kvp.ContainsKey("serverIP"))
337 { 347 {
338 //int port = 0; 348 //int port = 0;
diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs
index 67d7cbe..33d6fde 100644
--- a/OpenSim/Services/Interfaces/ISimulationService.cs
+++ b/OpenSim/Services/Interfaces/ISimulationService.cs
@@ -71,6 +71,14 @@ namespace OpenSim.Services.Interfaces
71 bool ReleaseAgent(UUID originRegion, UUID id, string uri); 71 bool ReleaseAgent(UUID originRegion, UUID id, string uri);
72 72
73 /// <summary> 73 /// <summary>
74 /// Close child agent.
75 /// </summary>
76 /// <param name="regionHandle"></param>
77 /// <param name="id"></param>
78 /// <returns></returns>
79 bool CloseChildAgent(GridRegion destination, UUID id);
80
81 /// <summary>
74 /// Close agent. 82 /// Close agent.
75 /// </summary> 83 /// </summary>
76 /// <param name="regionHandle"></param> 84 /// <param name="regionHandle"></param>
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index f985ab2..e98cc22 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -56,6 +56,7 @@ namespace OpenSim.Services.LLLoginService
56 public static LLFailedLoginResponse InventoryProblem; 56 public static LLFailedLoginResponse InventoryProblem;
57 public static LLFailedLoginResponse DeadRegionProblem; 57 public static LLFailedLoginResponse DeadRegionProblem;
58 public static LLFailedLoginResponse LoginBlockedProblem; 58 public static LLFailedLoginResponse LoginBlockedProblem;
59 public static LLFailedLoginResponse UnverifiedAccountProblem;
59 public static LLFailedLoginResponse AlreadyLoggedInProblem; 60 public static LLFailedLoginResponse AlreadyLoggedInProblem;
60 public static LLFailedLoginResponse InternalError; 61 public static LLFailedLoginResponse InternalError;
61 62
@@ -76,6 +77,10 @@ namespace OpenSim.Services.LLLoginService
76 LoginBlockedProblem = new LLFailedLoginResponse("presence", 77 LoginBlockedProblem = new LLFailedLoginResponse("presence",
77 "Logins are currently restricted. Please try again later.", 78 "Logins are currently restricted. Please try again later.",
78 "false"); 79 "false");
80 UnverifiedAccountProblem = new LLFailedLoginResponse("presence",
81 "Your account has not yet been verified. Please check " +
82 "your email and click the provided link.",
83 "false");
79 AlreadyLoggedInProblem = new LLFailedLoginResponse("presence", 84 AlreadyLoggedInProblem = new LLFailedLoginResponse("presence",
80 "You appear to be already logged in. " + 85 "You appear to be already logged in. " +
81 "If this is not the case please wait for your session to timeout. " + 86 "If this is not the case please wait for your session to timeout. " +
@@ -325,6 +330,7 @@ namespace OpenSim.Services.LLLoginService
325 private void FillOutRegionData(GridRegion destination) 330 private void FillOutRegionData(GridRegion destination)
326 { 331 {
327 IPEndPoint endPoint = destination.ExternalEndPoint; 332 IPEndPoint endPoint = destination.ExternalEndPoint;
333 if (endPoint == null) return;
328 SimAddress = endPoint.Address.ToString(); 334 SimAddress = endPoint.Address.ToString();
329 SimPort = (uint)endPoint.Port; 335 SimPort = (uint)endPoint.Port;
330 RegionX = (uint)destination.RegionLocX; 336 RegionX = (uint)destination.RegionLocX;
diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs
index 127c4b2..6c66414 100644
--- a/OpenSim/Services/LLLoginService/LLLoginService.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginService.cs
@@ -228,6 +228,12 @@ namespace OpenSim.Services.LLLoginService
228 return LLFailedLoginResponse.UserProblem; 228 return LLFailedLoginResponse.UserProblem;
229 } 229 }
230 230
231 if (account.UserLevel < 0)
232 {
233 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: Unverified account");
234 return LLFailedLoginResponse.UnverifiedAccountProblem;
235 }
236
231 if (account.UserLevel < m_MinLoginLevel) 237 if (account.UserLevel < m_MinLoginLevel)
232 { 238 {
233 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: login is blocked for user level {0}", account.UserLevel); 239 m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: login is blocked for user level {0}", account.UserLevel);