clockwerk-opensim-stable – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 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  
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31  
32 using OpenSim.Framework;
33 using OpenSim.Framework.Client;
34 using OpenSim.Region.Framework.Interfaces;
35 using OpenSim.Region.Framework.Scenes;
36 using OpenSim.Services.Connectors.Hypergrid;
37 using OpenSim.Services.Interfaces;
38 using OpenSim.Server.Base;
39  
40 using GridRegion = OpenSim.Services.Interfaces.GridRegion;
41  
42 using OpenMetaverse;
43 using log4net;
44 using Nini.Config;
45 using Mono.Addins;
46  
47 namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
48 {
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "HGInventoryAccessModule")]
50 public class HGInventoryAccessModule : BasicInventoryAccessModule, INonSharedRegionModule, IInventoryAccessModule
51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53  
54 private static HGAssetMapper m_assMapper;
55 public static HGAssetMapper AssetMapper
56 {
57 get { return m_assMapper; }
58 }
59  
60 private string m_HomeURI;
61 private bool m_OutboundPermission;
62 private string m_ThisGatekeeper;
63 private bool m_RestrictInventoryAccessAbroad;
64  
65 private bool m_bypassPermissions = true;
66  
67 // private bool m_Initialized = false;
68  
69 #region INonSharedRegionModule
70  
71 public override string Name
72 {
73 get { return "HGInventoryAccessModule"; }
74 }
75  
76 public override void Initialise(IConfigSource source)
77 {
78 IConfig moduleConfig = source.Configs["Modules"];
79 if (moduleConfig != null)
80 {
81 string name = moduleConfig.GetString("InventoryAccessModule", "");
82 if (name == Name)
83 {
84 m_Enabled = true;
85  
86 InitialiseCommon(source);
87  
88 m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name);
89  
90 IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"];
91 if (thisModuleConfig != null)
92 {
93 m_HomeURI = Util.GetConfigVarFromSections<string>(source, "HomeURI",
94 new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty);
95 m_ThisGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI",
96 new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty);
97 // Legacy. Renove soon!
98 m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", m_ThisGatekeeper);
99  
100 m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true);
101 m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true);
102 }
103 else
104 m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!");
105  
106 m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(source, "serverside_object_permissions",
107 new string[] { "Startup", "Permissions" }, true);
108  
109 }
110 }
111 }
112  
113 public override void AddRegion(Scene scene)
114 {
115 if (!m_Enabled)
116 return;
117  
118 base.AddRegion(scene);
119 m_assMapper = new HGAssetMapper(scene, m_HomeURI);
120 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
121 scene.EventManager.OnTeleportStart += TeleportStart;
122 scene.EventManager.OnTeleportFail += TeleportFail;
123  
124 // We're fgoing to enforce some stricter permissions if Outbound is false
125 scene.Permissions.OnTakeObject += CanTakeObject;
126 scene.Permissions.OnTakeCopyObject += CanTakeObject;
127 scene.Permissions.OnTransferUserInventory += OnTransferUserInventory;
128 }
129  
130 #endregion
131  
132 #region Event handlers
133  
134 protected override void OnNewClient(IClientAPI client)
135 {
136 base.OnNewClient(client);
137 client.OnCompleteMovementToRegion += new Action<IClientAPI, bool>(OnCompleteMovementToRegion);
138 }
139  
140 protected void OnCompleteMovementToRegion(IClientAPI client, bool arg2)
141 {
142 //m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: OnCompleteMovementToRegion of user {0}", client.Name);
143 object sp = null;
144 if (client.Scene.TryGetScenePresence(client.AgentId, out sp))
145 {
146 if (sp is ScenePresence)
147 {
148 AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId);
149 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
150 {
151 if (m_RestrictInventoryAccessAbroad)
152 {
153 IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
154 if (uMan.IsLocalGridUser(client.AgentId))
155 ProcessInventoryForComingHome(client);
156 else
157 ProcessInventoryForArriving(client);
158 }
159 }
160 }
161 }
162 }
163  
164 protected void TeleportStart(IClientAPI client, GridRegion destination, GridRegion finalDestination, uint teleportFlags, bool gridLogout)
165 {
166 if (gridLogout && m_RestrictInventoryAccessAbroad)
167 {
168 IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
169 if (uMan != null && uMan.IsLocalGridUser(client.AgentId))
170 {
171 // local grid user
172 ProcessInventoryForHypergriding(client);
173 }
174 else
175 {
176 // Foreigner
177 ProcessInventoryForLeaving(client);
178 }
179 }
180  
181 }
182  
183 protected void TeleportFail(IClientAPI client, bool gridLogout)
184 {
185 if (gridLogout && m_RestrictInventoryAccessAbroad)
186 {
187 IUserManagement uMan = m_Scene.RequestModuleInterface<IUserManagement>();
188 if (uMan.IsLocalGridUser(client.AgentId))
189 {
190 ProcessInventoryForComingHome(client);
191 }
192 else
193 {
194 ProcessInventoryForArriving(client);
195 }
196 }
197 }
198  
199 public void UploadInventoryItem(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel)
200 {
201 if (type == AssetType.Link)
202 return;
203  
204 string userAssetServer = string.Empty;
205 if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
206 {
207 m_assMapper.Post(assetID, avatarID, userAssetServer);
208 }
209 }
210  
211 #endregion
212  
213 #region Overrides of Basic Inventory Access methods
214  
215 protected override string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix)
216 {
217 if (UserManagementModule != null && !UserManagementModule.IsLocalGridUser(presence.UUID))
218 prefix = "HG ";
219 else
220 prefix = string.Empty;
221 suffix = " @ " + m_ThisGatekeeper;
222 Vector3 pos = presence.AbsolutePosition;
223 return String.Format("Landmark version 2\nregion_id {0}\nlocal_pos {1} {2} {3}\nregion_handle {4}\ngatekeeper {5}\n",
224 presence.Scene.RegionInfo.RegionID,
225 pos.X, pos.Y, pos.Z,
226 presence.RegionHandle,
227 m_ThisGatekeeper);
228 }
229  
230  
231 ///
232 /// CapsUpdateInventoryItemAsset
233 ///
234 public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
235 {
236 UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
237  
238 UploadInventoryItem(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0);
239  
240 return newAssetID;
241 }
242  
243 ///
244 /// Used in DeleteToInventory
245 ///
246 protected override void ExportAsset(UUID agentID, UUID assetID)
247 {
248 if (!assetID.Equals(UUID.Zero))
249 UploadInventoryItem(agentID, AssetType.Unknown, assetID, "", 0);
250 else
251 m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
252 }
253  
254 ///
255 /// RezObject
256 ///
257 public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
258 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
259 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
260 {
261 m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
262  
263 //if (fromTaskID.Equals(UUID.Zero))
264 //{
265 InventoryItemBase item = new InventoryItemBase(itemID);
266 item.Owner = remoteClient.AgentId;
267 item = m_Scene.InventoryService.GetItem(item);
268 //if (item == null)
269 //{ // Fetch the item
270 // item = new InventoryItemBase();
271 // item.Owner = remoteClient.AgentId;
272 // item.ID = itemID;
273 // item = m_assMapper.Get(item, userInfo.RootFolder.ID, userInfo);
274 //}
275 string userAssetServer = string.Empty;
276 if (item != null && IsForeignUser(remoteClient.AgentId, out userAssetServer))
277 {
278 m_assMapper.Get(item.AssetID, remoteClient.AgentId, userAssetServer);
279  
280 }
281 //}
282  
283 // OK, we're done fetching. Pass it up to the default RezObject
284 SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
285 RezSelected, RemoveItem, fromTaskID, attachment);
286  
287 if (sog == null)
288 remoteClient.SendAgentAlertMessage("Unable to rez: problem accessing inventory or locating assets", false);
289  
290 return sog;
291  
292 }
293  
294 public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
295 {
296 string userAssetServer = string.Empty;
297 if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty)
298 m_assMapper.Get(item.AssetID, sender, userAssetServer);
299  
300 if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission)
301 m_assMapper.Post(item.AssetID, receiver, userAssetServer);
302 }
303  
304 public override bool IsForeignUser(UUID userID, out string assetServerURL)
305 {
306 assetServerURL = string.Empty;
307  
308 if (UserManagementModule != null && !UserManagementModule.IsLocalGridUser(userID))
309 { // foreign
310 ScenePresence sp = null;
311 if (m_Scene.TryGetScenePresence(userID, out sp))
312 {
313 AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
314 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
315 {
316 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
317 assetServerURL = assetServerURL.Trim(new char[] { '/' });
318 }
319 }
320 else
321 {
322 assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI");
323 assetServerURL = assetServerURL.Trim(new char[] { '/' });
324 }
325 return true;
326 }
327  
328 return false;
329 }
330  
331 protected override InventoryItemBase GetItem(UUID agentID, UUID itemID)
332 {
333 InventoryItemBase item = base.GetItem(agentID, itemID);
334 if (item == null)
335 return null;
336  
337 string userAssetServer = string.Empty;
338 if (IsForeignUser(agentID, out userAssetServer))
339 m_assMapper.Get(item.AssetID, agentID, userAssetServer);
340  
341 return item;
342 }
343  
344 #endregion
345  
346 #region Inventory manipulation upon arriving/leaving
347  
348 //
349 // These 2 are for local and foreign users coming back, respectively
350 //
351  
352 private void ProcessInventoryForComingHome(IClientAPI client)
353 {
354 m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Restoring root folder for local user {0}", client.Name);
355 if (client is IClientCore)
356 {
357 IClientCore core = (IClientCore)client;
358 IClientInventory inv;
359  
360 if (core.TryGet<IClientInventory>(out inv))
361 {
362 InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
363 InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
364  
365 List<InventoryFolderBase> keep = new List<InventoryFolderBase>();
366  
367 foreach (InventoryFolderBase f in content.Folders)
368 {
369 if (f.Name != "My Suitcase" && f.Name != "Current Outfit")
370 keep.Add(f);
371 }
372  
373 inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
374 }
375 }
376 }
377  
378 private void ProcessInventoryForArriving(IClientAPI client)
379 {
380 // No-op for now, but we may need to do something for freign users inventory
381 }
382  
383 //
384 // These 2 are for local and foreign users going away respectively
385 //
386  
387 private void ProcessInventoryForHypergriding(IClientAPI client)
388 {
389 if (client is IClientCore)
390 {
391 IClientCore core = (IClientCore)client;
392 IClientInventory inv;
393  
394 if (core.TryGet<IClientInventory>(out inv))
395 {
396 InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId);
397 if (root != null)
398 {
399 m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name);
400 InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID);
401  
402 List<InventoryFolderBase> keep = new List<InventoryFolderBase>();
403  
404 foreach (InventoryFolderBase f in content.Folders)
405 {
406 if (f.Name != "My Suitcase" && f.Name != "Current Outfit")
407 {
408 f.Name = f.Name + " (Unavailable)";
409 keep.Add(f);
410 }
411 }
412  
413 // items directly under the root folder
414 foreach (InventoryItemBase it in content.Items)
415 it.Name = it.Name + " (Unavailable)"; ;
416  
417 // Send the new names
418 inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray());
419  
420 }
421 }
422 }
423 }
424  
425 private void ProcessInventoryForLeaving(IClientAPI client)
426 {
427 // No-op for now
428 }
429  
430 #endregion
431  
432 #region Permissions
433  
434 private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene)
435 {
436 if (m_bypassPermissions) return true;
437  
438 if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer))
439 {
440 SceneObjectGroup sog = null;
441 if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer)
442 return true;
443  
444 return false;
445 }
446  
447 return true;
448 }
449  
450 private bool OnTransferUserInventory(UUID itemID, UUID userID, UUID recipientID)
451 {
452 if (m_bypassPermissions) return true;
453  
454 if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(recipientID))
455 return false;
456  
457 return true;
458 }
459  
460  
461 #endregion
462 }
463 }