aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorDiva Canto2010-04-30 11:39:02 -0700
committerDiva Canto2010-04-30 11:39:02 -0700
commit5fda81e6bbb80cbe904e69638f5f405aca78f111 (patch)
tree670c850e7481a05398f93ae37460771fbd74863f /OpenSim
parenttake out some debug logging in the sqlite db adaptor (diff)
downloadopensim-SC-5fda81e6bbb80cbe904e69638f5f405aca78f111.zip
opensim-SC-5fda81e6bbb80cbe904e69638f5f405aca78f111.tar.gz
opensim-SC-5fda81e6bbb80cbe904e69638f5f405aca78f111.tar.bz2
opensim-SC-5fda81e6bbb80cbe904e69638f5f405aca78f111.tar.xz
* XInventory fairly tested, including for HG. Almost ready to switch.
* Removed a few buglets and added better exception handling.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs7
-rw-r--r--OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml1
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs212
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs8
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs2
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGInventoryServerInConnector.cs104
-rw-r--r--OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs50
-rw-r--r--OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs119
-rw-r--r--OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs2
9 files changed, 140 insertions, 365 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 23d5b3c..febd4ca 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -365,6 +365,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
365 List<UUID> GetOnlineFriends(UUID userID) 365 List<UUID> GetOnlineFriends(UUID userID)
366 { 366 {
367 List<string> friendList = new List<string>(); 367 List<string> friendList = new List<string>();
368 List<UUID> online = new List<UUID>();
368 369
369 foreach (FriendInfo fi in m_Friends[userID].Friends) 370 foreach (FriendInfo fi in m_Friends[userID].Friends)
370 { 371 {
@@ -372,9 +373,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
372 friendList.Add(fi.Friend); 373 friendList.Add(fi.Friend);
373 } 374 }
374 375
375 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); 376 if (friendList.Count == 0)
377 // no friends whatsoever
378 return online;
376 379
377 List<UUID> online = new List<UUID>(); 380 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
378 381
379 foreach (PresenceInfo pi in presence) 382 foreach (PresenceInfo pi in presence)
380 { 383 {
diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index 0a5ff3f..c738296 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -47,6 +47,7 @@
47 <RegionModule id="RemoteInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteInventoryServicesConnector" /> 47 <RegionModule id="RemoteInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteInventoryServicesConnector" />
48 <RegionModule id="RemoteXInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteXInventoryServicesConnector" /> 48 <RegionModule id="RemoteXInventoryServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.RemoteXInventoryServicesConnector" />
49 <RegionModule id="HGInventoryBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.HGInventoryBroker" /> 49 <RegionModule id="HGInventoryBroker" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.HGInventoryBroker" />
50 <RegionModule id="HGInventoryBroker2" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory.HGInventoryBroker2" />
50 <RegionModule id="LocalNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.LocalNeighbourServicesConnector" /> 51 <RegionModule id="LocalNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.LocalNeighbourServicesConnector" />
51 <RegionModule id="RemoteNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.RemoteNeighbourServicesConnector" /> 52 <RegionModule id="RemoteNeighbourServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Neighbour.RemoteNeighbourServicesConnector" />
52 <RegionModule id="LocalLandServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Land.LocalLandServicesConnector" /> 53 <RegionModule id="LocalLandServicesConnector" type="OpenSim.Region.CoreModules.ServiceConnectorsOut.Land.LocalLandServicesConnector" />
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs
index 3509161..fc3393f 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker2.cs
@@ -41,27 +41,22 @@ using OpenMetaverse;
41 41
42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory 42namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
43{ 43{
44 public class HGInventoryBroker2 : INonSharedRegionModule, IInventoryService 44 public class HGInventoryBroker2 : ISharedRegionModule, IInventoryService
45 { 45 {
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 49
50 private static bool m_Initialized = false;
51 private static bool m_Enabled = false; 50 private static bool m_Enabled = false;
52 51
53 private static IInventoryService m_LocalGridInventoryService; 52 private static IInventoryService m_LocalGridInventoryService;
54 private static ISessionAuthInventoryService m_HGService; // obsolete
55 private Dictionary<string, IInventoryService> m_connectors = new Dictionary<string, IInventoryService>(); 53 private Dictionary<string, IInventoryService> m_connectors = new Dictionary<string, IInventoryService>();
56 54
57 // A cache of userIDs --> ServiceURLs, for HGBroker only 55 // A cache of userIDs --> ServiceURLs, for HGBroker only
58 protected Dictionary<UUID, string> m_InventoryURLs; 56 protected Dictionary<UUID, string> m_InventoryURLs = new Dictionary<UUID,string>();
59 57
60 private Scene m_Scene;
61 private List<Scene> m_Scenes = new List<Scene>(); 58 private List<Scene> m_Scenes = new List<Scene>();
62 59
63 private IUserAccountService m_UserAccountService;
64
65 public Type ReplaceableInterface 60 public Type ReplaceableInterface
66 { 61 {
67 get { return null; } 62 get { return null; }
@@ -74,65 +69,45 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
74 69
75 public void Initialise(IConfigSource source) 70 public void Initialise(IConfigSource source)
76 { 71 {
77 if (!m_Initialized) 72 IConfig moduleConfig = source.Configs["Modules"];
73 if (moduleConfig != null)
78 { 74 {
79 IConfig moduleConfig = source.Configs["Modules"]; 75 string name = moduleConfig.GetString("InventoryServices", "");
80 if (moduleConfig != null) 76 if (name == Name)
81 { 77 {
82 string name = moduleConfig.GetString("InventoryServices", ""); 78 IConfig inventoryConfig = source.Configs["InventoryService"];
83 if (name == Name) 79 if (inventoryConfig == null)
84 { 80 {
85 IConfig inventoryConfig = source.Configs["InventoryService"]; 81 m_log.Error("[HG INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
86 if (inventoryConfig == null) 82 return;
87 { 83 }
88 m_log.Error("[HG INVENTORY CONNECTOR]: InventoryService missing from OpenSim.ini");
89 return;
90 }
91
92 string localDll = inventoryConfig.GetString("LocalGridInventoryService",
93 String.Empty);
94 string HGDll = inventoryConfig.GetString("HypergridInventoryService",
95 String.Empty);
96
97 if (localDll == String.Empty)
98 {
99 m_log.Error("[HG INVENTORY CONNECTOR]: No LocalGridInventoryService named in section InventoryService");
100 //return;
101 throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's");
102 }
103
104 if (HGDll == String.Empty)
105 {
106 m_log.Error("[HG INVENTORY CONNECTOR]: No HypergridInventoryService named in section InventoryService");
107 //return;
108 throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's");
109 }
110 84
111 Object[] args = new Object[] { source }; 85 string localDll = inventoryConfig.GetString("LocalGridInventoryService",
112 m_LocalGridInventoryService = 86 String.Empty);
113 ServerUtils.LoadPlugin<IInventoryService>(localDll, 87 //string HGDll = inventoryConfig.GetString("HypergridInventoryService",
114 args); 88 // String.Empty);
115 89
116 m_HGService = 90 if (localDll == String.Empty)
117 ServerUtils.LoadPlugin<ISessionAuthInventoryService>(HGDll, 91 {
118 args); 92 m_log.Error("[HG INVENTORY CONNECTOR]: No LocalGridInventoryService named in section InventoryService");
93 //return;
94 throw new Exception("Unable to proceed. Please make sure your ini files in config-include are updated according to .example's");
95 }
119 96
120 if (m_LocalGridInventoryService == null) 97 Object[] args = new Object[] { source };
121 { 98 m_LocalGridInventoryService =
122 m_log.Error("[HG INVENTORY CONNECTOR]: Can't load local inventory service"); 99 ServerUtils.LoadPlugin<IInventoryService>(localDll,
123 return; 100 args);
124 }
125 if (m_HGService == null)
126 {
127 m_log.Error("[HG INVENTORY CONNECTOR]: Can't load hypergrid inventory service");
128 return;
129 }
130 101
131 m_Enabled = true; 102 if (m_LocalGridInventoryService == null)
132 m_log.Info("[HG INVENTORY CONNECTOR]: HG inventory broker enabled"); 103 {
104 m_log.Error("[HG INVENTORY CONNECTOR]: Can't load local inventory service");
105 return;
133 } 106 }
107
108 m_Enabled = true;
109 m_log.InfoFormat("[HG INVENTORY CONNECTOR]: HG inventory broker enabled with inner connector of type {0}", m_LocalGridInventoryService.GetType());
134 } 110 }
135 m_Initialized = true;
136 } 111 }
137 } 112 }
138 113
@@ -149,13 +124,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
149 if (!m_Enabled) 124 if (!m_Enabled)
150 return; 125 return;
151 126
152 m_Scene = scene;
153 m_Scenes.Add(scene); 127 m_Scenes.Add(scene);
154 m_UserAccountService = m_Scene.UserAccountService;
155 128
156 scene.RegisterModuleInterface<IInventoryService>(this); 129 scene.RegisterModuleInterface<IInventoryService>(this);
157 130
158 scene.EventManager.OnMakeRootAgent += OnMakeRootAgent;
159 scene.EventManager.OnClientClosed += OnClientClosed; 131 scene.EventManager.OnClientClosed += OnClientClosed;
160 132
161 } 133 }
@@ -177,13 +149,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
177 149
178 } 150 }
179 151
180 #region Cache 152 #region URL Cache
181
182 void OnMakeRootAgent(ScenePresence presence)
183 {
184 if (!m_InventoryURLs.ContainsKey(presence.UUID))
185 CacheInventoryServiceURL(presence.Scene, presence.UUID);
186 }
187 153
188 void OnClientClosed(UUID clientID, Scene scene) 154 void OnClientClosed(UUID clientID, Scene scene)
189 { 155 {
@@ -200,10 +166,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
200 return; 166 return;
201 } 167 }
202 } 168 }
203
204 m_log.DebugFormat(
205 "[INVENTORY CACHE]: OnClientClosed in {0}, user {1} out of sim. Dropping inventory URL",
206 scene.RegionInfo.RegionName, clientID);
207 DropInventoryServiceURL(clientID); 169 DropInventoryServiceURL(clientID);
208 } 170 }
209 } 171 }
@@ -213,35 +175,47 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
213 /// and sticks it in the cache 175 /// and sticks it in the cache
214 /// </summary> 176 /// </summary>
215 /// <param name="userID"></param> 177 /// <param name="userID"></param>
216 private void CacheInventoryServiceURL(Scene scene, UUID userID) 178 private void CacheInventoryServiceURL(UUID userID)
217 { 179 {
218 if (scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, userID) == null) 180 if (m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, userID) == null)
219 { 181 {
220 // The user does not have a local account; let's cache its service URL 182 // The user does not have a local account; let's cache its service URL
221 string inventoryURL = string.Empty; 183 string inventoryURL = string.Empty;
222 ScenePresence sp = null; 184 ScenePresence sp = null;
223 scene.TryGetScenePresence(userID, out sp); 185 foreach (Scene scene in m_Scenes)
224 if (sp != null)
225 { 186 {
226 AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 187 scene.TryGetScenePresence(userID, out sp);
227 if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI")) 188 if (sp != null)
228 { 189 {
229 inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString(); 190 AgentCircuitData aCircuit = scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
230 if (inventoryURL != null && inventoryURL != string.Empty) 191 if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI"))
231 { 192 {
232 inventoryURL = inventoryURL.Trim(new char[] { '/' }); 193 inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString();
233 m_InventoryURLs.Add(userID, inventoryURL); 194 if (inventoryURL != null && inventoryURL != string.Empty)
195 {
196 inventoryURL = inventoryURL.Trim(new char[] { '/' });
197 m_InventoryURLs.Add(userID, inventoryURL);
198 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Added {0} to the cache of inventory URLs", inventoryURL);
199 return;
200 }
234 } 201 }
235 } 202 }
236 } 203 }
237 } 204 }
205
206 // else put a null; it means that the methods should forward to local grid's inventory
207 m_InventoryURLs.Add(userID, null);
238 } 208 }
239 209
240 private void DropInventoryServiceURL(UUID userID) 210 private void DropInventoryServiceURL(UUID userID)
241 { 211 {
242 lock (m_InventoryURLs) 212 lock (m_InventoryURLs)
243 if (m_InventoryURLs.ContainsKey(userID)) 213 if (m_InventoryURLs.ContainsKey(userID))
214 {
215 string url = m_InventoryURLs[userID];
244 m_InventoryURLs.Remove(userID); 216 m_InventoryURLs.Remove(userID);
217 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: Removed {0} from the cache of inventory URLs", url);
218 }
245 } 219 }
246 220
247 public string GetInventoryServiceURL(UUID userID) 221 public string GetInventoryServiceURL(UUID userID)
@@ -249,7 +223,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
249 if (m_InventoryURLs.ContainsKey(userID)) 223 if (m_InventoryURLs.ContainsKey(userID))
250 return m_InventoryURLs[userID]; 224 return m_InventoryURLs[userID];
251 225
252 return null; 226 else
227 CacheInventoryServiceURL(userID);
228
229 return m_InventoryURLs[userID];
253 } 230 }
254 #endregion 231 #endregion
255 232
@@ -276,7 +253,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
276 253
277 public InventoryFolderBase GetRootFolder(UUID userID) 254 public InventoryFolderBase GetRootFolder(UUID userID)
278 { 255 {
279 m_log.DebugFormat("[HGInventory]: GetRootFolder for {0}", userID); 256 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetRootFolder for {0}", userID);
280 257
281 string invURL = GetInventoryServiceURL(userID); 258 string invURL = GetInventoryServiceURL(userID);
282 259
@@ -290,7 +267,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
290 267
291 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type) 268 public InventoryFolderBase GetFolderForType(UUID userID, AssetType type)
292 { 269 {
293 m_log.DebugFormat("[HGInventory]: GetFolderForType {0} type {1}", userID, type); 270 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: GetFolderForType {0} type {1}", userID, type);
294 271
295 string invURL = GetInventoryServiceURL(userID); 272 string invURL = GetInventoryServiceURL(userID);
296 273
@@ -304,7 +281,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
304 281
305 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 282 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
306 { 283 {
307 m_log.Debug("[HGInventory]: GetFolderContent " + folderID); 284 m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderContent " + folderID);
308 285
309 string invURL = GetInventoryServiceURL(userID); 286 string invURL = GetInventoryServiceURL(userID);
310 287
@@ -319,7 +296,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
319 296
320 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) 297 public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID)
321 { 298 {
322 m_log.Debug("[HGInventory]: GetFolderItems " + folderID); 299 m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID);
323 300
324 string invURL = GetInventoryServiceURL(userID); 301 string invURL = GetInventoryServiceURL(userID);
325 302
@@ -337,7 +314,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
337 if (folder == null) 314 if (folder == null)
338 return false; 315 return false;
339 316
340 m_log.Debug("[HGInventory]: AddFolder " + folder.ID); 317 m_log.Debug("[HG INVENTORY CONNECTOR]: AddFolder " + folder.ID);
341 318
342 string invURL = GetInventoryServiceURL(folder.Owner); 319 string invURL = GetInventoryServiceURL(folder.Owner);
343 320
@@ -354,7 +331,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
354 if (folder == null) 331 if (folder == null)
355 return false; 332 return false;
356 333
357 m_log.Debug("[HGInventory]: UpdateFolder " + folder.ID); 334 m_log.Debug("[HG INVENTORY CONNECTOR]: UpdateFolder " + folder.ID);
358 335
359 string invURL = GetInventoryServiceURL(folder.Owner); 336 string invURL = GetInventoryServiceURL(folder.Owner);
360 337
@@ -373,7 +350,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
373 if (folderIDs.Count == 0) 350 if (folderIDs.Count == 0)
374 return false; 351 return false;
375 352
376 m_log.Debug("[HGInventory]: DeleteFolders for " + ownerID); 353 m_log.Debug("[HG INVENTORY CONNECTOR]: DeleteFolders for " + ownerID);
377 354
378 string invURL = GetInventoryServiceURL(ownerID); 355 string invURL = GetInventoryServiceURL(ownerID);
379 356
@@ -390,7 +367,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
390 if (folder == null) 367 if (folder == null)
391 return false; 368 return false;
392 369
393 m_log.Debug("[HGInventory]: MoveFolder for " + folder.Owner); 370 m_log.Debug("[HG INVENTORY CONNECTOR]: MoveFolder for " + folder.Owner);
394 371
395 string invURL = GetInventoryServiceURL(folder.Owner); 372 string invURL = GetInventoryServiceURL(folder.Owner);
396 373
@@ -407,7 +384,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
407 if (folder == null) 384 if (folder == null)
408 return false; 385 return false;
409 386
410 m_log.Debug("[HGInventory]: PurgeFolder for " + folder.Owner); 387 m_log.Debug("[HG INVENTORY CONNECTOR]: PurgeFolder for " + folder.Owner);
411 388
412 string invURL = GetInventoryServiceURL(folder.Owner); 389 string invURL = GetInventoryServiceURL(folder.Owner);
413 390
@@ -424,7 +401,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
424 if (item == null) 401 if (item == null)
425 return false; 402 return false;
426 403
427 m_log.Debug("[HGInventory]: AddItem " + item.ID); 404 m_log.Debug("[HG INVENTORY CONNECTOR]: AddItem " + item.ID);
428 405
429 string invURL = GetInventoryServiceURL(item.Owner); 406 string invURL = GetInventoryServiceURL(item.Owner);
430 407
@@ -441,7 +418,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
441 if (item == null) 418 if (item == null)
442 return false; 419 return false;
443 420
444 m_log.Debug("[HGInventory]: UpdateItem " + item.ID); 421 m_log.Debug("[HG INVENTORY CONNECTOR]: UpdateItem " + item.ID);
445 422
446 string invURL = GetInventoryServiceURL(item.Owner); 423 string invURL = GetInventoryServiceURL(item.Owner);
447 424
@@ -460,7 +437,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
460 if (items.Count == 0) 437 if (items.Count == 0)
461 return true; 438 return true;
462 439
463 m_log.Debug("[HGInventory]: MoveItems for " + ownerID); 440 m_log.Debug("[HG INVENTORY CONNECTOR]: MoveItems for " + ownerID);
464 441
465 string invURL = GetInventoryServiceURL(ownerID); 442 string invURL = GetInventoryServiceURL(ownerID);
466 443
@@ -481,7 +458,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
481 if (itemIDs.Count == 0) 458 if (itemIDs.Count == 0)
482 return true; 459 return true;
483 460
484 m_log.Debug("[HGInventory]: DeleteItems for " + ownerID); 461 m_log.Debug("[HG INVENTORY CONNECTOR]: DeleteItems for " + ownerID);
485 462
486 string invURL = GetInventoryServiceURL(ownerID); 463 string invURL = GetInventoryServiceURL(ownerID);
487 464
@@ -497,7 +474,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
497 { 474 {
498 if (item == null) 475 if (item == null)
499 return null; 476 return null;
500 m_log.Debug("[HGInventory]: GetItem " + item.ID); 477 m_log.Debug("[HG INVENTORY CONNECTOR]: GetItem " + item.ID);
501 478
502 string invURL = GetInventoryServiceURL(item.Owner); 479 string invURL = GetInventoryServiceURL(item.Owner);
503 480
@@ -514,7 +491,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
514 if (folder == null) 491 if (folder == null)
515 return null; 492 return null;
516 493
517 m_log.Debug("[HGInventory]: GetFolder " + folder.ID); 494 m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolder " + folder.ID);
518 495
519 string invURL = GetInventoryServiceURL(folder.Owner); 496 string invURL = GetInventoryServiceURL(folder.Owner);
520 497
@@ -538,7 +515,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
538 515
539 public int GetAssetPermissions(UUID userID, UUID assetID) 516 public int GetAssetPermissions(UUID userID, UUID assetID)
540 { 517 {
541 m_log.Debug("[HGInventory]: GetAssetPermissions " + assetID); 518 m_log.Debug("[HG INVENTORY CONNECTOR]: GetAssetPermissions " + assetID);
542 519
543 string invURL = GetInventoryServiceURL(userID); 520 string invURL = GetInventoryServiceURL(userID);
544 521
@@ -575,44 +552,5 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
575 return connector; 552 return connector;
576 } 553 }
577 554
578
579 private UUID GetSessionID(UUID userID)
580 {
581 ScenePresence sp = null;
582 if (m_Scene.TryGetScenePresence(userID, out sp))
583 {
584 return sp.ControllingClient.SessionId;
585 }
586
587 m_log.DebugFormat("[HG INVENTORY CONNECTOR]: scene presence for {0} not found", userID);
588 return UUID.Zero;
589 }
590
591 private bool IsForeignUser(UUID userID, out string inventoryURL)
592 {
593 inventoryURL = string.Empty;
594 UserAccount account = null;
595 if (m_Scene.UserAccountService != null)
596 account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, userID);
597
598 if (account == null) // foreign user
599 {
600 ScenePresence sp = null;
601 m_Scene.TryGetScenePresence(userID, out sp);
602 if (sp != null)
603 {
604 AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
605 if (aCircuit.ServiceURLs.ContainsKey("InventoryServerURI"))
606 {
607 inventoryURL = aCircuit.ServiceURLs["InventoryServerURI"].ToString();
608 inventoryURL = inventoryURL.Trim(new char[] { '/' });
609 return true;
610 }
611 }
612 }
613 return false;
614 }
615
616
617 } 555 }
618} 556}
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
index ac9e792..277060d 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs
@@ -172,11 +172,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
172 return m_RemoteConnector.GetFolderForType(userID, type); 172 return m_RemoteConnector.GetFolderForType(userID, type);
173 } 173 }
174 174
175 public Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(UUID userID)
176 {
177 return m_RemoteConnector.GetSystemFolders(userID);
178 }
179
180 public InventoryCollection GetFolderContent(UUID userID, UUID folderID) 175 public InventoryCollection GetFolderContent(UUID userID, UUID folderID)
181 { 176 {
182 return m_RemoteConnector.GetFolderContent(userID, folderID); 177 return m_RemoteConnector.GetFolderContent(userID, folderID);
@@ -267,9 +262,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
267 262
268 public InventoryItemBase GetItem(InventoryItemBase item) 263 public InventoryItemBase GetItem(InventoryItemBase item)
269 { 264 {
265 m_log.DebugFormat("[XINVENTORY CONNECTOR]: GetItem {0}", item.ID);
270 if (item == null) 266 if (item == null)
271 return null; 267 return null;
272 268
269 if (m_RemoteConnector == null)
270 m_log.DebugFormat("[XINVENTORY CONNECTOR]: connector stub is null!!!");
273 return m_RemoteConnector.GetItem(item); 271 return m_RemoteConnector.GetItem(item);
274 } 272 }
275 273
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs
index 865f99e..5f3666e 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/RemotePresenceServiceConnector.cs
@@ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence
76 76
77 m_PresenceDetector = new PresenceDetector(this); 77 m_PresenceDetector = new PresenceDetector(this);
78 78
79 m_log.Info("[INVENTORY CONNECTOR]: Remote presence enabled"); 79 m_log.Info("[REMOTE PRESENCE CONNECTOR]: Remote presence enabled");
80 } 80 }
81 } 81 }
82 82
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGInventoryServerInConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HGInventoryServerInConnector.cs
deleted file mode 100644
index 41897eb..0000000
--- a/OpenSim/Server/Handlers/Hypergrid/HGInventoryServerInConnector.cs
+++ /dev/null
@@ -1,104 +0,0 @@
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.Reflection;
33using log4net;
34using Nini.Config;
35using Nwc.XmlRpc;
36using OpenSim.Server.Base;
37using OpenSim.Server.Handlers.Inventory;
38using OpenSim.Services.Interfaces;
39using OpenSim.Framework;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Server.Handlers.Base;
42using OpenMetaverse;
43
44namespace OpenSim.Server.Handlers.Hypergrid
45{
46 public class HGInventoryServiceInConnector : InventoryServiceInConnector
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 //private static readonly int INVENTORY_DEFAULT_SESSION_TIME = 30; // secs
51 //private AuthedSessionCache m_session_cache = new AuthedSessionCache(INVENTORY_DEFAULT_SESSION_TIME);
52
53 private IUserAgentService m_UserAgentService;
54
55 public HGInventoryServiceInConnector(IConfigSource config, IHttpServer server, string configName) :
56 base(config, server, configName)
57 {
58 IConfig serverConfig = config.Configs[m_ConfigName];
59 if (serverConfig == null)
60 throw new Exception(String.Format("No section '{0}' in config file", m_ConfigName));
61
62 string userAgentService = serverConfig.GetString("UserAgentService", string.Empty);
63 string m_userserver_url = serverConfig.GetString("UserAgentURI", String.Empty);
64 if (m_userserver_url != string.Empty)
65 {
66 Object[] args = new Object[] { m_userserver_url };
67 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(userAgentService, args);
68 }
69
70 AddHttpHandlers(server);
71 m_log.Debug("[HG INVENTORY HANDLER]: handlers initialized");
72 }
73
74 /// <summary>
75 /// Check that the source of an inventory request for a particular agent is a current session belonging to
76 /// that agent.
77 /// </summary>
78 /// <param name="session_id"></param>
79 /// <param name="avatar_id"></param>
80 /// <returns></returns>
81 public override bool CheckAuthSession(string session_id, string avatar_id)
82 {
83 //m_log.InfoFormat("[HG INVENTORY IN CONNECTOR]: checking authed session {0} {1}", session_id, avatar_id);
84 // This doesn't work
85
86 // if (m_session_cache.getCachedSession(session_id, avatar_id) == null)
87 // {
88 // //cache miss, ask userserver
89 // m_UserAgentService.VerifyAgent(session_id, ???);
90 // }
91 // else
92 // {
93 // // cache hits
94 // m_log.Info("[HG INVENTORY IN CONNECTOR]: got authed session from cache");
95 // return true;
96 // }
97
98 // m_log.Warn("[HG INVENTORY IN CONNECTOR]: unknown session_id, request rejected");
99 // return false;
100
101 return true;
102 }
103 }
104}
diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
index 16b05df..b0fee6d 100644
--- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
+++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs
@@ -144,8 +144,6 @@ namespace OpenSim.Server.Handlers.Asset
144 return HandleGetActiveGestures(request); 144 return HandleGetActiveGestures(request);
145 case "GETASSETPERMISSIONS": 145 case "GETASSETPERMISSIONS":
146 return HandleGetAssetPermissions(request); 146 return HandleGetAssetPermissions(request);
147 case "GETSYSTEMFOLDERS":
148 return HandleGetSystemFolders(request);
149 } 147 }
150 m_log.DebugFormat("[XINVENTORY HANDLER]: unknown method request: {0}", method); 148 m_log.DebugFormat("[XINVENTORY HANDLER]: unknown method request: {0}", method);
151 } 149 }
@@ -575,29 +573,6 @@ namespace OpenSim.Server.Handlers.Asset
575 return encoding.GetBytes(xmlString); 573 return encoding.GetBytes(xmlString);
576 } 574 }
577 575
578 byte[] HandleGetSystemFolders(Dictionary<string, object> request)
579 {
580 Dictionary<string, object> result = new Dictionary<string, object>();
581 UUID principal = UUID.Zero;
582 UUID.TryParse(request["PRINCIPAL"].ToString(), out principal);
583
584 Dictionary<AssetType, InventoryFolderBase> sfolders = GetSystemFolders(principal);
585 //m_log.DebugFormat("[XXX]: SystemFolders got {0} folders", sfolders.Count);
586
587 Dictionary<string, object> folders = new Dictionary<string, object>();
588 int i = 0;
589 foreach (KeyValuePair<AssetType, InventoryFolderBase> kvp in sfolders)
590 {
591 folders["folder_" + i.ToString()] = EncodeFolder(kvp.Value);
592 i++;
593 }
594 result["FOLDERS"] = folders;
595
596 string xmlString = ServerUtils.BuildXmlResponse(result);
597 //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
598 UTF8Encoding encoding = new UTF8Encoding();
599 return encoding.GetBytes(xmlString);
600 }
601 576
602 private Dictionary<string, object> EncodeFolder(InventoryFolderBase f) 577 private Dictionary<string, object> EncodeFolder(InventoryFolderBase f)
603 { 578 {
@@ -683,30 +658,5 @@ namespace OpenSim.Server.Handlers.Asset
683 return item; 658 return item;
684 } 659 }
685 660
686 #region Extra
687 private Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(UUID userID)
688 {
689 InventoryFolderBase root = m_InventoryService.GetRootFolder(userID);
690 if (root != null)
691 {
692 InventoryCollection content = m_InventoryService.GetFolderContent(userID, root.ID);
693 if (content != null)
694 {
695 Dictionary<AssetType, InventoryFolderBase> folders = new Dictionary<AssetType, InventoryFolderBase>();
696 foreach (InventoryFolderBase folder in content.Folders)
697 {
698 if ((folder.Type != (short)AssetType.Folder) && (folder.Type != (short)AssetType.Unknown))
699 folders[(AssetType)folder.Type] = folder;
700 }
701 // Put the root folder there, as type Folder
702 folders[AssetType.Folder] = root;
703 return folders;
704 }
705 }
706 m_log.WarnFormat("[XINVENTORY SERVICE]: System folders for {0} not found", userID);
707 return new Dictionary<AssetType, InventoryFolderBase>();
708 }
709 #endregion
710
711 } 661 }
712} 662}
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
index 52294da..e25e7eb 100644
--- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
+++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs
@@ -158,30 +158,31 @@ namespace OpenSim.Services.Connectors
158 158
159 public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) 159 public InventoryCollection GetFolderContent(UUID principalID, UUID folderID)
160 { 160 {
161 Dictionary<string,object> ret = MakeRequest("GETFOLDERCONTENT",
162 new Dictionary<string,object> {
163 { "PRINCIPAL", principalID.ToString() },
164 { "FOLDER", folderID.ToString() }
165 });
166
167 if (ret == null)
168 return null;
169 if (ret.Count == 0)
170 return null;
171
172
173 InventoryCollection inventory = new InventoryCollection(); 161 InventoryCollection inventory = new InventoryCollection();
174 inventory.Folders = new List<InventoryFolderBase>();
175 inventory.Items = new List<InventoryItemBase>();
176 inventory.UserID = principalID;
177 162
178 Dictionary<string,object> folders =
179 (Dictionary<string,object>)ret["FOLDERS"];
180 Dictionary<string,object> items =
181 (Dictionary<string,object>)ret["ITEMS"];
182
183 try 163 try
184 { 164 {
165 Dictionary<string,object> ret = MakeRequest("GETFOLDERCONTENT",
166 new Dictionary<string,object> {
167 { "PRINCIPAL", principalID.ToString() },
168 { "FOLDER", folderID.ToString() }
169 });
170
171 if (ret == null)
172 return null;
173 if (ret.Count == 0)
174 return null;
175
176
177 inventory.Folders = new List<InventoryFolderBase>();
178 inventory.Items = new List<InventoryItemBase>();
179 inventory.UserID = principalID;
180
181 Dictionary<string,object> folders =
182 (Dictionary<string,object>)ret["FOLDERS"];
183 Dictionary<string,object> items =
184 (Dictionary<string,object>)ret["ITEMS"];
185
185 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i 186 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
186 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o)); 187 inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o));
187 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i 188 foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i
@@ -189,7 +190,7 @@ namespace OpenSim.Services.Connectors
189 } 190 }
190 catch (Exception e) 191 catch (Exception e)
191 { 192 {
192 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception unwrapping content list: {0}", e.Message); 193 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolderContent: {0}", e.Message);
193 } 194 }
194 195
195 return inventory; 196 return inventory;
@@ -408,32 +409,50 @@ namespace OpenSim.Services.Connectors
408 409
409 public InventoryItemBase GetItem(InventoryItemBase item) 410 public InventoryItemBase GetItem(InventoryItemBase item)
410 { 411 {
411 Dictionary<string,object> ret = MakeRequest("GETITEM", 412 try
412 new Dictionary<string,object> { 413 {
414 Dictionary<string, object> ret = MakeRequest("GETITEM",
415 new Dictionary<string, object> {
413 { "ID", item.ID.ToString() } 416 { "ID", item.ID.ToString() }
414 }); 417 });
415 418
416 if (ret == null) 419 if (ret == null)
417 return null; 420 return null;
418 if (ret.Count == 0) 421 if (ret.Count == 0)
419 return null; 422 return null;
423
424 return BuildItem((Dictionary<string, object>)ret["item"]);
425 }
426 catch (Exception e)
427 {
428 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetItem: {0}", e.Message);
429 }
420 430
421 return BuildItem((Dictionary<string, object>)ret["item"]); 431 return null;
422 } 432 }
423 433
424 public InventoryFolderBase GetFolder(InventoryFolderBase folder) 434 public InventoryFolderBase GetFolder(InventoryFolderBase folder)
425 { 435 {
426 Dictionary<string,object> ret = MakeRequest("GETFOLDER", 436 try
427 new Dictionary<string,object> { 437 {
438 Dictionary<string, object> ret = MakeRequest("GETFOLDER",
439 new Dictionary<string, object> {
428 { "ID", folder.ID.ToString() } 440 { "ID", folder.ID.ToString() }
429 }); 441 });
430 442
431 if (ret == null) 443 if (ret == null)
432 return null; 444 return null;
433 if (ret.Count == 0) 445 if (ret.Count == 0)
434 return null; 446 return null;
435 447
436 return BuildFolder((Dictionary<string, object>)ret["folder"]); 448 return BuildFolder((Dictionary<string, object>)ret["folder"]);
449 }
450 catch (Exception e)
451 {
452 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: Exception in GetFolder: {0}", e.Message);
453 }
454
455 return null;
437 } 456 }
438 457
439 public List<InventoryItemBase> GetActiveGestures(UUID principalID) 458 public List<InventoryItemBase> GetActiveGestures(UUID principalID)
@@ -468,36 +487,6 @@ namespace OpenSim.Services.Connectors
468 return int.Parse(ret["RESULT"].ToString()); 487 return int.Parse(ret["RESULT"].ToString());
469 } 488 }
470 489
471 public Dictionary<AssetType, InventoryFolderBase> GetSystemFolders(UUID userID)
472 {
473 Dictionary<string, object> ret = MakeRequest("GETSYSTEMFOLDERS",
474 new Dictionary<string, object> {
475 { "PRINCIPAL", userID.ToString() },
476 });
477
478 if (ret == null)
479 return new Dictionary<AssetType,InventoryFolderBase>();
480
481 Dictionary<AssetType, InventoryFolderBase> sfolders = new Dictionary<AssetType, InventoryFolderBase>();
482
483 try
484 {
485 Dictionary<string, object> folders = (Dictionary<string, object>)ret["FOLDERS"];
486
487 foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i
488 {
489 InventoryFolderBase folder = BuildFolder((Dictionary<string, object>)o);
490 sfolders.Add((AssetType)folder.Type, folder);
491 }
492
493 }
494 catch (Exception e)
495 {
496 m_log.DebugFormat("[XINVENTORY CONNECTOR STUB]: exception {0}", e.Message);
497 }
498
499 return sfolders;
500 }
501 490
502 // These are either obsolete or unused 491 // These are either obsolete or unused
503 // 492 //
diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
index 4dadd9e..23621b7 100644
--- a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs
@@ -329,7 +329,7 @@ namespace OpenSim.Services.Connectors
329 reqString); 329 reqString);
330 if (reply == null || (reply != null && reply == string.Empty)) 330 if (reply == null || (reply != null && reply == string.Empty))
331 { 331 {
332 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgent received null or empty reply"); 332 m_log.DebugFormat("[PRESENCE CONNECTOR]: GetAgents received null or empty reply");
333 return null; 333 return null;
334 } 334 }
335 } 335 }