aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs4
-rw-r--r--OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs3
-rw-r--r--OpenSim/ApplicationPlugins/Rest/RestPlugin.cs2
-rw-r--r--OpenSim/Framework/Communications/IUserService.cs16
-rw-r--r--OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs5
-rw-r--r--OpenSim/Framework/Communications/UserManagerBase.cs32
-rw-r--r--OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs6
-rw-r--r--OpenSim/Grid/UserServer.Modules/UserManager.cs56
-rw-r--r--OpenSim/Region/Communications/Local/LocalUserServices.cs19
-rw-r--r--OpenSim/Region/Communications/OGS1/OGS1UserServices.cs33
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs42
11 files changed, 180 insertions, 38 deletions
diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs
index 13f6426..db62d52 100644
--- a/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestHandler.cs
@@ -207,7 +207,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
207 // This plugin will only be enabled if the broader 207 // This plugin will only be enabled if the broader
208 // REST plugin mechanism is enabled. 208 // REST plugin mechanism is enabled.
209 209
210 Rest.Log.InfoFormat("{0} Plugin is initializing", MsgId); 210 //Rest.Log.InfoFormat("{0} Plugin is initializing", MsgId);
211 211
212 base.Initialise(openSim); 212 base.Initialise(openSim);
213 213
@@ -216,7 +216,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Inventory
216 216
217 if (!IsEnabled) 217 if (!IsEnabled)
218 { 218 {
219 Rest.Log.WarnFormat("{0} Plugins are disabled", MsgId); 219 //Rest.Log.WarnFormat("{0} Plugins are disabled", MsgId);
220 return; 220 return;
221 } 221 }
222 222
diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs b/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs
index f790c5e..02ef588 100644
--- a/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs
+++ b/OpenSim/ApplicationPlugins/Rest/Regions/RestRegionPlugin.cs
@@ -68,9 +68,10 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions
68 base.Initialise(openSim); 68 base.Initialise(openSim);
69 if (!IsEnabled) 69 if (!IsEnabled)
70 { 70 {
71 m_log.WarnFormat("{0} Rest Plugins are disabled", MsgID); 71 //m_log.WarnFormat("{0} Rest Plugins are disabled", MsgID);
72 return; 72 return;
73 } 73 }
74
74 m_log.InfoFormat("{0} REST region plugin enabled", MsgID); 75 m_log.InfoFormat("{0} REST region plugin enabled", MsgID);
75 76
76 // add REST method handlers 77 // add REST method handlers
diff --git a/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs b/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
index fd23384..ff1502a 100644
--- a/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
+++ b/OpenSim/ApplicationPlugins/Rest/RestPlugin.cs
@@ -216,7 +216,7 @@ namespace OpenSim.ApplicationPlugins.Rest
216 216
217 if (!_config.GetBoolean("enabled", false)) 217 if (!_config.GetBoolean("enabled", false))
218 { 218 {
219 m_log.WarnFormat("{0} Rest Plugins are disabled", MsgID); 219 //m_log.WarnFormat("{0} Rest Plugins are disabled", MsgID);
220 return; 220 return;
221 } 221 }
222 222
diff --git a/OpenSim/Framework/Communications/IUserService.cs b/OpenSim/Framework/Communications/IUserService.cs
index 725225d..15c5a96 100644
--- a/OpenSim/Framework/Communications/IUserService.cs
+++ b/OpenSim/Framework/Communications/IUserService.cs
@@ -98,7 +98,7 @@ namespace OpenSim.Framework.Communications
98 /// <param name="friendlistowner">The agent that who's friends list is being updated</param> 98 /// <param name="friendlistowner">The agent that who's friends list is being updated</param>
99 /// <param name="friend">The agent that is getting or loosing permissions</param> 99 /// <param name="friend">The agent that is getting or loosing permissions</param>
100 /// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param> 100 /// <param name="perms">A uint bit vector for set perms that the friend being added has; 0 = none, 1=This friend can see when they sign on, 2 = map, 4 edit objects </param>
101 void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms); 101 void UpdateUserFriendPerms(UUID friendlistowner, UUID friend, uint perms);
102 102
103 /// <summary> 103 /// <summary>
104 /// Logs off a user on the user server 104 /// Logs off a user on the user server
@@ -137,9 +137,21 @@ namespace OpenSim.Framework.Communications
137 // But since Scenes only have IUserService references, I'm placing it here for now. 137 // But since Scenes only have IUserService references, I'm placing it here for now.
138 bool VerifySession(UUID userID, UUID sessionID); 138 bool VerifySession(UUID userID, UUID sessionID);
139 139
140 /// <summary>
141 /// Authenticate a user by their password.
142 /// </summary>
143 ///
144 /// This is used by callers outside the login process that want to
145 /// verify a user who has given their password.
146 ///
147 /// This should probably also be in IAuthentication but is here for the same reasons as VerifySession() is
148 ///
149 /// <param name="userID"></param>
150 /// <param name="password"></param>
151 /// <returns></returns>
152 bool AuthenticateUserByPassword(UUID userID, string password);
140 153
141 // Temporary Hack until we move everything to the new service model 154 // Temporary Hack until we move everything to the new service model
142 void SetInventoryService(IInventoryService invService); 155 void SetInventoryService(IInventoryService invService);
143
144 } 156 }
145} 157}
diff --git a/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs b/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs
index ac0dc6d..a757282 100644
--- a/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs
+++ b/OpenSim/Framework/Communications/Tests/Cache/AssetCacheTests.cs
@@ -149,6 +149,11 @@ namespace OpenSim.Framework.Communications.Tests
149 { 149 {
150 throw new NotImplementedException(); 150 throw new NotImplementedException();
151 } 151 }
152
153 public virtual bool AuthenticateUserByPassword(UUID userID, string password)
154 {
155 throw new NotImplementedException();
156 }
152 } 157 }
153 } 158 }
154} 159}
diff --git a/OpenSim/Framework/Communications/UserManagerBase.cs b/OpenSim/Framework/Communications/UserManagerBase.cs
index 58174a0..1abd733 100644
--- a/OpenSim/Framework/Communications/UserManagerBase.cs
+++ b/OpenSim/Framework/Communications/UserManagerBase.cs
@@ -44,7 +44,8 @@ namespace OpenSim.Framework.Communications
44 /// <summary> 44 /// <summary>
45 /// Base class for user management (create, read, etc) 45 /// Base class for user management (create, read, etc)
46 /// </summary> 46 /// </summary>
47 public abstract class UserManagerBase : IUserService, IUserAdminService, IAvatarService, IMessagingService, IAuthentication 47 public abstract class UserManagerBase
48 : IUserService, IUserAdminService, IAvatarService, IMessagingService, IAuthentication
48 { 49 {
49 private static readonly ILog m_log 50 private static readonly ILog m_log
50 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -93,9 +94,9 @@ namespace OpenSim.Framework.Communications
93 public void AddPlugin(string provider, string connect) 94 public void AddPlugin(string provider, string connect)
94 { 95 {
95 m_plugins.AddRange(DataPluginFactory.LoadDataPlugins<IUserDataPlugin>(provider, connect)); 96 m_plugins.AddRange(DataPluginFactory.LoadDataPlugins<IUserDataPlugin>(provider, connect));
96 } 97 }
97 98
98 #region UserProfile 99 #region UserProfile
99 100
100 public virtual void AddTemporaryUserProfile(UserProfileData userProfile) 101 public virtual void AddTemporaryUserProfile(UserProfileData userProfile)
101 { 102 {
@@ -891,7 +892,10 @@ namespace OpenSim.Framework.Communications
891 892
892 if (userProfile != null && userProfile.CurrentAgent != null) 893 if (userProfile != null && userProfile.CurrentAgent != null)
893 { 894 {
894 m_log.DebugFormat("[USER AUTH]: Verifying session {0} for {1}; current session {2}", sessionID, userID, userProfile.CurrentAgent.SessionID); 895 m_log.DebugFormat(
896 "[USER AUTH]: Verifying session {0} for {1}; current session {2}",
897 sessionID, userID, userProfile.CurrentAgent.SessionID);
898
895 if (userProfile.CurrentAgent.SessionID == sessionID) 899 if (userProfile.CurrentAgent.SessionID == sessionID)
896 { 900 {
897 return true; 901 return true;
@@ -901,6 +905,26 @@ namespace OpenSim.Framework.Communications
901 return false; 905 return false;
902 } 906 }
903 907
908 public virtual bool AuthenticateUserByPassword(UUID userID, string password)
909 {
910// m_log.DebugFormat("[USER AUTH]: Authenticating user {0} given password {1}", userID, password);
911
912 UserProfileData userProfile = GetUserProfile(userID);
913
914 if (null == userProfile)
915 return false;
916
917 string md5PasswordHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + userProfile.PasswordSalt);
918
919// m_log.DebugFormat(
920// "[USER AUTH]: Submitted hash {0}, stored hash {1}", md5PasswordHash, userProfile.PasswordHash);
921
922 if (md5PasswordHash == userProfile.PasswordHash)
923 return true;
924 else
925 return false;
926 }
927
904 #endregion 928 #endregion
905 } 929 }
906} 930}
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index db87958..01990fa 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -736,8 +736,11 @@ namespace OpenSim.Framework.Servers.HttpServer
736 else 736 else
737 { 737 {
738 xmlRpcResponse = new XmlRpcResponse(); 738 xmlRpcResponse = new XmlRpcResponse();
739
739 // Code set in accordance with http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php 740 // Code set in accordance with http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
740 xmlRpcResponse.SetFault(-32601, String.Format("Requested method [{0}] not found", methodName)); 741 xmlRpcResponse.SetFault(
742 XmlRpcErrorCodes.SERVER_ERROR_METHOD,
743 String.Format("Requested method [{0}] not found", methodName));
741 } 744 }
742 745
743 responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse); 746 responseString = XmlRpcResponseSerializer.Singleton.Serialize(xmlRpcResponse);
@@ -757,6 +760,7 @@ namespace OpenSim.Framework.Servers.HttpServer
757 response.SendChunked = false; 760 response.SendChunked = false;
758 response.ContentLength64 = buf.Length; 761 response.ContentLength64 = buf.Length;
759 response.ContentEncoding = Encoding.UTF8; 762 response.ContentEncoding = Encoding.UTF8;
763
760 try 764 try
761 { 765 {
762 response.OutputStream.Write(buf, 0, buf.Length); 766 response.OutputStream.Write(buf, 0, buf.Length);
diff --git a/OpenSim/Grid/UserServer.Modules/UserManager.cs b/OpenSim/Grid/UserServer.Modules/UserManager.cs
index 002f232..efbf45e 100644
--- a/OpenSim/Grid/UserServer.Modules/UserManager.cs
+++ b/OpenSim/Grid/UserServer.Modules/UserManager.cs
@@ -108,6 +108,9 @@ namespace OpenSim.Grid.UserServer.Modules
108 m_httpServer.AddXmlRPCHandler("get_user_by_uuid", XmlRPCGetUserMethodUUID); 108 m_httpServer.AddXmlRPCHandler("get_user_by_uuid", XmlRPCGetUserMethodUUID);
109 m_httpServer.AddXmlRPCHandler("get_avatar_picker_avatar", XmlRPCGetAvatarPickerAvatar); 109 m_httpServer.AddXmlRPCHandler("get_avatar_picker_avatar", XmlRPCGetAvatarPickerAvatar);
110 110
111 // Used by IAR module to do password checks
112 m_httpServer.AddXmlRPCHandler("authenticate_user_by_password", XmlRPCAuthenticateUserMethodPassword);
113
111 m_httpServer.AddXmlRPCHandler("update_user_current_region", XmlRPCAtRegion); 114 m_httpServer.AddXmlRPCHandler("update_user_current_region", XmlRPCAtRegion);
112 m_httpServer.AddXmlRPCHandler("logout_of_simulator", XmlRPCLogOffUserMethodUUID); 115 m_httpServer.AddXmlRPCHandler("logout_of_simulator", XmlRPCLogOffUserMethodUUID);
113 m_httpServer.AddXmlRPCHandler("get_agent_by_uuid", XmlRPCGetAgentMethodUUID); 116 m_httpServer.AddXmlRPCHandler("get_agent_by_uuid", XmlRPCGetAgentMethodUUID);
@@ -203,6 +206,57 @@ namespace OpenSim.Grid.UserServer.Modules
203 206
204 #region XMLRPC User Methods 207 #region XMLRPC User Methods
205 208
209 /// <summary>
210 /// Authenticate a user using their password
211 /// </summary>
212 /// <param name="request">Must contain values for "user_uuid" and "password" keys</param>
213 /// <param name="remoteClient"></param>
214 /// <returns></returns>
215 public XmlRpcResponse XmlRPCAuthenticateUserMethodPassword(XmlRpcRequest request, IPEndPoint remoteClient)
216 {
217// m_log.DebugFormat("[USER MANAGER]: Received authenticated user by password request from {0}", remoteClient);
218
219 Hashtable requestData = (Hashtable)request.Params[0];
220 string userUuidRaw = (string)requestData["user_uuid"];
221 string password = (string)requestData["password"];
222
223 if (null == userUuidRaw)
224 return Util.CreateUnknownUserErrorResponse();
225
226 UUID userUuid;
227 if (!UUID.TryParse(userUuidRaw, out userUuid))
228 return Util.CreateUnknownUserErrorResponse();
229
230 UserProfileData userProfile = m_userDataBaseService.GetUserProfile(userUuid);
231 if (null == userProfile)
232 return Util.CreateUnknownUserErrorResponse();
233
234 string authed;
235
236 if (null == password)
237 {
238 authed = "FALSE";
239 }
240 else
241 {
242 if (m_userDataBaseService.AuthenticateUserByPassword(userUuid, password))
243 authed = "TRUE";
244 else
245 authed = "FALSE";
246 }
247
248// m_log.DebugFormat(
249// "[USER MANAGER]: Authentication by password result from {0} for {1} is {2}",
250// remoteClient, userUuid, authed);
251
252 XmlRpcResponse response = new XmlRpcResponse();
253 Hashtable responseData = new Hashtable();
254 responseData["auth_user"] = authed;
255 response.Value = responseData;
256
257 return response;
258 }
259
206 public XmlRpcResponse XmlRPCGetAvatarPickerAvatar(XmlRpcRequest request, IPEndPoint remoteClient) 260 public XmlRpcResponse XmlRPCGetAvatarPickerAvatar(XmlRpcRequest request, IPEndPoint remoteClient)
207 { 261 {
208 // XmlRpcResponse response = new XmlRpcResponse(); 262 // XmlRpcResponse response = new XmlRpcResponse();
@@ -246,10 +300,10 @@ namespace OpenSim.Grid.UserServer.Modules
246 m_userDataBaseService.CommitAgent(ref userProfile); 300 m_userDataBaseService.CommitAgent(ref userProfile);
247 //setUserProfile(userProfile); 301 //setUserProfile(userProfile);
248 302
249
250 returnstring = "TRUE"; 303 returnstring = "TRUE";
251 } 304 }
252 } 305 }
306
253 responseData.Add("returnString", returnstring); 307 responseData.Add("returnString", returnstring);
254 response.Value = responseData; 308 response.Value = responseData;
255 return response; 309 return response;
diff --git a/OpenSim/Region/Communications/Local/LocalUserServices.cs b/OpenSim/Region/Communications/Local/LocalUserServices.cs
index af4fb37..d18937e 100644
--- a/OpenSim/Region/Communications/Local/LocalUserServices.cs
+++ b/OpenSim/Region/Communications/Local/LocalUserServices.cs
@@ -80,6 +80,21 @@ namespace OpenSim.Region.Communications.Local
80 throw new Exception("[LOCAL USER SERVICES]: Unknown master user UUID. Possible reason: UserServer is not running."); 80 throw new Exception("[LOCAL USER SERVICES]: Unknown master user UUID. Possible reason: UserServer is not running.");
81 } 81 }
82 return data; 82 return data;
83 } 83 }
84
85 public override bool AuthenticateUserByPassword(UUID userID, string password)
86 {
87 UserProfileData userProfile = GetUserProfile(userID);
88
89 if (null == userProfile)
90 return false;
91
92 string md5PasswordHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + userProfile.PasswordSalt);
93
94 if (md5PasswordHash == userProfile.PasswordHash)
95 return true;
96 else
97 return false;
98 }
84 } 99 }
85} 100} \ No newline at end of file
diff --git a/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs b/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs
index dff8305..51ba2e9 100644
--- a/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs
+++ b/OpenSim/Region/Communications/OGS1/OGS1UserServices.cs
@@ -140,6 +140,37 @@ namespace OpenSim.Region.Communications.OGS1
140 { 140 {
141 m_log.DebugFormat("[OGS1 USER SERVICES]: Verifying user session for " + userID); 141 m_log.DebugFormat("[OGS1 USER SERVICES]: Verifying user session for " + userID);
142 return AuthClient.VerifySession(GetUserServerURL(userID), userID, sessionID); 142 return AuthClient.VerifySession(GetUserServerURL(userID), userID, sessionID);
143 } 143 }
144
145 public override bool AuthenticateUserByPassword(UUID userID, string password)
146 {
147 Hashtable param = new Hashtable();
148 param["user_uuid"] = userID.ToString();
149 param["password"] = password;
150 IList parameters = new ArrayList();
151 parameters.Add(param);
152 XmlRpcRequest req = new XmlRpcRequest("authenticate_user_by_password", parameters);
153 XmlRpcResponse resp = req.Send(m_commsManager.NetworkServersInfo.UserURL, 30000);
154
155 // Temporary measure to deal with older services
156 if (resp.IsFault && resp.FaultCode == XmlRpcErrorCodes.SERVER_ERROR_METHOD)
157 {
158 throw new Exception(
159 String.Format(
160 "XMLRPC method 'authenticate_user_by_password' not yet implemented by user service at {0}",
161 m_commsManager.NetworkServersInfo.UserURL));
162 }
163
164 Hashtable respData = (Hashtable)resp.Value;
165
166 if ((string)respData["auth_user"] == "TRUE")
167 {
168 return true;
169 }
170 else
171 {
172 return false;
173 }
174 }
144 } 175 }
145} \ No newline at end of file 176} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
index 196205c..55dce05 100644
--- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs
@@ -322,7 +322,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
322 /// <param name="pass">User password</param> 322 /// <param name="pass">User password</param>
323 /// <returns></returns> 323 /// <returns></returns>
324 protected CachedUserInfo GetUserInfo(string firstName, string lastName, string pass) 324 protected CachedUserInfo GetUserInfo(string firstName, string lastName, string pass)
325 { 325 {
326 CachedUserInfo userInfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(firstName, lastName); 326 CachedUserInfo userInfo = m_aScene.CommsManager.UserProfileCacheService.GetUserDetails(firstName, lastName);
327 //m_aScene.CommsManager.UserService.GetUserProfile(firstName, lastName); 327 //m_aScene.CommsManager.UserService.GetUserProfile(firstName, lastName);
328 if (null == userInfo) 328 if (null == userInfo)
@@ -333,29 +333,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
333 return null; 333 return null;
334 } 334 }
335 335
336 string md5PasswdHash = Util.Md5Hash(Util.Md5Hash(pass) + ":" + userInfo.UserProfile.PasswordSalt); 336 try
337 337 {
338 if (userInfo.UserProfile.PasswordHash == null || userInfo.UserProfile.PasswordHash == String.Empty) 338 if (m_aScene.CommsManager.UserService.AuthenticateUserByPassword(userInfo.UserProfile.ID, pass))
339 { 339 {
340 m_log.ErrorFormat( 340 return userInfo;
341 "[INVENTORY ARCHIVER]: Sorry, the grid mode service is not providing password hash details for the check. This will be fixed in an OpenSim git revision soon"); 341 }
342 342 else
343 return null; 343 {
344 m_log.ErrorFormat(
345 "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.",
346 firstName, lastName);
347 return null;
348 }
344 } 349 }
345 350 catch (Exception e)
346// m_log.DebugFormat(
347// "[INVENTORY ARCHIVER]: received salt {0}, hash {1}, supplied hash {2}",
348// userInfo.UserProfile.PasswordSalt, userInfo.UserProfile.PasswordHash, md5PasswdHash);
349
350 if (userInfo.UserProfile.PasswordHash != md5PasswdHash)
351 { 351 {
352 m_log.ErrorFormat( 352 m_log.ErrorFormat("[INVENTORY ARCHIVER]: Could not authenticate password, {0}", e.Message);
353 "[INVENTORY ARCHIVER]: Password for user {0} {1} incorrect. Please try again.",
354 firstName, lastName);
355 return null; 353 return null;
356 } 354 }
357
358 return userInfo;
359 } 355 }
360 356
361 /// <summary> 357 /// <summary>
@@ -375,9 +371,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver
375 { 371 {
376 foreach (InventoryNodeBase node in loadedNodes) 372 foreach (InventoryNodeBase node in loadedNodes)
377 { 373 {
378 m_log.DebugFormat( 374// m_log.DebugFormat(
379 "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}", 375// "[INVENTORY ARCHIVER]: Notifying {0} of loaded inventory node {1}",
380 user.Name, node.Name); 376// user.Name, node.Name);
381 377
382 user.ControllingClient.SendBulkUpdateInventory(node); 378 user.ControllingClient.SendBulkUpdateInventory(node);
383 } 379 }