aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework/InventoryAccess
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/InventoryAccess')
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs200
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs207
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs57
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs655
4 files changed, 1119 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
new file mode 100644
index 0000000..664f38d
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs
@@ -0,0 +1,200 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Threading;
32using log4net;
33using OpenMetaverse;
34using OpenSim.Framework;
35
36using OpenSim.Region.Framework.Scenes;
37using OpenSim.Region.Framework.Scenes.Serialization;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Services.Interfaces;
40
41//using HyperGrid.Framework;
42//using OpenSim.Region.Communications.Hypergrid;
43
44namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
45{
46 public class HGAssetMapper
47 {
48 #region Fields
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 // This maps between inventory server urls and inventory server clients
52// private Dictionary<string, InventoryClient> m_inventoryServers = new Dictionary<string, InventoryClient>();
53
54 private Scene m_scene;
55
56 #endregion
57
58 #region Constructor
59
60 public HGAssetMapper(Scene scene)
61 {
62 m_scene = scene;
63 }
64
65 #endregion
66
67 #region Internal functions
68
69 public AssetBase FetchAsset(string url, UUID assetID)
70 {
71 AssetBase asset = m_scene.AssetService.Get(url + "/" + assetID.ToString());
72
73 if (asset != null)
74 {
75 m_log.DebugFormat("[HG ASSET MAPPER]: Copied asset {0} from {1} to local asset server. ", asset.ID, url);
76 return asset;
77 }
78 return null;
79 }
80
81 public bool PostAsset(string url, AssetBase asset)
82 {
83 if (asset != null)
84 {
85 // See long comment in AssetCache.AddAsset
86 if (!asset.Temporary || asset.Local)
87 {
88 // We need to copy the asset into a new asset, because
89 // we need to set its ID to be URL+UUID, so that the
90 // HGAssetService dispatches it to the remote grid.
91 // It's not pretty, but the best that can be done while
92 // not having a global naming infrastructure
93 AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID);
94 Copy(asset, asset1);
95 try
96 {
97 asset1.ID = url + "/" + asset.ID;
98 }
99 catch
100 {
101 m_log.Warn("[HG ASSET MAPPER]: Oops.");
102 }
103
104 m_scene.AssetService.Store(asset1);
105 m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url);
106 }
107 return true;
108 }
109 else
110 m_log.Warn("[HG ASSET MAPPER]: Tried to post asset to remote server, but asset not in local cache.");
111
112 return false;
113 }
114
115 private void Copy(AssetBase from, AssetBase to)
116 {
117 to.Data = from.Data;
118 to.Description = from.Description;
119 to.FullID = from.FullID;
120 to.ID = from.ID;
121 to.Local = from.Local;
122 to.Name = from.Name;
123 to.Temporary = from.Temporary;
124 to.Type = from.Type;
125
126 }
127
128 // TODO: unused
129 // private void Dump(Dictionary<UUID, bool> lst)
130 // {
131 // m_log.Debug("XXX -------- UUID DUMP ------- XXX");
132 // foreach (KeyValuePair<UUID, bool> kvp in lst)
133 // m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")");
134 // m_log.Debug("XXX -------- UUID DUMP ------- XXX");
135 // }
136
137 #endregion
138
139
140 #region Public interface
141
142 public void Get(UUID assetID, UUID ownerID, string userAssetURL)
143 {
144 // Get the item from the remote asset server onto the local AssetCache
145 // and place an entry in m_assetMap
146
147 m_log.Debug("[HG ASSET MAPPER]: Fetching object " + assetID + " from asset server " + userAssetURL);
148 AssetBase asset = FetchAsset(userAssetURL, assetID);
149
150 if (asset != null)
151 {
152 // OK, now fetch the inside.
153 Dictionary<UUID, int> ids = new Dictionary<UUID, int>();
154 HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, userAssetURL);
155 uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids);
156 foreach (UUID uuid in ids.Keys)
157 FetchAsset(userAssetURL, uuid);
158
159 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully fetched asset {0} from asset server {1}", asset.ID, userAssetURL);
160
161 }
162 else
163 m_log.Warn("[HG ASSET MAPPER]: Could not fetch asset from remote asset server " + userAssetURL);
164 }
165
166
167 public void Post(UUID assetID, UUID ownerID, string userAssetURL)
168 {
169 // Post the item from the local AssetCache onto the remote asset server
170 // and place an entry in m_assetMap
171
172 m_log.Debug("[HG ASSET MAPPER]: Posting object " + assetID + " to asset server " + userAssetURL);
173 AssetBase asset = m_scene.AssetService.Get(assetID.ToString());
174 if (asset != null)
175 {
176 Dictionary<UUID, int> ids = new Dictionary<UUID, int>();
177 HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, string.Empty);
178 uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids);
179 foreach (UUID uuid in ids.Keys)
180 {
181 asset = m_scene.AssetService.Get(uuid.ToString());
182 if (asset == null)
183 m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid);
184 else
185 PostAsset(userAssetURL, asset);
186 }
187
188 // maybe all pieces got there...
189 m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL);
190
191 }
192 else
193 m_log.DebugFormat("[HG ASSET MAPPER]: Something wrong with asset {0}, it could not be found", assetID);
194
195 }
196
197 #endregion
198
199 }
200}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
new file mode 100644
index 0000000..25f5154
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs
@@ -0,0 +1,207 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31
32using OpenSim.Framework;
33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Services.Connectors.Hypergrid;
36using OpenSim.Services.Interfaces;
37using OpenSim.Server.Base;
38
39using GridRegion = OpenSim.Services.Interfaces.GridRegion;
40
41using OpenMetaverse;
42using log4net;
43using Nini.Config;
44
45namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
46{
47 public class HGInventoryAccessModule : BasicInventoryAccessModule, INonSharedRegionModule, IInventoryAccessModule
48 {
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private static HGAssetMapper m_assMapper;
52 public static HGAssetMapper AssetMapper
53 {
54 get { return m_assMapper; }
55 }
56
57 private bool m_Initialized = false;
58
59 #region INonSharedRegionModule
60
61 public override string Name
62 {
63 get { return "HGInventoryAccessModule"; }
64 }
65
66 public override void Initialise(IConfigSource source)
67 {
68 IConfig moduleConfig = source.Configs["Modules"];
69 if (moduleConfig != null)
70 {
71 string name = moduleConfig.GetString("InventoryAccessModule", "");
72 if (name == Name)
73 {
74 m_Enabled = true;
75 m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name);
76 }
77 }
78 }
79
80 public override void AddRegion(Scene scene)
81 {
82 if (!m_Enabled)
83 return;
84
85 base.AddRegion(scene);
86 m_assMapper = new HGAssetMapper(scene);
87 scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem;
88
89 }
90
91 #endregion
92
93 #region Event handlers
94
95 public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel)
96 {
97 string userAssetServer = string.Empty;
98 if (IsForeignUser(avatarID, out userAssetServer))
99 {
100 m_assMapper.Post(assetID, avatarID, userAssetServer);
101 }
102 }
103
104 #endregion
105
106 #region Overrides of Basic Inventory Access methods
107 ///
108 /// CapsUpdateInventoryItemAsset
109 ///
110 public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
111 {
112 UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data);
113
114 UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0);
115
116 return newAssetID;
117 }
118
119 ///
120 /// DeleteToInventory
121 ///
122 public override UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient)
123 {
124 UUID assetID = base.DeleteToInventory(action, folderID, objectGroup, remoteClient);
125
126 if (!assetID.Equals(UUID.Zero))
127 {
128 UploadInventoryItem(remoteClient.AgentId, assetID, "", 0);
129 }
130 else
131 m_log.Debug("[HGScene]: Scene.Inventory did not create asset");
132
133 return assetID;
134 }
135
136 ///
137 /// RezObject
138 ///
139 public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
140 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
141 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
142 {
143 m_log.DebugFormat("[HGScene] RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID);
144
145 //if (fromTaskID.Equals(UUID.Zero))
146 //{
147 InventoryItemBase item = new InventoryItemBase(itemID);
148 item.Owner = remoteClient.AgentId;
149 item = m_Scene.InventoryService.GetItem(item);
150 //if (item == null)
151 //{ // Fetch the item
152 // item = new InventoryItemBase();
153 // item.Owner = remoteClient.AgentId;
154 // item.ID = itemID;
155 // item = m_assMapper.Get(item, userInfo.RootFolder.ID, userInfo);
156 //}
157 string userAssetServer = string.Empty;
158 if (item != null && IsForeignUser(remoteClient.AgentId, out userAssetServer))
159 {
160 m_assMapper.Get(item.AssetID, remoteClient.AgentId, userAssetServer);
161
162 }
163 //}
164
165 // OK, we're done fetching. Pass it up to the default RezObject
166 return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
167 RezSelected, RemoveItem, fromTaskID, attachment);
168
169 }
170
171 public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
172 {
173 string userAssetServer = string.Empty;
174 if (IsForeignUser(sender, out userAssetServer))
175 m_assMapper.Get(item.AssetID, sender, userAssetServer);
176
177 if (IsForeignUser(receiver, out userAssetServer))
178 m_assMapper.Post(item.AssetID, receiver, userAssetServer);
179 }
180
181 #endregion
182
183 public bool IsForeignUser(UUID userID, out string assetServerURL)
184 {
185 assetServerURL = string.Empty;
186 UserAccount account = null;
187 if (m_Scene.UserAccountService != null)
188 account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, userID);
189
190 if (account == null) // foreign
191 {
192 ScenePresence sp = null;
193 if (m_Scene.TryGetAvatar(userID, out sp))
194 {
195 AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
196 if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
197 {
198 assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString();
199 assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true;
200 }
201 }
202 }
203
204 return false;
205 }
206 }
207}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs
new file mode 100644
index 0000000..fcb544f
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs
@@ -0,0 +1,57 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30
31using OpenSim.Framework;
32using OpenSim.Region.Framework.Scenes;
33using OpenSim.Services.Interfaces;
34using OpenMetaverse;
35
36namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
37{
38 public class HGUuidGatherer : UuidGatherer
39 {
40 protected string m_assetServerURL;
41 protected HGAssetMapper m_assetMapper;
42
43 public HGUuidGatherer(HGAssetMapper assMap, IAssetService assetCache, string assetServerURL) : base(assetCache)
44 {
45 m_assetMapper = assMap;
46 m_assetServerURL = assetServerURL;
47 }
48
49 protected override AssetBase GetAsset(UUID uuid)
50 {
51 if (string.Empty == m_assetServerURL)
52 return m_assetCache.Get(uuid.ToString());
53 else
54 return m_assetMapper.FetchAsset(m_assetServerURL, uuid);
55 }
56 }
57}
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
new file mode 100644
index 0000000..e0df288
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -0,0 +1,655 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32using System.Threading;
33
34using OpenSim.Framework;
35using OpenSim.Framework.Capabilities;
36using OpenSim.Framework.Client;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Region.Framework.Scenes.Serialization;
40using OpenSim.Services.Interfaces;
41
42using GridRegion = OpenSim.Services.Interfaces.GridRegion;
43
44using OpenMetaverse;
45using log4net;
46using Nini.Config;
47
48namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
49{
50 public class BasicInventoryAccessModule : INonSharedRegionModule, IInventoryAccessModule
51 {
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 protected bool m_Enabled = false;
55 protected Scene m_Scene;
56
57 #region INonSharedRegionModule
58
59 public Type ReplaceableInterface
60 {
61 get { return null; }
62 }
63
64 public virtual string Name
65 {
66 get { return "BasicInventoryAccessModule"; }
67 }
68
69 public virtual void Initialise(IConfigSource source)
70 {
71 IConfig moduleConfig = source.Configs["Modules"];
72 if (moduleConfig != null)
73 {
74 string name = moduleConfig.GetString("InventoryAccessModule", "");
75 if (name == Name)
76 {
77 m_Enabled = true;
78 m_log.InfoFormat("[INVENTORY ACCESS MODULE]: {0} enabled.", Name);
79 }
80 }
81 }
82
83 public virtual void PostInitialise()
84 {
85 }
86
87 public virtual void AddRegion(Scene scene)
88 {
89 if (!m_Enabled)
90 return;
91
92 m_Scene = scene;
93
94 scene.RegisterModuleInterface<IInventoryAccessModule>(this);
95 scene.EventManager.OnNewClient += OnNewClient;
96 }
97
98 protected virtual void OnNewClient(IClientAPI client)
99 {
100
101 }
102
103 public virtual void Close()
104 {
105 if (!m_Enabled)
106 return;
107 }
108
109
110 public virtual void RemoveRegion(Scene scene)
111 {
112 if (!m_Enabled)
113 return;
114 m_Scene = null;
115 }
116
117 public virtual void RegionLoaded(Scene scene)
118 {
119 if (!m_Enabled)
120 return;
121
122 }
123
124 #endregion
125
126 #region Inventory Access
127
128 /// <summary>
129 /// Capability originating call to update the asset of an item in an agent's inventory
130 /// </summary>
131 /// <param name="remoteClient"></param>
132 /// <param name="itemID"></param>
133 /// <param name="data"></param>
134 /// <returns></returns>
135 public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
136 {
137 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
138 item = m_Scene.InventoryService.GetItem(item);
139
140 if (item != null)
141 {
142 if ((InventoryType)item.InvType == InventoryType.Notecard)
143 {
144 if (!m_Scene.Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId))
145 {
146 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
147 return UUID.Zero;
148 }
149
150 remoteClient.SendAgentAlertMessage("Notecard saved", false);
151 }
152 else if ((InventoryType)item.InvType == InventoryType.LSL)
153 {
154 if (!m_Scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
155 {
156 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
157 return UUID.Zero;
158 }
159
160 remoteClient.SendAgentAlertMessage("Script saved", false);
161 }
162
163 AssetBase asset =
164 CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId.ToString());
165 item.AssetID = asset.FullID;
166 m_Scene.AssetService.Store(asset);
167
168 m_Scene.InventoryService.UpdateItem(item);
169
170 // remoteClient.SendInventoryItemCreateUpdate(item);
171 return (asset.FullID);
172 }
173 else
174 {
175 m_log.ErrorFormat(
176 "[AGENT INVENTORY]: Could not find item {0} for caps inventory update",
177 itemID);
178 }
179
180 return UUID.Zero;
181 }
182
183 /// <summary>
184 /// Delete a scene object from a scene and place in the given avatar's inventory.
185 /// Returns the UUID of the newly created asset.
186 /// </summary>
187 /// <param name="action"></param>
188 /// <param name="folderID"></param>
189 /// <param name="objectGroup"></param>
190 /// <param name="remoteClient"> </param>
191 public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
192 SceneObjectGroup objectGroup, IClientAPI remoteClient)
193 {
194 UUID assetID = UUID.Zero;
195
196 Vector3 inventoryStoredPosition = new Vector3
197 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
198 ? 250
199 : objectGroup.AbsolutePosition.X)
200 ,
201 (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
202 ? 250
203 : objectGroup.AbsolutePosition.X,
204 objectGroup.AbsolutePosition.Z);
205
206 Vector3 originalPosition = objectGroup.AbsolutePosition;
207
208 objectGroup.AbsolutePosition = inventoryStoredPosition;
209
210 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup);
211
212 objectGroup.AbsolutePosition = originalPosition;
213
214 // Get the user info of the item destination
215 //
216 UUID userID = UUID.Zero;
217
218 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy ||
219 action == DeRezAction.SaveToExistingUserInventoryItem)
220 {
221 // Take or take copy require a taker
222 // Saving changes requires a local user
223 //
224 if (remoteClient == null)
225 return UUID.Zero;
226
227 userID = remoteClient.AgentId;
228 }
229 else
230 {
231 // All returns / deletes go to the object owner
232 //
233
234 userID = objectGroup.RootPart.OwnerID;
235 }
236
237 if (userID == UUID.Zero) // Can't proceed
238 {
239 return UUID.Zero;
240 }
241
242 // If we're returning someone's item, it goes back to the
243 // owner's Lost And Found folder.
244 // Delete is treated like return in this case
245 // Deleting your own items makes them go to trash
246 //
247
248 InventoryFolderBase folder = null;
249 InventoryItemBase item = null;
250
251 if (DeRezAction.SaveToExistingUserInventoryItem == action)
252 {
253 item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID);
254 item = m_Scene.InventoryService.GetItem(item);
255
256 //item = userInfo.RootFolder.FindItem(
257 // objectGroup.RootPart.FromUserInventoryItemID);
258
259 if (null == item)
260 {
261 m_log.DebugFormat(
262 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
263 objectGroup.Name, objectGroup.UUID);
264 return UUID.Zero;
265 }
266 }
267 else
268 {
269 // Folder magic
270 //
271 if (action == DeRezAction.Delete)
272 {
273 // Deleting someone else's item
274 //
275
276
277 if (remoteClient == null ||
278 objectGroup.OwnerID != remoteClient.AgentId)
279 {
280 // Folder skeleton may not be loaded and we
281 // have to wait for the inventory to find
282 // the destination folder
283 //
284 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
285 }
286 else
287 {
288 // Assume inventory skeleton was loaded during login
289 // and all folders can be found
290 //
291 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
292 }
293 }
294 else if (action == DeRezAction.Return)
295 {
296
297 // Dump to lost + found unconditionally
298 //
299 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
300 }
301
302 if (folderID == UUID.Zero && folder == null)
303 {
304 if (action == DeRezAction.Delete)
305 {
306 // Deletes go to trash by default
307 //
308 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
309 }
310 else
311 {
312 // Catch all. Use lost & found
313 //
314
315 folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
316 }
317 }
318
319 if (folder == null) // None of the above
320 {
321 //folder = userInfo.RootFolder.FindFolder(folderID);
322 folder = new InventoryFolderBase(folderID);
323
324 if (folder == null) // Nowhere to put it
325 {
326 return UUID.Zero;
327 }
328 }
329
330 item = new InventoryItemBase();
331 item.CreatorId = objectGroup.RootPart.CreatorID.ToString();
332 item.ID = UUID.Random();
333 item.InvType = (int)InventoryType.Object;
334 item.Folder = folder.ID;
335 item.Owner = userID;
336 }
337
338 AssetBase asset = CreateAsset(
339 objectGroup.GetPartName(objectGroup.RootPart.LocalId),
340 objectGroup.GetPartDescription(objectGroup.RootPart.LocalId),
341 (sbyte)AssetType.Object,
342 Utils.StringToBytes(sceneObjectXml),
343 objectGroup.OwnerID.ToString());
344 m_Scene.AssetService.Store(asset);
345 assetID = asset.FullID;
346
347 if (DeRezAction.SaveToExistingUserInventoryItem == action)
348 {
349 item.AssetID = asset.FullID;
350 m_Scene.InventoryService.UpdateItem(item);
351 }
352 else
353 {
354 item.AssetID = asset.FullID;
355
356 if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions())
357 {
358 uint perms = objectGroup.GetEffectivePermissions();
359 uint nextPerms = (perms & 7) << 13;
360 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
361 perms &= ~(uint)PermissionMask.Copy;
362 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
363 perms &= ~(uint)PermissionMask.Transfer;
364 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
365 perms &= ~(uint)PermissionMask.Modify;
366
367 item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
368 item.CurrentPermissions = item.BasePermissions;
369 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
370 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
371 item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
372 item.CurrentPermissions |= 8; // Slam!
373 }
374 else
375 {
376 item.BasePermissions = objectGroup.GetEffectivePermissions();
377 item.CurrentPermissions = objectGroup.GetEffectivePermissions();
378 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
379 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
380 item.GroupPermissions = objectGroup.RootPart.GroupMask;
381
382 item.CurrentPermissions |= 8; // Slam!
383 }
384
385 // TODO: add the new fields (Flags, Sale info, etc)
386 item.CreationDate = Util.UnixTimeSinceEpoch();
387 item.Description = asset.Description;
388 item.Name = asset.Name;
389 item.AssetType = asset.Type;
390
391 m_Scene.InventoryService.AddItem(item);
392
393 if (remoteClient != null && item.Owner == remoteClient.AgentId)
394 {
395 remoteClient.SendInventoryItemCreateUpdate(item, 0);
396 }
397 else
398 {
399 ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner);
400 if (notifyUser != null)
401 {
402 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
403 }
404 }
405 }
406
407 return assetID;
408 }
409
410
411 /// <summary>
412 /// Rez an object into the scene from the user's inventory
413 /// </summary>
414 /// <param name="remoteClient"></param>
415 /// <param name="itemID"></param>
416 /// <param name="RayEnd"></param>
417 /// <param name="RayStart"></param>
418 /// <param name="RayTargetID"></param>
419 /// <param name="BypassRayCast"></param>
420 /// <param name="RayEndIsIntersection"></param>
421 /// <param name="RezSelected"></param>
422 /// <param name="RemoveItem"></param>
423 /// <param name="fromTaskID"></param>
424 /// <param name="attachment"></param>
425 /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
426 public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
427 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
428 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
429 {
430 // Work out position details
431 byte bRayEndIsIntersection = (byte)0;
432
433 if (RayEndIsIntersection)
434 {
435 bRayEndIsIntersection = (byte)1;
436 }
437 else
438 {
439 bRayEndIsIntersection = (byte)0;
440 }
441
442 Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
443
444
445 Vector3 pos = m_Scene.GetNewRezLocation(
446 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
447 BypassRayCast, bRayEndIsIntersection, true, scale, false);
448
449 // Rez object
450 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
451 item = m_Scene.InventoryService.GetItem(item);
452
453 if (item != null)
454 {
455 AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString());
456
457 if (rezAsset != null)
458 {
459 UUID itemId = UUID.Zero;
460
461 // If we have permission to copy then link the rezzed object back to the user inventory
462 // item that it came from. This allows us to enable 'save object to inventory'
463 if (!m_Scene.Permissions.BypassPermissions())
464 {
465 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
466 {
467 itemId = item.ID;
468 }
469 }
470 else
471 {
472 // Brave new fullperm world
473 //
474 itemId = item.ID;
475 }
476
477 string xmlData = Utils.BytesToString(rezAsset.Data);
478 SceneObjectGroup group
479 = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData);
480
481 if (!m_Scene.Permissions.CanRezObject(
482 group.Children.Count, remoteClient.AgentId, pos)
483 && !attachment)
484 {
485 // The client operates in no fail mode. It will
486 // have already removed the item from the folder
487 // if it's no copy.
488 // Put it back if it's not an attachment
489 //
490 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
491 remoteClient.SendBulkUpdateInventory(item);
492 return null;
493 }
494
495 group.ResetIDs();
496
497 if (attachment)
498 {
499 group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom;
500 group.RootPart.IsAttachment = true;
501 }
502
503 m_Scene.AddNewSceneObject(group, true);
504
505 // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
506 // if attachment we set it's asset id so object updates can reflect that
507 // if not, we set it's position in world.
508 if (!attachment)
509 {
510 float offsetHeight = 0;
511 pos = m_Scene.GetNewRezLocation(
512 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
513 BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
514 pos.Z += offsetHeight;
515 group.AbsolutePosition = pos;
516 // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);
517
518 }
519 else
520 {
521 group.SetFromItemID(itemID);
522 }
523
524 SceneObjectPart rootPart = null;
525 try
526 {
527 rootPart = group.GetChildPart(group.UUID);
528 }
529 catch (NullReferenceException)
530 {
531 string isAttachment = "";
532
533 if (attachment)
534 isAttachment = " Object was an attachment";
535
536 m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
537 }
538
539 // Since renaming the item in the inventory does not affect the name stored
540 // in the serialization, transfer the correct name from the inventory to the
541 // object itself before we rez.
542 rootPart.Name = item.Name;
543 rootPart.Description = item.Description;
544
545 List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
546
547 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
548 if (rootPart.OwnerID != item.Owner)
549 {
550 //Need to kill the for sale here
551 rootPart.ObjectSaleType = 0;
552 rootPart.SalePrice = 10;
553
554 if (m_Scene.Permissions.PropagatePermissions())
555 {
556 if ((item.CurrentPermissions & 8) != 0)
557 {
558 foreach (SceneObjectPart part in partList)
559 {
560 part.EveryoneMask = item.EveryOnePermissions;
561 part.NextOwnerMask = item.NextPermissions;
562 part.GroupMask = 0; // DO NOT propagate here
563 }
564 }
565 group.ApplyNextOwnerPermissions();
566 }
567 }
568
569 foreach (SceneObjectPart part in partList)
570 {
571 if (part.OwnerID != item.Owner)
572 {
573 part.LastOwnerID = part.OwnerID;
574 part.OwnerID = item.Owner;
575 part.Inventory.ChangeInventoryOwner(item.Owner);
576 }
577 else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam!
578 {
579 part.EveryoneMask = item.EveryOnePermissions;
580 part.NextOwnerMask = item.NextPermissions;
581
582 part.GroupMask = 0; // DO NOT propagate here
583 }
584 }
585
586 rootPart.TrimPermissions();
587
588 if (!attachment)
589 {
590 if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
591 {
592 group.ClearPartAttachmentData();
593 }
594 }
595
596 if (!attachment)
597 {
598 // Fire on_rez
599 group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0);
600
601 rootPart.ScheduleFullUpdate();
602 }
603
604 if (!m_Scene.Permissions.BypassPermissions())
605 {
606 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
607 {
608 // If this is done on attachments, no
609 // copy ones will be lost, so avoid it
610 //
611 if (!attachment)
612 {
613 List<UUID> uuids = new List<UUID>();
614 uuids.Add(item.ID);
615 m_Scene.InventoryService.DeleteItems(item.Owner, uuids);
616 }
617 }
618 }
619
620 return rootPart.ParentGroup;
621 }
622 }
623
624 return null;
625 }
626
627 public virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
628 {
629 }
630
631 #endregion
632
633 #region Misc
634
635 /// <summary>
636 /// Create a new asset data structure.
637 /// </summary>
638 /// <param name="name"></param>
639 /// <param name="description"></param>
640 /// <param name="invType"></param>
641 /// <param name="assetType"></param>
642 /// <param name="data"></param>
643 /// <returns></returns>
644 private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data, string creatorID)
645 {
646 AssetBase asset = new AssetBase(UUID.Random(), name, assetType, creatorID);
647 asset.Description = description;
648 asset.Data = (data == null) ? new byte[1] : data;
649
650 return asset;
651 }
652
653 #endregion
654 }
655}