aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/Caps
diff options
context:
space:
mode:
authorUbitUmarov2015-09-01 11:43:07 +0100
committerUbitUmarov2015-09-01 11:43:07 +0100
commitfb78b182520fc9bb0f971afd0322029c70278ea6 (patch)
treeb4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Region/ClientStack/Linden/Caps
parentlixo (diff)
parentMantis #7713: fixed bug introduced by 1st MOSES patch. (diff)
downloadopensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.zip
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2
opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/Caps')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs182
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs136
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs1309
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs91
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs830
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs433
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs190
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs144
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs144
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs169
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs152
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs151
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs297
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs389
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs378
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs33
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs234
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs303
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs159
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs302
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs454
21 files changed, 6480 insertions, 0 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs
new file mode 100644
index 0000000..aabdb51
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/AgentPreferencesModule.cs
@@ -0,0 +1,182 @@
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.IO;
32using log4net;
33using Mono.Addins;
34using Nini.Config;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework.Console;
38using OpenSim.Framework.Servers;
39using OpenSim.Framework.Servers.HttpServer;
40using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Services.Interfaces;
43using Caps = OpenSim.Framework.Capabilities.Caps;
44using OpenSim.Capabilities.Handlers;
45
46namespace OpenSim.Region.ClientStack.LindenCaps
47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AgentPreferencesModule")]
49 public class AgentPreferencesModule : ISharedRegionModule
50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 private List<Scene> m_scenes = new List<Scene>();
54
55 public void Initialise(IConfigSource source)
56 {
57
58 }
59
60 #region Region module
61
62 public void AddRegion(Scene scene)
63 {
64 lock (m_scenes) m_scenes.Add(scene);
65 }
66
67 public void RemoveRegion(Scene scene)
68 {
69 lock (m_scenes) m_scenes.Remove(scene);
70 scene.EventManager.OnRegisterCaps -= RegisterCaps;
71 scene = null;
72 }
73
74 public void RegionLoaded(Scene scene)
75 {
76 scene.EventManager.OnRegisterCaps += delegate(UUID agentID, OpenSim.Framework.Capabilities.Caps caps)
77 {
78 RegisterCaps(agentID, caps);
79 };
80 }
81
82 public void PostInitialise() {}
83
84 public void Close() {}
85
86 public string Name { get { return "AgentPreferencesModule"; } }
87
88 public Type ReplaceableInterface
89 {
90 get { return null; }
91 }
92
93 public void RegisterCaps(UUID agent, Caps caps)
94 {
95 UUID capId = UUID.Random();
96 caps.RegisterHandler("AgentPreferences",
97 new RestStreamHandler("POST", "/CAPS/" + capId,
98 delegate(string request, string path, string param,
99 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
100 {
101 return UpdateAgentPreferences(request, path, param, agent);
102 }));
103 caps.RegisterHandler("UpdateAgentLanguage",
104 new RestStreamHandler("POST", "/CAPS/" + capId,
105 delegate(string request, string path, string param,
106 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
107 {
108 return UpdateAgentPreferences(request, path, param, agent);
109 }));
110 caps.RegisterHandler("UpdateAgentInformation",
111 new RestStreamHandler("POST", "/CAPS/" + capId,
112 delegate(string request, string path, string param,
113 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
114 {
115 return UpdateAgentPreferences(request, path, param, agent);
116 }));
117 }
118
119 public string UpdateAgentPreferences(string request, string path, string param, UUID agent)
120 {
121 OSDMap resp = new OSDMap();
122 // The viewer doesn't do much with the return value, so for now, if there is no preference service,
123 // we'll return a null llsd block for debugging purposes. This may change if someone knows what the
124 // correct server response would be here.
125 if (m_scenes[0].AgentPreferencesService == null)
126 {
127 return OSDParser.SerializeLLSDXmlString(resp);
128 }
129 m_log.DebugFormat("[AgentPrefs]: UpdateAgentPreferences for {0}", agent.ToString());
130 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
131 AgentPrefs data = m_scenes[0].AgentPreferencesService.GetAgentPreferences(agent);
132 if (data == null)
133 {
134 data = new AgentPrefs(agent);
135 }
136
137 if (req.ContainsKey("access_prefs"))
138 {
139 OSDMap accessPrefs = (OSDMap)req["access_prefs"]; // We could check with ContainsKey...
140 data.AccessPrefs = accessPrefs["max"].AsString();
141 }
142 if (req.ContainsKey("default_object_perm_masks"))
143 {
144 OSDMap permsMap = (OSDMap)req["default_object_perm_masks"];
145 data.PermEveryone = permsMap["Everyone"].AsInteger();
146 data.PermGroup = permsMap["Group"].AsInteger();
147 data.PermNextOwner = permsMap["NextOwner"].AsInteger();
148 }
149 if (req.ContainsKey("hover_height"))
150 {
151 data.HoverHeight = req["hover_height"].AsReal();
152 }
153 if (req.ContainsKey("language"))
154 {
155 data.Language = req["language"].AsString();
156 }
157 if (req.ContainsKey("language_is_public"))
158 {
159 data.LanguageIsPublic = req["language_is_public"].AsBoolean();
160 }
161 m_scenes[0].AgentPreferencesService.StoreAgentPreferences(data);
162 OSDMap respAccessPrefs = new OSDMap();
163 respAccessPrefs["max"] = data.AccessPrefs;
164 resp["access_prefs"] = respAccessPrefs;
165 OSDMap respDefaultPerms = new OSDMap();
166 respDefaultPerms["Everyone"] = data.PermEveryone;
167 respDefaultPerms["Group"] = data.PermGroup;
168 respDefaultPerms["NextOwner"] = data.PermNextOwner;
169 resp["default_object_perm_masks"] = respDefaultPerms;
170 resp["god_level"] = 0; // *TODO: Add this
171 resp["hover_height"] = data.HoverHeight;
172 resp["language"] = data.Language;
173 resp["language_is_public"] = data.LanguageIsPublic;
174
175 string response = OSDParser.SerializeLLSDXmlString(resp);
176 return response;
177 }
178
179 #endregion Region module
180 }
181}
182
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
new file mode 100644
index 0000000..bbadc55
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/AvatarPickerSearchModule.cs
@@ -0,0 +1,136 @@
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.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection;
34using System.IO;
35using System.Web;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenSim.Framework;
42using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenSim.Region.Framework.Interfaces;
45using OpenSim.Region.Framework.Scenes;
46using OpenSim.Services.Interfaces;
47using Caps = OpenSim.Framework.Capabilities.Caps;
48using OpenSim.Capabilities.Handlers;
49
50namespace OpenSim.Region.ClientStack.Linden
51{
52 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AvatarPickerSearchModule")]
53 public class AvatarPickerSearchModule : INonSharedRegionModule
54 {
55// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56
57 private Scene m_scene;
58 private IPeople m_People;
59 private bool m_Enabled = false;
60
61 private string m_URL;
62
63 #region ISharedRegionModule Members
64
65 public void Initialise(IConfigSource source)
66 {
67 IConfig config = source.Configs["ClientStack.LindenCaps"];
68 if (config == null)
69 return;
70
71 m_URL = config.GetString("Cap_AvatarPickerSearch", string.Empty);
72 // Cap doesn't exist
73 if (m_URL != string.Empty)
74 m_Enabled = true;
75 }
76
77 public void AddRegion(Scene s)
78 {
79 if (!m_Enabled)
80 return;
81
82 m_scene = s;
83 }
84
85 public void RemoveRegion(Scene s)
86 {
87 if (!m_Enabled)
88 return;
89
90 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
91 m_scene = null;
92 }
93
94 public void RegionLoaded(Scene s)
95 {
96 if (!m_Enabled)
97 return;
98
99 m_People = m_scene.RequestModuleInterface<IPeople>();
100 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
101 }
102
103 public void PostInitialise()
104 {
105 }
106
107 public void Close() { }
108
109 public string Name { get { return "AvatarPickerSearchModule"; } }
110
111 public Type ReplaceableInterface
112 {
113 get { return null; }
114 }
115
116 #endregion
117
118 public void RegisterCaps(UUID agentID, Caps caps)
119 {
120 UUID capID = UUID.Random();
121
122 if (m_URL == "localhost")
123 {
124// m_log.DebugFormat("[AVATAR PICKER SEARCH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
125 caps.RegisterHandler(
126 "AvatarPickerSearch",
127 new AvatarPickerSearchHandler("/CAPS/" + capID + "/", m_People, "AvatarPickerSearch", "Search for avatars by name"));
128 }
129 else
130 {
131 // m_log.DebugFormat("[AVATAR PICKER SEARCH]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
132 caps.RegisterHandler("AvatarPickerSearch", m_URL);
133 }
134 }
135 }
136} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
new file mode 100644
index 0000000..774202e
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -0,0 +1,1309 @@
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.IO;
32using System.Reflection;
33using System.Text;
34
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using Nini.Config;
38using log4net;
39
40using OpenSim.Framework;
41using OpenSim.Framework.Capabilities;
42using OpenSim.Region.Framework;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.Framework.Scenes.Serialization;
45using OpenSim.Framework.Servers;
46using OpenSim.Framework.Servers.HttpServer;
47using OpenSim.Framework.Client;
48using OpenSim.Services.Interfaces;
49
50using Caps = OpenSim.Framework.Capabilities.Caps;
51using OSDArray = OpenMetaverse.StructuredData.OSDArray;
52using OSDMap = OpenMetaverse.StructuredData.OSDMap;
53using PermissionMask = OpenSim.Framework.PermissionMask;
54
55namespace OpenSim.Region.ClientStack.Linden
56{
57 public delegate void UpLoadedAsset(
58 string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder,
59 byte[] data, string inventoryType, string assetType);
60
61 public delegate UUID UpdateItem(UUID itemID, byte[] data);
62
63 public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
64
65 public delegate void NewInventoryItem(UUID userID, InventoryItemBase item);
66
67 public delegate void NewAsset(AssetBase asset);
68
69 public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data);
70
71 public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
72 bool isScriptRunning, byte[] data);
73
74 public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
75 bool fetchFolders, bool fetchItems, int sortOrder, out int version);
76
77 /// <summary>
78 /// XXX Probably not a particularly nice way of allow us to get the scene presence from the scene (chiefly so that
79 /// we can popup a message on the user's client if the inventory service has permanently failed). But I didn't want
80 /// to just pass the whole Scene into CAPS.
81 /// </summary>
82 public delegate IClientAPI GetClientDelegate(UUID agentID);
83
84 public class BunchOfCaps
85 {
86 private static readonly ILog m_log =
87 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
88
89 private Scene m_Scene;
90 private Caps m_HostCapsObj;
91
92 private static readonly string m_requestPath = "0000/";
93 // private static readonly string m_mapLayerPath = "0001/";
94 private static readonly string m_newInventory = "0002/";
95 //private static readonly string m_requestTexture = "0003/";
96 private static readonly string m_notecardUpdatePath = "0004/";
97 private static readonly string m_notecardTaskUpdatePath = "0005/";
98 // private static readonly string m_fetchInventoryPath = "0006/";
99 private static readonly string m_copyFromNotecardPath = "0007/";
100 // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule.
101 private static readonly string m_getObjectPhysicsDataPath = "0101/";
102 /* 0102 - 0103 RESERVED */
103 private static readonly string m_UpdateAgentInformationPath = "0500/";
104
105 // These are callbacks which will be setup by the scene so that we can update scene data when we
106 // receive capability calls
107 public NewInventoryItem AddNewInventoryItem = null;
108 public NewAsset AddNewAsset = null;
109 public ItemUpdatedCallback ItemUpdatedCall = null;
110 public TaskScriptUpdatedCallback TaskScriptUpdatedCall = null;
111 public FetchInventoryDescendentsCAPS CAPSFetchInventoryDescendents = null;
112 public GetClientDelegate GetClient = null;
113
114 private bool m_persistBakedTextures = false;
115 private IAssetService m_assetService;
116 private bool m_dumpAssetsToFile = false;
117 private string m_regionName;
118 private int m_levelUpload = 0;
119
120 public BunchOfCaps(Scene scene, Caps caps)
121 {
122 m_Scene = scene;
123 m_HostCapsObj = caps;
124 IConfigSource config = m_Scene.Config;
125 if (config != null)
126 {
127 IConfig sconfig = config.Configs["Startup"];
128 if (sconfig != null)
129 {
130 m_levelUpload = sconfig.GetInt("LevelUpload", 0);
131 }
132
133 IConfig appearanceConfig = config.Configs["Appearance"];
134 if (appearanceConfig != null)
135 {
136 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
137 }
138 }
139
140 m_assetService = m_Scene.AssetService;
141 m_regionName = m_Scene.RegionInfo.RegionName;
142
143 RegisterHandlers();
144
145 AddNewInventoryItem = m_Scene.AddUploadedInventoryItem;
146 ItemUpdatedCall = m_Scene.CapsUpdateInventoryItemAsset;
147 TaskScriptUpdatedCall = m_Scene.CapsUpdateTaskInventoryScriptAsset;
148 GetClient = m_Scene.SceneGraph.GetControllingClient;
149 }
150
151 /// <summary>
152 /// Register a bunch of CAPS http service handlers
153 /// </summary>
154 public void RegisterHandlers()
155 {
156 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
157
158 RegisterRegionServiceHandlers(capsBase);
159 RegisterInventoryServiceHandlers(capsBase);
160 }
161
162 public void RegisterRegionServiceHandlers(string capsBase)
163 {
164 try
165 {
166 // the root of all evil
167 m_HostCapsObj.RegisterHandler(
168 "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
169
170// m_log.DebugFormat(
171// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
172
173 //m_capsHandlers["MapLayer"] =
174 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
175 // capsBase + m_mapLayerPath,
176 // GetMapLayer);
177 IRequestHandler req
178 = new RestStreamHandler(
179 "POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory, "UpdateScript", null);
180
181 m_HostCapsObj.RegisterHandler("UpdateScriptTaskInventory", req);
182 m_HostCapsObj.RegisterHandler("UpdateScriptTask", req);
183 }
184 catch (Exception e)
185 {
186 m_log.Error("[CAPS]: " + e.ToString());
187 }
188 }
189
190 public void RegisterInventoryServiceHandlers(string capsBase)
191 {
192 try
193 {
194 // I don't think this one works...
195 m_HostCapsObj.RegisterHandler(
196 "NewFileAgentInventory",
197 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDAssetUploadResponse>(
198 "POST",
199 capsBase + m_newInventory,
200 NewAgentInventoryRequest,
201 "NewFileAgentInventory",
202 null));
203
204 IRequestHandler req
205 = new RestStreamHandler(
206 "POST", capsBase + m_notecardUpdatePath, NoteCardAgentInventory, "Update*", null);
207
208 m_HostCapsObj.RegisterHandler("UpdateNotecardAgentInventory", req);
209 m_HostCapsObj.RegisterHandler("UpdateScriptAgentInventory", req);
210 m_HostCapsObj.RegisterHandler("UpdateScriptAgent", req);
211
212 IRequestHandler getObjectPhysicsDataHandler
213 = new RestStreamHandler(
214 "POST", capsBase + m_getObjectPhysicsDataPath, GetObjectPhysicsData, "GetObjectPhysicsData", null);
215 m_HostCapsObj.RegisterHandler("GetObjectPhysicsData", getObjectPhysicsDataHandler);
216
217 IRequestHandler UpdateAgentInformationHandler
218 = new RestStreamHandler(
219 "POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation, "UpdateAgentInformation", null);
220 m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler);
221
222 m_HostCapsObj.RegisterHandler(
223 "CopyInventoryFromNotecard",
224 new RestStreamHandler(
225 "POST", capsBase + m_copyFromNotecardPath, CopyInventoryFromNotecard, "CopyInventoryFromNotecard", null));
226
227 // As of RC 1.22.9 of the Linden client this is
228 // supported
229
230 //m_capsHandlers["WebFetchInventoryDescendents"] =new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryDescendentsRequest);
231
232 // justincc: I've disabled the CAPS service for now to fix problems with selecting textures, and
233 // subsequent inventory breakage, in the edit object pane (such as mantis 1085). This requires
234 // enhancements (probably filling out the folder part of the LLSD reply) to our CAPS service,
235 // but when I went on the Linden grid, the
236 // simulators I visited (version 1.21) were, surprisingly, no longer supplying this capability. Instead,
237 // the 1.19.1.4 client appeared to be happily flowing inventory data over UDP
238 //
239 // This is very probably just a temporary measure - once the CAPS service appears again on the Linden grid
240 // we will be
241 // able to get the data we need to implement the necessary part of the protocol to fix the issue above.
242 // m_capsHandlers["FetchInventoryDescendents"] =
243 // new RestStreamHandler("POST", capsBase + m_fetchInventoryPath, FetchInventoryRequest);
244
245 // m_capsHandlers["FetchInventoryDescendents"] =
246 // new LLSDStreamhandler<LLSDFetchInventoryDescendents, LLSDInventoryDescendents>("POST",
247 // capsBase + m_fetchInventory,
248 // FetchInventory));
249 // m_capsHandlers["RequestTextureDownload"] = new RestStreamHandler("POST",
250 // capsBase + m_requestTexture,
251 // RequestTexture);
252 }
253 catch (Exception e)
254 {
255 m_log.Error("[CAPS]: " + e.ToString());
256 }
257 }
258
259 /// <summary>
260 /// Construct a client response detailing all the capabilities this server can provide.
261 /// </summary>
262 /// <param name="request"></param>
263 /// <param name="path"></param>
264 /// <param name="param"></param>
265 /// <param name="httpRequest">HTTP request header object</param>
266 /// <param name="httpResponse">HTTP response header object</param>
267 /// <returns></returns>
268 public string SeedCapRequest(string request, string path, string param,
269 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
270 {
271// m_log.DebugFormat(
272// "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
273
274 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
275 {
276 m_log.WarnFormat(
277 "[CAPS]: Unauthorized CAPS client {0} from {1}",
278 m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
279
280 return string.Empty;
281 }
282
283 OSDArray capsRequested = (OSDArray)OSDParser.DeserializeLLSDXml(request);
284 List<string> validCaps = new List<string>();
285
286 foreach (OSD c in capsRequested)
287 validCaps.Add(c.AsString());
288
289 string result = LLSDHelpers.SerialiseLLSDReply(m_HostCapsObj.GetCapsDetails(true, validCaps));
290
291 //m_log.DebugFormat("[CAPS] CapsRequest {0}", result);
292
293 return result;
294 }
295
296 /// <summary>
297 /// Called by the script task update handler. Provides a URL to which the client can upload a new asset.
298 /// </summary>
299 /// <param name="request"></param>
300 /// <param name="path"></param>
301 /// <param name="param"></param>
302 /// <param name="httpRequest">HTTP request header object</param>
303 /// <param name="httpResponse">HTTP response header object</param>
304 /// <returns></returns>
305 public string ScriptTaskInventory(string request, string path, string param,
306 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
307 {
308 try
309 {
310// m_log.Debug("[CAPS]: ScriptTaskInventory Request in region: " + m_regionName);
311 //m_log.DebugFormat("[CAPS]: request: {0}, path: {1}, param: {2}", request, path, param);
312
313 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
314 LLSDTaskScriptUpdate llsdUpdateRequest = new LLSDTaskScriptUpdate();
315 LLSDHelpers.DeserialiseOSDMap(hash, llsdUpdateRequest);
316
317 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
318 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
319
320 TaskInventoryScriptUpdater uploader =
321 new TaskInventoryScriptUpdater(
322 llsdUpdateRequest.item_id,
323 llsdUpdateRequest.task_id,
324 llsdUpdateRequest.is_script_running,
325 capsBase + uploaderPath,
326 m_HostCapsObj.HttpListener,
327 m_dumpAssetsToFile);
328 uploader.OnUpLoad += TaskScriptUpdated;
329
330 m_HostCapsObj.HttpListener.AddStreamHandler(
331 new BinaryStreamHandler(
332 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "TaskInventoryScriptUpdater", null));
333
334 string protocol = "http://";
335
336 if (m_HostCapsObj.SSLCaps)
337 protocol = "https://";
338
339 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
340 uploaderPath;
341
342 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
343 uploadResponse.uploader = uploaderURL;
344 uploadResponse.state = "upload";
345
346 // m_log.InfoFormat("[CAPS]: " +
347 // "ScriptTaskInventory response: {0}",
348 // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
349
350 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
351 }
352 catch (Exception e)
353 {
354 m_log.Error("[CAPS]: " + e.ToString());
355 }
356
357 return null;
358 }
359
360 /// <summary>
361 /// Called when new asset data for an agent inventory item update has been uploaded.
362 /// </summary>
363 /// <param name="itemID">Item to update</param>
364 /// <param name="primID">Prim containing item to update</param>
365 /// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
366 /// <param name="data">New asset data</param>
367 public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors)
368 {
369 if (TaskScriptUpdatedCall != null)
370 {
371 ArrayList e = TaskScriptUpdatedCall(m_HostCapsObj.AgentID, itemID, primID, isScriptRunning, data);
372 foreach (Object item in e)
373 errors.Add(item);
374 }
375 }
376
377 /// <summary>
378 /// Called when new asset data for an agent inventory item update has been uploaded.
379 /// </summary>
380 /// <param name="itemID">Item to update</param>
381 /// <param name="data">New asset data</param>
382 /// <returns></returns>
383 public UUID ItemUpdated(UUID itemID, byte[] data)
384 {
385 if (ItemUpdatedCall != null)
386 {
387 return ItemUpdatedCall(m_HostCapsObj.AgentID, itemID, data);
388 }
389
390 return UUID.Zero;
391 }
392
393 /// <summary>
394 ///
395 /// </summary>
396 /// <param name="llsdRequest"></param>
397 /// <returns></returns>
398 public LLSDAssetUploadResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest)
399 {
400 //m_log.Debug("[CAPS]: NewAgentInventoryRequest Request is: " + llsdRequest.ToString());
401 //m_log.Debug("asset upload request via CAPS" + llsdRequest.inventory_type + " , " + llsdRequest.asset_type);
402
403 if (llsdRequest.asset_type == "texture" ||
404 llsdRequest.asset_type == "animation" ||
405 llsdRequest.asset_type == "sound")
406 {
407 ScenePresence avatar = null;
408 IClientAPI client = null;
409 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
410
411 // check user level
412 if (avatar != null)
413 {
414 client = avatar.ControllingClient;
415
416 if (avatar.UserLevel < m_levelUpload)
417 {
418 if (client != null)
419 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
420
421 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
422 errorResponse.uploader = "";
423 errorResponse.state = "error";
424 return errorResponse;
425 }
426 }
427
428 // check funds
429 if (client != null)
430 {
431 IMoneyModule mm = m_Scene.RequestModuleInterface<IMoneyModule>();
432
433 if (mm != null)
434 {
435 if (!mm.UploadCovered(client.AgentId, mm.UploadCharge))
436 {
437 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
438
439 LLSDAssetUploadResponse errorResponse = new LLSDAssetUploadResponse();
440 errorResponse.uploader = "";
441 errorResponse.state = "error";
442 return errorResponse;
443 }
444 }
445 }
446 }
447
448 string assetName = llsdRequest.name;
449 string assetDes = llsdRequest.description;
450 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
451 UUID newAsset = UUID.Random();
452 UUID newInvItem = UUID.Random();
453 UUID parentFolder = llsdRequest.folder_id;
454 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
455
456 AssetUploader uploader =
457 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
458 llsdRequest.asset_type, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
459
460 m_HostCapsObj.HttpListener.AddStreamHandler(
461 new BinaryStreamHandler(
462 "POST",
463 capsBase + uploaderPath,
464 uploader.uploaderCaps,
465 "NewAgentInventoryRequest",
466 m_HostCapsObj.AgentID.ToString()));
467
468 string protocol = "http://";
469
470 if (m_HostCapsObj.SSLCaps)
471 protocol = "https://";
472
473 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
474 uploaderPath;
475
476 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
477 uploadResponse.uploader = uploaderURL;
478 uploadResponse.state = "upload";
479 uploader.OnUpLoad += UploadCompleteHandler;
480 return uploadResponse;
481 }
482
483 /// <summary>
484 /// Convert raw uploaded data into the appropriate asset and item.
485 /// </summary>
486 /// <param name="assetID"></param>
487 /// <param name="inventoryItem"></param>
488 /// <param name="data"></param>
489 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
490 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
491 string assetType)
492 {
493 m_log.DebugFormat(
494 "[BUNCH OF CAPS]: Uploaded asset {0} for inventory item {1}, inv type {2}, asset type {3}",
495 assetID, inventoryItem, inventoryType, assetType);
496
497 sbyte assType = 0;
498 sbyte inType = 0;
499
500 if (inventoryType == "sound")
501 {
502 inType = (sbyte)InventoryType.Sound;
503 assType = (sbyte)AssetType.Sound;
504 }
505 else if (inventoryType == "snapshot")
506 {
507 inType = (sbyte)InventoryType.Snapshot;
508 }
509 else if (inventoryType == "animation")
510 {
511 inType = (sbyte)InventoryType.Animation;
512 assType = (sbyte)AssetType.Animation;
513 }
514 else if (inventoryType == "wearable")
515 {
516 inType = (sbyte)InventoryType.Wearable;
517 switch (assetType)
518 {
519 case "bodypart":
520 assType = (sbyte)AssetType.Bodypart;
521 break;
522 case "clothing":
523 assType = (sbyte)AssetType.Clothing;
524 break;
525 }
526 }
527 else if (inventoryType == "object")
528 {
529 inType = (sbyte)InventoryType.Object;
530 assType = (sbyte)AssetType.Object;
531
532 List<Vector3> positions = new List<Vector3>();
533 List<Quaternion> rotations = new List<Quaternion>();
534 OSDMap request = (OSDMap)OSDParser.DeserializeLLSDXml(data);
535 OSDArray instance_list = (OSDArray)request["instance_list"];
536 OSDArray mesh_list = (OSDArray)request["mesh_list"];
537 OSDArray texture_list = (OSDArray)request["texture_list"];
538 SceneObjectGroup grp = null;
539
540 InventoryFolderBase textureUploadFolder = null;
541
542 List<InventoryFolderBase> foldersToUpdate = new List<InventoryFolderBase>();
543 List<InventoryItemBase> itemsToUpdate = new List<InventoryItemBase>();
544 IClientInventory clientInv = null;
545
546 if (texture_list.Count > 0)
547 {
548 ScenePresence avatar = null;
549 m_Scene.TryGetScenePresence(m_HostCapsObj.AgentID, out avatar);
550
551 if (avatar != null)
552 {
553 IClientCore core = (IClientCore)avatar.ControllingClient;
554
555 if (core.TryGet<IClientInventory>(out clientInv))
556 {
557 var systemTextureFolder = m_Scene.InventoryService.GetFolderForType(m_HostCapsObj.AgentID, FolderType.Texture);
558 textureUploadFolder = new InventoryFolderBase(UUID.Random(), assetName, m_HostCapsObj.AgentID, (short)FolderType.None, systemTextureFolder.ID, 1);
559 if (m_Scene.InventoryService.AddFolder(textureUploadFolder))
560 {
561 foldersToUpdate.Add(textureUploadFolder);
562
563 m_log.DebugFormat(
564 "[BUNCH OF CAPS]: Created new folder '{0}' ({1}) for textures uploaded with mesh object {2}",
565 textureUploadFolder.Name, textureUploadFolder.ID, assetName);
566 }
567 else
568 {
569 textureUploadFolder = null;
570 }
571 }
572 }
573 }
574
575 List<UUID> textures = new List<UUID>();
576 for (int i = 0; i < texture_list.Count; i++)
577 {
578 AssetBase textureAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Texture, "");
579 textureAsset.Data = texture_list[i].AsBinary();
580 m_assetService.Store(textureAsset);
581 textures.Add(textureAsset.FullID);
582
583 if (textureUploadFolder != null)
584 {
585 InventoryItemBase textureItem = new InventoryItemBase();
586 textureItem.Owner = m_HostCapsObj.AgentID;
587 textureItem.CreatorId = m_HostCapsObj.AgentID.ToString();
588 textureItem.CreatorData = String.Empty;
589 textureItem.ID = UUID.Random();
590 textureItem.AssetID = textureAsset.FullID;
591 textureItem.Description = assetDescription;
592 textureItem.Name = assetName + " - Texture " + (i + 1).ToString();
593 textureItem.AssetType = (int)AssetType.Texture;
594 textureItem.InvType = (int)InventoryType.Texture;
595 textureItem.Folder = textureUploadFolder.ID;
596 textureItem.CurrentPermissions
597 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
598 textureItem.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
599 textureItem.EveryOnePermissions = 0;
600 textureItem.NextPermissions = (uint)PermissionMask.All;
601 textureItem.CreationDate = Util.UnixTimeSinceEpoch();
602 m_Scene.InventoryService.AddItem(textureItem);
603 itemsToUpdate.Add(textureItem);
604
605 m_log.DebugFormat(
606 "[BUNCH OF CAPS]: Created new inventory item '{0}' ({1}) for texture uploaded with mesh object {2}",
607 textureItem.Name, textureItem.ID, assetName);
608 }
609 }
610
611 if (clientInv != null && (foldersToUpdate.Count > 0 || itemsToUpdate.Count > 0))
612 {
613 clientInv.SendBulkUpdateInventory(foldersToUpdate.ToArray(), itemsToUpdate.ToArray());
614 }
615
616 for (int i = 0; i < mesh_list.Count; i++)
617 {
618 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
619
620 Primitive.TextureEntry textureEntry
621 = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE);
622 OSDMap inner_instance_list = (OSDMap)instance_list[i];
623
624 OSDArray face_list = (OSDArray)inner_instance_list["face_list"];
625 for (uint face = 0; face < face_list.Count; face++)
626 {
627 OSDMap faceMap = (OSDMap)face_list[(int)face];
628 Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face);
629 if(faceMap.ContainsKey("fullbright"))
630 f.Fullbright = faceMap["fullbright"].AsBoolean();
631 if (faceMap.ContainsKey ("diffuse_color"))
632 f.RGBA = faceMap["diffuse_color"].AsColor4();
633
634 int textureNum = faceMap["image"].AsInteger();
635 float imagerot = faceMap["imagerot"].AsInteger();
636 float offsets = (float)faceMap["offsets"].AsReal();
637 float offsett = (float)faceMap["offsett"].AsReal();
638 float scales = (float)faceMap["scales"].AsReal();
639 float scalet = (float)faceMap["scalet"].AsReal();
640
641 if(imagerot != 0)
642 f.Rotation = imagerot;
643
644 if(offsets != 0)
645 f.OffsetU = offsets;
646
647 if (offsett != 0)
648 f.OffsetV = offsett;
649
650 if (scales != 0)
651 f.RepeatU = scales;
652
653 if (scalet != 0)
654 f.RepeatV = scalet;
655
656 if (textures.Count > textureNum)
657 f.TextureID = textures[textureNum];
658 else
659 f.TextureID = Primitive.TextureEntry.WHITE_TEXTURE;
660
661 textureEntry.FaceTextures[face] = f;
662 }
663
664 pbs.TextureEntry = textureEntry.GetBytes();
665
666 AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, (sbyte)AssetType.Mesh, "");
667 meshAsset.Data = mesh_list[i].AsBinary();
668 m_assetService.Store(meshAsset);
669
670 pbs.SculptEntry = true;
671 pbs.SculptTexture = meshAsset.FullID;
672 pbs.SculptType = (byte)SculptType.Mesh;
673 pbs.SculptData = meshAsset.Data;
674
675 Vector3 position = inner_instance_list["position"].AsVector3();
676 Vector3 scale = inner_instance_list["scale"].AsVector3();
677 Quaternion rotation = inner_instance_list["rotation"].AsQuaternion();
678
679// no longer used - begin ------------------------
680// int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger();
681// int material = inner_instance_list["material"].AsInteger();
682// int mesh = inner_instance_list["mesh"].AsInteger();
683
684// OSDMap permissions = (OSDMap)inner_instance_list["permissions"];
685// int base_mask = permissions["base_mask"].AsInteger();
686// int everyone_mask = permissions["everyone_mask"].AsInteger();
687// UUID creator_id = permissions["creator_id"].AsUUID();
688// UUID group_id = permissions["group_id"].AsUUID();
689// int group_mask = permissions["group_mask"].AsInteger();
690// bool is_owner_group = permissions["is_owner_group"].AsBoolean();
691// UUID last_owner_id = permissions["last_owner_id"].AsUUID();
692// int next_owner_mask = permissions["next_owner_mask"].AsInteger();
693// UUID owner_id = permissions["owner_id"].AsUUID();
694// int owner_mask = permissions["owner_mask"].AsInteger();
695// no longer used - end ------------------------
696
697 UUID owner_id = m_HostCapsObj.AgentID;
698
699 SceneObjectPart prim
700 = new SceneObjectPart(owner_id, pbs, position, Quaternion.Identity, Vector3.Zero);
701
702 prim.Scale = scale;
703 //prim.OffsetPosition = position;
704 rotations.Add(rotation);
705 positions.Add(position);
706 prim.UUID = UUID.Random();
707 prim.CreatorID = owner_id;
708 prim.OwnerID = owner_id;
709 prim.GroupID = UUID.Zero;
710 prim.LastOwnerID = prim.OwnerID;
711 prim.CreationDate = Util.UnixTimeSinceEpoch();
712 prim.Name = assetName;
713 prim.Description = "";
714
715// prim.BaseMask = (uint)base_mask;
716// prim.EveryoneMask = (uint)everyone_mask;
717// prim.GroupMask = (uint)group_mask;
718// prim.NextOwnerMask = (uint)next_owner_mask;
719// prim.OwnerMask = (uint)owner_mask;
720
721 if (grp == null)
722 grp = new SceneObjectGroup(prim);
723 else
724 grp.AddPart(prim);
725 }
726
727 Vector3 rootPos = positions[0];
728
729 if (grp.Parts.Length > 1)
730 {
731 // Fix first link number
732 grp.RootPart.LinkNum++;
733
734 Quaternion rootRotConj = Quaternion.Conjugate(rotations[0]);
735 Quaternion tmprot;
736 Vector3 offset;
737
738 // fix children rotations and positions
739 for (int i = 1; i < rotations.Count; i++)
740 {
741 tmprot = rotations[i];
742 tmprot = rootRotConj * tmprot;
743
744 grp.Parts[i].RotationOffset = tmprot;
745
746 offset = positions[i] - rootPos;
747
748 offset *= rootRotConj;
749 grp.Parts[i].OffsetPosition = offset;
750 }
751
752 grp.AbsolutePosition = rootPos;
753 grp.UpdateGroupRotationR(rotations[0]);
754 }
755 else
756 {
757 grp.AbsolutePosition = rootPos;
758 grp.UpdateGroupRotationR(rotations[0]);
759 }
760
761 data = ASCIIEncoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(grp));
762 }
763
764 AssetBase asset;
765 asset = new AssetBase(assetID, assetName, assType, m_HostCapsObj.AgentID.ToString());
766 asset.Data = data;
767 if (AddNewAsset != null)
768 AddNewAsset(asset);
769 else if (m_assetService != null)
770 m_assetService.Store(asset);
771
772 InventoryItemBase item = new InventoryItemBase();
773 item.Owner = m_HostCapsObj.AgentID;
774 item.CreatorId = m_HostCapsObj.AgentID.ToString();
775 item.CreatorData = String.Empty;
776 item.ID = inventoryItem;
777 item.AssetID = asset.FullID;
778 item.Description = assetDescription;
779 item.Name = assetName;
780 item.AssetType = assType;
781 item.InvType = inType;
782 item.Folder = parentFolder;
783
784 // If we set PermissionMask.All then when we rez the item the next permissions will replace the current
785 // (owner) permissions. This becomes a problem if next permissions are changed.
786 item.CurrentPermissions
787 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Export);
788
789 item.BasePermissions = (uint)PermissionMask.All | (uint)PermissionMask.Export;
790 item.EveryOnePermissions = 0;
791 item.NextPermissions = (uint)PermissionMask.All;
792 item.CreationDate = Util.UnixTimeSinceEpoch();
793
794 if (AddNewInventoryItem != null)
795 {
796 AddNewInventoryItem(m_HostCapsObj.AgentID, item);
797 }
798 }
799
800 /// <summary>
801 ///
802 /// </summary>
803 /// <param name="mapReq"></param>
804 /// <returns></returns>
805 public LLSDMapLayerResponse GetMapLayer(LLSDMapRequest mapReq)
806 {
807 m_log.Debug("[CAPS]: MapLayer Request in region: " + m_regionName);
808 LLSDMapLayerResponse mapResponse = new LLSDMapLayerResponse();
809 mapResponse.LayerData.Array.Add(GetOSDMapLayerResponse());
810 return mapResponse;
811 }
812
813 /// <summary>
814 ///
815 /// </summary>
816 /// <returns></returns>
817 protected static OSDMapLayer GetOSDMapLayerResponse()
818 {
819 OSDMapLayer mapLayer = new OSDMapLayer();
820 mapLayer.Right = 5000;
821 mapLayer.Top = 5000;
822 mapLayer.ImageID = new UUID("00000000-0000-1111-9999-000000000006");
823
824 return mapLayer;
825 }
826
827 /// <summary>
828 ///
829 /// </summary>
830 /// <param name="request"></param>
831 /// <param name="path"></param>
832 /// <param name="param"></param>
833 /// <returns></returns>
834 public string RequestTexture(string request, string path, string param)
835 {
836 m_log.Debug("texture request " + request);
837 // Needs implementing (added to remove compiler warning)
838 return String.Empty;
839 }
840
841
842 /// <summary>
843 /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset.
844 /// </summary>
845 /// <param name="request"></param>
846 /// <param name="path"></param>
847 /// <param name="param"></param>
848 /// <returns></returns>
849 public string NoteCardAgentInventory(string request, string path, string param,
850 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
851 {
852 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request in region: " + m_regionName + "\n" + request);
853 //m_log.Debug("[CAPS]: NoteCardAgentInventory Request is: " + request);
854
855 //OpenMetaverse.StructuredData.OSDMap hash = (OpenMetaverse.StructuredData.OSDMap)OpenMetaverse.StructuredData.LLSDParser.DeserializeBinary(Utils.StringToBytes(request));
856 Hashtable hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
857 LLSDItemUpdate llsdRequest = new LLSDItemUpdate();
858 LLSDHelpers.DeserialiseOSDMap(hash, llsdRequest);
859
860 string capsBase = "/CAPS/" + m_HostCapsObj.CapsObjectPath;
861 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
862
863 ItemUpdater uploader =
864 new ItemUpdater(llsdRequest.item_id, capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_dumpAssetsToFile);
865 uploader.OnUpLoad += ItemUpdated;
866
867 m_HostCapsObj.HttpListener.AddStreamHandler(
868 new BinaryStreamHandler(
869 "POST", capsBase + uploaderPath, uploader.uploaderCaps, "NoteCardAgentInventory", null));
870
871 string protocol = "http://";
872
873 if (m_HostCapsObj.SSLCaps)
874 protocol = "https://";
875
876 string uploaderURL = protocol + m_HostCapsObj.HostName + ":" + m_HostCapsObj.Port.ToString() + capsBase +
877 uploaderPath;
878
879 LLSDAssetUploadResponse uploadResponse = new LLSDAssetUploadResponse();
880 uploadResponse.uploader = uploaderURL;
881 uploadResponse.state = "upload";
882
883 // m_log.InfoFormat("[CAPS]: " +
884 // "NoteCardAgentInventory response: {0}",
885 // LLSDHelpers.SerialiseLLSDReply(uploadResponse)));
886
887 return LLSDHelpers.SerialiseLLSDReply(uploadResponse);
888 }
889
890 /// <summary>
891 /// Called by the CopyInventoryFromNotecard caps handler.
892 /// </summary>
893 /// <param name="request"></param>
894 /// <param name="path"></param>
895 /// <param name="param"></param>
896 public string CopyInventoryFromNotecard(string request, string path, string param,
897 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
898 {
899 Hashtable response = new Hashtable();
900 response["int_response_code"] = 404;
901 response["content_type"] = "text/plain";
902 response["keepalive"] = false;
903 response["str_response_string"] = "";
904
905 try
906 {
907 OSDMap content = (OSDMap)OSDParser.DeserializeLLSDXml(request);
908 UUID objectID = content["object-id"].AsUUID();
909 UUID notecardID = content["notecard-id"].AsUUID();
910 UUID folderID = content["folder-id"].AsUUID();
911 UUID itemID = content["item-id"].AsUUID();
912
913 // m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, FolderID:{0}, ItemID:{1}, NotecardID:{2}, ObjectID:{3}", folderID, itemID, notecardID, objectID);
914
915 if (objectID != UUID.Zero)
916 {
917 SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
918 if (part != null)
919 {
920// TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
921 if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
922 {
923 return LLSDHelpers.SerialiseLLSDReply(response);
924 }
925 }
926 }
927
928 InventoryItemBase item = null;
929 InventoryItemBase copyItem = null;
930 IClientAPI client = null;
931
932 m_Scene.TryGetClient(m_HostCapsObj.AgentID, out client);
933 item = m_Scene.InventoryService.GetItem(new InventoryItemBase(itemID));
934 if (item != null)
935 {
936 string message;
937 copyItem = m_Scene.GiveInventoryItem(m_HostCapsObj.AgentID, item.Owner, itemID, folderID, out message);
938 if (client != null)
939 {
940 if (copyItem != null)
941 {
942 m_log.InfoFormat("[CAPS]: CopyInventoryFromNotecard, ItemID:{0}, FolderID:{1}", copyItem.ID, copyItem.Folder);
943 client.SendBulkUpdateInventory(copyItem);
944 }
945 else
946 {
947 client.SendAgentAlertMessage(message, false);
948 }
949 }
950 }
951 else
952 {
953 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard - Failed to retrieve item {0} from notecard {1}", itemID, notecardID);
954 if (client != null)
955 client.SendAgentAlertMessage("Failed to retrieve item", false);
956 }
957 }
958 catch (Exception e)
959 {
960 m_log.ErrorFormat("[CAPS]: CopyInventoryFromNotecard : {0}", e.ToString());
961 }
962
963 response["int_response_code"] = 200;
964 return LLSDHelpers.SerialiseLLSDReply(response);
965 }
966
967 public string GetObjectPhysicsData(string request, string path,
968 string param, IOSHttpRequest httpRequest,
969 IOSHttpResponse httpResponse)
970 {
971 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
972 OSDMap resp = new OSDMap();
973 OSDArray object_ids = (OSDArray)req["object_ids"];
974
975 for (int i = 0 ; i < object_ids.Count ; i++)
976 {
977 UUID uuid = object_ids[i].AsUUID();
978
979 SceneObjectPart obj = m_Scene.GetSceneObjectPart(uuid);
980 if (obj != null)
981 {
982 OSDMap object_data = new OSDMap();
983
984 object_data["PhysicsShapeType"] = obj.PhysicsShapeType;
985 object_data["Density"] = obj.Density;
986 object_data["Friction"] = obj.Friction;
987 object_data["Restitution"] = obj.Restitution;
988 object_data["GravityMultiplier"] = obj.GravityModifier;
989
990 resp[uuid.ToString()] = object_data;
991 }
992 }
993
994 string response = OSDParser.SerializeLLSDXmlString(resp);
995 return response;
996 }
997
998 public string UpdateAgentInformation(string request, string path,
999 string param, IOSHttpRequest httpRequest,
1000 IOSHttpResponse httpResponse)
1001 {
1002 OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
1003 OSDMap accessPrefs = (OSDMap)req["access_prefs"];
1004 string desiredMaturity = accessPrefs["max"];
1005
1006 OSDMap resp = new OSDMap();
1007 OSDMap respAccessPrefs = new OSDMap();
1008 respAccessPrefs["max"] = desiredMaturity; // echoing the maturity back means success
1009 resp["access_prefs"] = respAccessPrefs;
1010
1011 string response = OSDParser.SerializeLLSDXmlString(resp);
1012 return response;
1013 }
1014 }
1015
1016 public class AssetUploader
1017 {
1018 public event UpLoadedAsset OnUpLoad;
1019 private UpLoadedAsset handlerUpLoad = null;
1020
1021 private string uploaderPath = String.Empty;
1022 private UUID newAssetID;
1023 private UUID inventoryItemID;
1024 private UUID parentFolder;
1025 private IHttpServer httpListener;
1026 private bool m_dumpAssetsToFile;
1027 private string m_assetName = String.Empty;
1028 private string m_assetDes = String.Empty;
1029
1030 private string m_invType = String.Empty;
1031 private string m_assetType = String.Empty;
1032
1033 public AssetUploader(string assetName, string description, UUID assetID, UUID inventoryItem,
1034 UUID parentFolderID, string invType, string assetType, string path,
1035 IHttpServer httpServer, bool dumpAssetsToFile)
1036 {
1037 m_assetName = assetName;
1038 m_assetDes = description;
1039 newAssetID = assetID;
1040 inventoryItemID = inventoryItem;
1041 uploaderPath = path;
1042 httpListener = httpServer;
1043 parentFolder = parentFolderID;
1044 m_assetType = assetType;
1045 m_invType = invType;
1046 m_dumpAssetsToFile = dumpAssetsToFile;
1047 }
1048
1049 /// <summary>
1050 /// Handle raw asset upload data via the capability.
1051 /// </summary>
1052 /// <param name="data"></param>
1053 /// <param name="path"></param>
1054 /// <param name="param"></param>
1055 /// <returns></returns>
1056 public string uploaderCaps(byte[] data, string path, string param)
1057 {
1058 UUID inv = inventoryItemID;
1059 string res = String.Empty;
1060 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1061 uploadComplete.new_asset = newAssetID.ToString();
1062 uploadComplete.new_inventory_item = inv;
1063 uploadComplete.state = "complete";
1064
1065 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1066
1067 httpListener.RemoveStreamHandler("POST", uploaderPath);
1068
1069 // TODO: probably make this a better set of extensions here
1070 string extension = ".jp2";
1071 if (m_invType != "image")
1072 {
1073 extension = ".dat";
1074 }
1075
1076 if (m_dumpAssetsToFile)
1077 {
1078 SaveAssetToFile(m_assetName + extension, data);
1079 }
1080 handlerUpLoad = OnUpLoad;
1081 if (handlerUpLoad != null)
1082 {
1083 handlerUpLoad(m_assetName, m_assetDes, newAssetID, inv, parentFolder, data, m_invType, m_assetType);
1084 }
1085
1086 return res;
1087 }
1088
1089 ///Left this in and commented in case there are unforseen issues
1090 //private void SaveAssetToFile(string filename, byte[] data)
1091 //{
1092 // FileStream fs = File.Create(filename);
1093 // BinaryWriter bw = new BinaryWriter(fs);
1094 // bw.Write(data);
1095 // bw.Close();
1096 // fs.Close();
1097 //}
1098
1099 private static void SaveAssetToFile(string filename, byte[] data)
1100 {
1101 string assetPath = "UserAssets";
1102 if (!Directory.Exists(assetPath))
1103 {
1104 Directory.CreateDirectory(assetPath);
1105 }
1106 FileStream fs = File.Create(Path.Combine(assetPath, Util.safeFileName(filename)));
1107 BinaryWriter bw = new BinaryWriter(fs);
1108 bw.Write(data);
1109 bw.Close();
1110 fs.Close();
1111 }
1112 }
1113
1114 /// <summary>
1115 /// This class is a callback invoked when a client sends asset data to
1116 /// an agent inventory notecard update url
1117 /// </summary>
1118 public class ItemUpdater
1119 {
1120 public event UpdateItem OnUpLoad;
1121
1122 private UpdateItem handlerUpdateItem = null;
1123
1124 private string uploaderPath = String.Empty;
1125 private UUID inventoryItemID;
1126 private IHttpServer httpListener;
1127 private bool m_dumpAssetToFile;
1128
1129 public ItemUpdater(UUID inventoryItem, string path, IHttpServer httpServer, bool dumpAssetToFile)
1130 {
1131 m_dumpAssetToFile = dumpAssetToFile;
1132
1133 inventoryItemID = inventoryItem;
1134 uploaderPath = path;
1135 httpListener = httpServer;
1136 }
1137
1138 /// <summary>
1139 /// Handle raw uploaded asset data.
1140 /// </summary>
1141 /// <param name="data"></param>
1142 /// <param name="path"></param>
1143 /// <param name="param"></param>
1144 /// <returns></returns>
1145 public string uploaderCaps(byte[] data, string path, string param)
1146 {
1147 UUID inv = inventoryItemID;
1148 string res = String.Empty;
1149 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
1150 UUID assetID = UUID.Zero;
1151 handlerUpdateItem = OnUpLoad;
1152 if (handlerUpdateItem != null)
1153 {
1154 assetID = handlerUpdateItem(inv, data);
1155 }
1156
1157 uploadComplete.new_asset = assetID.ToString();
1158 uploadComplete.new_inventory_item = inv;
1159 uploadComplete.state = "complete";
1160
1161 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1162
1163 httpListener.RemoveStreamHandler("POST", uploaderPath);
1164
1165 if (m_dumpAssetToFile)
1166 {
1167 SaveAssetToFile("updateditem" + Util.RandomClass.Next(1, 1000) + ".dat", data);
1168 }
1169
1170 return res;
1171 }
1172
1173 ///Left this in and commented in case there are unforseen issues
1174 //private void SaveAssetToFile(string filename, byte[] data)
1175 //{
1176 // FileStream fs = File.Create(filename);
1177 // BinaryWriter bw = new BinaryWriter(fs);
1178 // bw.Write(data);
1179 // bw.Close();
1180 // fs.Close();
1181 //}
1182
1183 private static void SaveAssetToFile(string filename, byte[] data)
1184 {
1185 string assetPath = "UserAssets";
1186 if (!Directory.Exists(assetPath))
1187 {
1188 Directory.CreateDirectory(assetPath);
1189 }
1190 FileStream fs = File.Create(Path.Combine(assetPath, filename));
1191 BinaryWriter bw = new BinaryWriter(fs);
1192 bw.Write(data);
1193 bw.Close();
1194 fs.Close();
1195 }
1196 }
1197
1198 /// <summary>
1199 /// This class is a callback invoked when a client sends asset data to
1200 /// a task inventory script update url
1201 /// </summary>
1202 public class TaskInventoryScriptUpdater
1203 {
1204 private static readonly ILog m_log =
1205 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
1206
1207 public event UpdateTaskScript OnUpLoad;
1208
1209 private UpdateTaskScript handlerUpdateTaskScript = null;
1210
1211 private string uploaderPath = String.Empty;
1212 private UUID inventoryItemID;
1213 private UUID primID;
1214 private bool isScriptRunning;
1215 private IHttpServer httpListener;
1216 private bool m_dumpAssetToFile;
1217
1218 public TaskInventoryScriptUpdater(UUID inventoryItemID, UUID primID, int isScriptRunning,
1219 string path, IHttpServer httpServer, bool dumpAssetToFile)
1220 {
1221 m_dumpAssetToFile = dumpAssetToFile;
1222
1223 this.inventoryItemID = inventoryItemID;
1224 this.primID = primID;
1225
1226 // This comes in over the packet as an integer, but actually appears to be treated as a bool
1227 this.isScriptRunning = (0 == isScriptRunning ? false : true);
1228
1229 uploaderPath = path;
1230 httpListener = httpServer;
1231 }
1232
1233 /// <summary>
1234 ///
1235 /// </summary>
1236 /// <param name="data"></param>
1237 /// <param name="path"></param>
1238 /// <param name="param"></param>
1239 /// <returns></returns>
1240 public string uploaderCaps(byte[] data, string path, string param)
1241 {
1242 try
1243 {
1244 // m_log.InfoFormat("[CAPS]: " +
1245 // "TaskInventoryScriptUpdater received data: {0}, path: {1}, param: {2}",
1246 // data, path, param));
1247
1248 string res = String.Empty;
1249 LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete();
1250
1251 ArrayList errors = new ArrayList();
1252 handlerUpdateTaskScript = OnUpLoad;
1253 if (handlerUpdateTaskScript != null)
1254 {
1255 handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors);
1256 }
1257
1258 uploadComplete.new_asset = inventoryItemID;
1259 uploadComplete.compiled = errors.Count > 0 ? false : true;
1260 uploadComplete.state = "complete";
1261 uploadComplete.errors = new OpenSim.Framework.Capabilities.OSDArray();
1262 uploadComplete.errors.Array = errors;
1263
1264 res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
1265
1266 httpListener.RemoveStreamHandler("POST", uploaderPath);
1267
1268 if (m_dumpAssetToFile)
1269 {
1270 SaveAssetToFile("updatedtaskscript" + Util.RandomClass.Next(1, 1000) + ".dat", data);
1271 }
1272
1273 // m_log.InfoFormat("[CAPS]: TaskInventoryScriptUpdater.uploaderCaps res: {0}", res);
1274
1275 return res;
1276 }
1277 catch (Exception e)
1278 {
1279 m_log.Error("[CAPS]: " + e.ToString());
1280 }
1281
1282 // XXX Maybe this should be some meaningful error packet
1283 return null;
1284 }
1285
1286 ///Left this in and commented in case there are unforseen issues
1287 //private void SaveAssetToFile(string filename, byte[] data)
1288 //{
1289 // FileStream fs = File.Create(filename);
1290 // BinaryWriter bw = new BinaryWriter(fs);
1291 // bw.Write(data);
1292 // bw.Close();
1293 // fs.Close();
1294 //}
1295 private static void SaveAssetToFile(string filename, byte[] data)
1296 {
1297 string assetPath = "UserAssets";
1298 if (!Directory.Exists(assetPath))
1299 {
1300 Directory.CreateDirectory(assetPath);
1301 }
1302 FileStream fs = File.Create(Path.Combine(assetPath, filename));
1303 BinaryWriter bw = new BinaryWriter(fs);
1304 bw.Write(data);
1305 bw.Close();
1306 fs.Close();
1307 }
1308 }
1309}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
new file mode 100644
index 0000000..c241075
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCapsModule.cs
@@ -0,0 +1,91 @@
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 log4net;
33using Nini.Config;
34using OpenMetaverse;
35using Mono.Addins;
36
37using OpenSim.Framework;
38using OpenSim.Region.Framework;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using Caps = OpenSim.Framework.Capabilities.Caps;
42
43[assembly: Addin("LindenCaps", OpenSim.VersionInfo.VersionNumber)]
44[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
45namespace OpenSim.Region.ClientStack.Linden
46{
47
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BunchOfCapsModule")]
49 public class BunchOfCapsModule : INonSharedRegionModule
50 {
51// private static readonly ILog m_log =
52// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private Scene m_Scene;
55
56 #region INonSharedRegionModule
57
58 public string Name { get { return "BunchOfCapsModule"; } }
59
60 public Type ReplaceableInterface { get { return null; } }
61
62 public void Initialise(IConfigSource source)
63 {
64 }
65
66 public void Close() { }
67
68 public void AddRegion(Scene scene)
69 {
70 m_Scene = scene;
71 m_Scene.EventManager.OnRegisterCaps += OnRegisterCaps;
72 }
73
74 public void RemoveRegion(Scene scene)
75 {
76 }
77
78 public void RegionLoaded(Scene scene)
79 {
80 }
81
82 public void PostInitialise() { }
83 #endregion
84
85 private void OnRegisterCaps(UUID agentID, Caps caps)
86 {
87 new BunchOfCaps(m_Scene, caps);
88 }
89
90 }
91}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
new file mode 100644
index 0000000..9b9f6a7
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -0,0 +1,830 @@
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 System.Threading;
34using log4net;
35using Nini.Config;
36using Mono.Addins;
37using OpenMetaverse;
38using OpenMetaverse.Messages.Linden;
39using OpenMetaverse.Packets;
40using OpenMetaverse.StructuredData;
41using OpenSim.Framework;
42using OpenSim.Framework.Console;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using BlockingLLSDQueue = OpenSim.Framework.BlockingQueue<OpenMetaverse.StructuredData.OSD>;
48using Caps=OpenSim.Framework.Capabilities.Caps;
49
50namespace OpenSim.Region.ClientStack.Linden
51{
52 public struct QueueItem
53 {
54 public int id;
55 public OSDMap body;
56 }
57
58 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EventQueueGetModule")]
59 public class EventQueueGetModule : IEventQueue, INonSharedRegionModule
60 {
61 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62 private static string LogHeader = "[EVENT QUEUE GET MODULE]";
63
64 /// <value>
65 /// Debug level.
66 /// </value>
67 public int DebugLevel { get; set; }
68
69 // Viewer post requests timeout in 60 secs
70 // https://bitbucket.org/lindenlab/viewer-release/src/421c20423df93d650cc305dc115922bb30040999/indra/llmessage/llhttpclient.cpp?at=default#cl-44
71 //
72 private const int VIEWER_TIMEOUT = 60 * 1000;
73 // Just to be safe, we work on a 10 sec shorter cycle
74 private const int SERVER_EQ_TIME_NO_EVENTS = VIEWER_TIMEOUT - (10 * 1000);
75
76 protected Scene m_scene;
77
78 private Dictionary<UUID, int> m_ids = new Dictionary<UUID, int>();
79
80 private Dictionary<UUID, Queue<OSD>> queues = new Dictionary<UUID, Queue<OSD>>();
81 private Dictionary<UUID, UUID> m_QueueUUIDAvatarMapping = new Dictionary<UUID, UUID>();
82 private Dictionary<UUID, UUID> m_AvatarQueueUUIDMapping = new Dictionary<UUID, UUID>();
83
84 #region INonSharedRegionModule methods
85 public virtual void Initialise(IConfigSource config)
86 {
87 }
88
89 public void AddRegion(Scene scene)
90 {
91 m_scene = scene;
92 scene.RegisterModuleInterface<IEventQueue>(this);
93
94 scene.EventManager.OnClientClosed += ClientClosed;
95 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
96
97 MainConsole.Instance.Commands.AddCommand(
98 "Debug",
99 false,
100 "debug eq",
101 "debug eq [0|1|2]",
102 "Turn on event queue debugging\n"
103 + " <= 0 - turns off all event queue logging\n"
104 + " >= 1 - turns on event queue setup and outgoing event logging\n"
105 + " >= 2 - turns on poll notification",
106 HandleDebugEq);
107
108 MainConsole.Instance.Commands.AddCommand(
109 "Debug",
110 false,
111 "show eq",
112 "show eq",
113 "Show contents of event queues for logged in avatars. Used for debugging.",
114 HandleShowEq);
115 }
116
117 public void RemoveRegion(Scene scene)
118 {
119 if (m_scene != scene)
120 return;
121
122 scene.EventManager.OnClientClosed -= ClientClosed;
123 scene.EventManager.OnRegisterCaps -= OnRegisterCaps;
124
125 scene.UnregisterModuleInterface<IEventQueue>(this);
126 m_scene = null;
127 }
128
129 public void RegionLoaded(Scene scene)
130 {
131 }
132
133 public virtual void Close()
134 {
135 }
136
137 public virtual string Name
138 {
139 get { return "EventQueueGetModule"; }
140 }
141
142 public Type ReplaceableInterface
143 {
144 get { return null; }
145 }
146
147 #endregion
148
149 protected void HandleDebugEq(string module, string[] args)
150 {
151 int debugLevel;
152
153 if (!(args.Length == 3 && int.TryParse(args[2], out debugLevel)))
154 {
155 MainConsole.Instance.OutputFormat("Usage: debug eq [0|1|2]");
156 }
157 else
158 {
159 DebugLevel = debugLevel;
160 MainConsole.Instance.OutputFormat(
161 "Set event queue debug level to {0} in {1}", DebugLevel, m_scene.RegionInfo.RegionName);
162 }
163 }
164
165 protected void HandleShowEq(string module, string[] args)
166 {
167 MainConsole.Instance.OutputFormat("For scene {0}", m_scene.Name);
168
169 lock (queues)
170 {
171 foreach (KeyValuePair<UUID, Queue<OSD>> kvp in queues)
172 {
173 MainConsole.Instance.OutputFormat(
174 "For agent {0} there are {1} messages queued for send.",
175 kvp.Key, kvp.Value.Count);
176 }
177 }
178 }
179
180 /// <summary>
181 /// Always returns a valid queue
182 /// </summary>
183 /// <param name="agentId"></param>
184 /// <returns></returns>
185 private Queue<OSD> TryGetQueue(UUID agentId)
186 {
187 lock (queues)
188 {
189 if (!queues.ContainsKey(agentId))
190 {
191 if (DebugLevel > 0)
192 m_log.DebugFormat(
193 "[EVENTQUEUE]: Adding new queue for agent {0} in region {1}",
194 agentId, m_scene.RegionInfo.RegionName);
195
196 queues[agentId] = new Queue<OSD>();
197 }
198
199 return queues[agentId];
200 }
201 }
202
203 /// <summary>
204 /// May return a null queue
205 /// </summary>
206 /// <param name="agentId"></param>
207 /// <returns></returns>
208 private Queue<OSD> GetQueue(UUID agentId)
209 {
210 lock (queues)
211 {
212 if (queues.ContainsKey(agentId))
213 {
214 return queues[agentId];
215 }
216 else
217 return null;
218 }
219 }
220
221 #region IEventQueue Members
222
223 public bool Enqueue(OSD ev, UUID avatarID)
224 {
225 //m_log.DebugFormat("[EVENTQUEUE]: Enqueuing event for {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName);
226 try
227 {
228 Queue<OSD> queue = GetQueue(avatarID);
229 if (queue != null)
230 {
231 lock (queue)
232 queue.Enqueue(ev);
233 }
234 else if (DebugLevel > 0)
235 {
236 ScenePresence sp = m_scene.GetScenePresence(avatarID);
237
238 // This assumes that an NPC should never have a queue.
239 if (sp != null && sp.PresenceType != PresenceType.Npc)
240 {
241 OSDMap evMap = (OSDMap)ev;
242 m_log.WarnFormat(
243 "[EVENTQUEUE]: (Enqueue) No queue found for agent {0} {1} when placing message {2} in region {3}",
244 sp.Name, sp.UUID, evMap["message"], m_scene.Name);
245 }
246 }
247 }
248 catch (NullReferenceException e)
249 {
250 m_log.Error("[EVENTQUEUE] Caught exception: " + e);
251 return false;
252 }
253
254 return true;
255 }
256
257 #endregion
258
259 private void ClientClosed(UUID agentID, Scene scene)
260 {
261 //m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
262
263 lock (queues)
264 queues.Remove(agentID);
265
266 List<UUID> removeitems = new List<UUID>();
267 lock (m_AvatarQueueUUIDMapping)
268 m_AvatarQueueUUIDMapping.Remove(agentID);
269
270 UUID searchval = UUID.Zero;
271
272 removeitems.Clear();
273
274 lock (m_QueueUUIDAvatarMapping)
275 {
276 foreach (UUID ky in m_QueueUUIDAvatarMapping.Keys)
277 {
278 searchval = m_QueueUUIDAvatarMapping[ky];
279
280 if (searchval == agentID)
281 {
282 removeitems.Add(ky);
283 }
284 }
285
286 foreach (UUID ky in removeitems)
287 m_QueueUUIDAvatarMapping.Remove(ky);
288 }
289
290 // m_log.DebugFormat("[EVENTQUEUE]: Deleted queues for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
291
292 }
293
294 /// <summary>
295 /// Generate an Event Queue Get handler path for the given eqg uuid.
296 /// </summary>
297 /// <param name='eqgUuid'></param>
298 private string GenerateEqgCapPath(UUID eqgUuid)
299 {
300 return string.Format("/CAPS/EQG/{0}/", eqgUuid);
301 }
302
303 public void OnRegisterCaps(UUID agentID, Caps caps)
304 {
305 // Register an event queue for the client
306
307 if (DebugLevel > 0)
308 m_log.DebugFormat(
309 "[EVENTQUEUE]: OnRegisterCaps: agentID {0} caps {1} region {2}",
310 agentID, caps, m_scene.RegionInfo.RegionName);
311
312 // Let's instantiate a Queue for this agent right now
313 TryGetQueue(agentID);
314
315 UUID eventQueueGetUUID;
316
317 lock (m_AvatarQueueUUIDMapping)
318 {
319 // Reuse open queues. The client does!
320 if (m_AvatarQueueUUIDMapping.ContainsKey(agentID))
321 {
322 //m_log.DebugFormat("[EVENTQUEUE]: Found Existing UUID!");
323 eventQueueGetUUID = m_AvatarQueueUUIDMapping[agentID];
324 }
325 else
326 {
327 eventQueueGetUUID = UUID.Random();
328 //m_log.DebugFormat("[EVENTQUEUE]: Using random UUID!");
329 }
330 }
331
332 lock (m_QueueUUIDAvatarMapping)
333 {
334 if (!m_QueueUUIDAvatarMapping.ContainsKey(eventQueueGetUUID))
335 m_QueueUUIDAvatarMapping.Add(eventQueueGetUUID, agentID);
336 }
337
338 lock (m_AvatarQueueUUIDMapping)
339 {
340 if (!m_AvatarQueueUUIDMapping.ContainsKey(agentID))
341 m_AvatarQueueUUIDMapping.Add(agentID, eventQueueGetUUID);
342 }
343
344 caps.RegisterPollHandler(
345 "EventQueueGet",
346 new PollServiceEventArgs(null, GenerateEqgCapPath(eventQueueGetUUID), HasEvents, GetEvents, NoEvents, agentID, SERVER_EQ_TIME_NO_EVENTS));
347
348 Random rnd = new Random(Environment.TickCount);
349 lock (m_ids)
350 {
351 if (!m_ids.ContainsKey(agentID))
352 m_ids.Add(agentID, rnd.Next(30000000));
353 }
354 }
355
356 public bool HasEvents(UUID requestID, UUID agentID)
357 {
358 // Don't use this, because of race conditions at agent closing time
359 //Queue<OSD> queue = TryGetQueue(agentID);
360
361 Queue<OSD> queue = GetQueue(agentID);
362 if (queue != null)
363 lock (queue)
364 {
365 //m_log.WarnFormat("POLLED FOR EVENTS BY {0} in {1} -- {2}", agentID, m_scene.RegionInfo.RegionName, queue.Count);
366 return queue.Count > 0;
367 }
368
369 return false;
370 }
371
372 /// <summary>
373 /// Logs a debug line for an outbound event queue message if appropriate.
374 /// </summary>
375 /// <param name='element'>Element containing message</param>
376 private void LogOutboundDebugMessage(OSD element, UUID agentId)
377 {
378 if (element is OSDMap)
379 {
380 OSDMap ev = (OSDMap)element;
381 m_log.DebugFormat(
382 "Eq OUT {0,-30} to {1,-20} {2,-20}",
383 ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name);
384 }
385 }
386
387 public Hashtable GetEvents(UUID requestID, UUID pAgentId)
388 {
389 if (DebugLevel >= 2)
390 m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.Name);
391
392 Queue<OSD> queue = GetQueue(pAgentId);
393 if (queue == null)
394 {
395 return NoEvents(requestID, pAgentId);
396 }
397
398 OSD element;
399 lock (queue)
400 {
401 if (queue.Count == 0)
402 return NoEvents(requestID, pAgentId);
403 element = queue.Dequeue(); // 15s timeout
404 }
405
406 int thisID = 0;
407 lock (m_ids)
408 thisID = m_ids[pAgentId];
409
410 OSDArray array = new OSDArray();
411 if (element == null) // didn't have an event in 15s
412 {
413 // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
414 array.Add(EventQueueHelper.KeepAliveEvent());
415 //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", pAgentId, m_scene.RegionInfo.RegionName);
416 }
417 else
418 {
419 if (DebugLevel > 0)
420 LogOutboundDebugMessage(element, pAgentId);
421
422 array.Add(element);
423
424 lock (queue)
425 {
426 while (queue.Count > 0)
427 {
428 element = queue.Dequeue();
429
430 if (DebugLevel > 0)
431 LogOutboundDebugMessage(element, pAgentId);
432
433 array.Add(element);
434 thisID++;
435 }
436 }
437 }
438
439 OSDMap events = new OSDMap();
440 events.Add("events", array);
441
442 events.Add("id", new OSDInteger(thisID));
443 lock (m_ids)
444 {
445 m_ids[pAgentId] = thisID + 1;
446 }
447 Hashtable responsedata = new Hashtable();
448 responsedata["int_response_code"] = 200;
449 responsedata["content_type"] = "application/xml";
450 responsedata["keepalive"] = false;
451 responsedata["reusecontext"] = false;
452 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
453 //m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", pAgentId, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
454 return responsedata;
455 }
456
457 public Hashtable NoEvents(UUID requestID, UUID agentID)
458 {
459 Hashtable responsedata = new Hashtable();
460 responsedata["int_response_code"] = 502;
461 responsedata["content_type"] = "text/plain";
462 responsedata["keepalive"] = false;
463 responsedata["reusecontext"] = false;
464 responsedata["str_response_string"] = "Upstream error: ";
465 responsedata["error_status_text"] = "Upstream error:";
466 responsedata["http_protocol_version"] = "HTTP/1.0";
467 return responsedata;
468 }
469
470// public Hashtable ProcessQueue(Hashtable request, UUID agentID, Caps caps)
471// {
472// // TODO: this has to be redone to not busy-wait (and block the thread),
473// // TODO: as soon as we have a non-blocking way to handle HTTP-requests.
474//
475//// if (m_log.IsDebugEnabled)
476//// {
477//// String debug = "[EVENTQUEUE]: Got request for agent {0} in region {1} from thread {2}: [ ";
478//// foreach (object key in request.Keys)
479//// {
480//// debug += key.ToString() + "=" + request[key].ToString() + " ";
481//// }
482//// m_log.DebugFormat(debug + " ]", agentID, m_scene.RegionInfo.RegionName, System.Threading.Thread.CurrentThread.Name);
483//// }
484//
485// Queue<OSD> queue = TryGetQueue(agentID);
486// OSD element;
487//
488// lock (queue)
489// element = queue.Dequeue(); // 15s timeout
490//
491// Hashtable responsedata = new Hashtable();
492//
493// int thisID = 0;
494// lock (m_ids)
495// thisID = m_ids[agentID];
496//
497// if (element == null)
498// {
499// //m_log.ErrorFormat("[EVENTQUEUE]: Nothing to process in " + m_scene.RegionInfo.RegionName);
500// if (thisID == -1) // close-request
501// {
502// m_log.ErrorFormat("[EVENTQUEUE]: 404 in " + m_scene.RegionInfo.RegionName);
503// responsedata["int_response_code"] = 404; //501; //410; //404;
504// responsedata["content_type"] = "text/plain";
505// responsedata["keepalive"] = false;
506// responsedata["str_response_string"] = "Closed EQG";
507// return responsedata;
508// }
509// responsedata["int_response_code"] = 502;
510// responsedata["content_type"] = "text/plain";
511// responsedata["keepalive"] = false;
512// responsedata["str_response_string"] = "Upstream error: ";
513// responsedata["error_status_text"] = "Upstream error:";
514// responsedata["http_protocol_version"] = "HTTP/1.0";
515// return responsedata;
516// }
517//
518// OSDArray array = new OSDArray();
519// if (element == null) // didn't have an event in 15s
520// {
521// // Send it a fake event to keep the client polling! It doesn't like 502s like the proxys say!
522// array.Add(EventQueueHelper.KeepAliveEvent());
523// //m_log.DebugFormat("[EVENTQUEUE]: adding fake event for {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
524// }
525// else
526// {
527// array.Add(element);
528//
529// if (element is OSDMap)
530// {
531// OSDMap ev = (OSDMap)element;
532// m_log.DebugFormat(
533// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
534// ev["message"], m_scene.GetScenePresence(agentID).Name);
535// }
536//
537// lock (queue)
538// {
539// while (queue.Count > 0)
540// {
541// element = queue.Dequeue();
542//
543// if (element is OSDMap)
544// {
545// OSDMap ev = (OSDMap)element;
546// m_log.DebugFormat(
547// "[EVENT QUEUE GET MODULE]: Eq OUT {0} to {1}",
548// ev["message"], m_scene.GetScenePresence(agentID).Name);
549// }
550//
551// array.Add(element);
552// thisID++;
553// }
554// }
555// }
556//
557// OSDMap events = new OSDMap();
558// events.Add("events", array);
559//
560// events.Add("id", new OSDInteger(thisID));
561// lock (m_ids)
562// {
563// m_ids[agentID] = thisID + 1;
564// }
565//
566// responsedata["int_response_code"] = 200;
567// responsedata["content_type"] = "application/xml";
568// responsedata["keepalive"] = false;
569// responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(events);
570//
571// m_log.DebugFormat("[EVENTQUEUE]: sending response for {0} in region {1}: {2}", agentID, m_scene.RegionInfo.RegionName, responsedata["str_response_string"]);
572//
573// return responsedata;
574// }
575
576// public Hashtable EventQueuePath2(Hashtable request)
577// {
578// string capuuid = (string)request["uri"]; //path.Replace("/CAPS/EQG/","");
579// // pull off the last "/" in the path.
580// Hashtable responsedata = new Hashtable();
581// capuuid = capuuid.Substring(0, capuuid.Length - 1);
582// capuuid = capuuid.Replace("/CAPS/EQG/", "");
583// UUID AvatarID = UUID.Zero;
584// UUID capUUID = UUID.Zero;
585//
586// // parse the path and search for the avatar with it registered
587// if (UUID.TryParse(capuuid, out capUUID))
588// {
589// lock (m_QueueUUIDAvatarMapping)
590// {
591// if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
592// {
593// AvatarID = m_QueueUUIDAvatarMapping[capUUID];
594// }
595// }
596//
597// if (AvatarID != UUID.Zero)
598// {
599// return ProcessQueue(request, AvatarID, m_scene.CapsModule.GetCapsForUser(AvatarID));
600// }
601// else
602// {
603// responsedata["int_response_code"] = 404;
604// responsedata["content_type"] = "text/plain";
605// responsedata["keepalive"] = false;
606// responsedata["str_response_string"] = "Not Found";
607// responsedata["error_status_text"] = "Not Found";
608// responsedata["http_protocol_version"] = "HTTP/1.0";
609// return responsedata;
610// // return 404
611// }
612// }
613// else
614// {
615// responsedata["int_response_code"] = 404;
616// responsedata["content_type"] = "text/plain";
617// responsedata["keepalive"] = false;
618// responsedata["str_response_string"] = "Not Found";
619// responsedata["error_status_text"] = "Not Found";
620// responsedata["http_protocol_version"] = "HTTP/1.0";
621// return responsedata;
622// // return 404
623// }
624// }
625
626 public OSD EventQueueFallBack(string path, OSD request, string endpoint)
627 {
628 // This is a fallback element to keep the client from loosing EventQueueGet
629 // Why does CAPS fail sometimes!?
630 m_log.Warn("[EVENTQUEUE]: In the Fallback handler! We lost the Queue in the rest handler!");
631 string capuuid = path.Replace("/CAPS/EQG/","");
632 capuuid = capuuid.Substring(0, capuuid.Length - 1);
633
634// UUID AvatarID = UUID.Zero;
635 UUID capUUID = UUID.Zero;
636 if (UUID.TryParse(capuuid, out capUUID))
637 {
638/* Don't remove this yet code cleaners!
639 * Still testing this!
640 *
641 lock (m_QueueUUIDAvatarMapping)
642 {
643 if (m_QueueUUIDAvatarMapping.ContainsKey(capUUID))
644 {
645 AvatarID = m_QueueUUIDAvatarMapping[capUUID];
646 }
647 }
648
649
650 if (AvatarID != UUID.Zero)
651 {
652 // Repair the CAP!
653 //OpenSim.Framework.Capabilities.Caps caps = m_scene.GetCapsHandlerForUser(AvatarID);
654 //string capsBase = "/CAPS/EQG/";
655 //caps.RegisterHandler("EventQueueGet",
656 //new RestHTTPHandler("POST", capsBase + capUUID.ToString() + "/",
657 //delegate(Hashtable m_dhttpMethod)
658 //{
659 // return ProcessQueue(m_dhttpMethod, AvatarID, caps);
660 //}));
661 // start new ID sequence.
662 Random rnd = new Random(System.Environment.TickCount);
663 lock (m_ids)
664 {
665 if (!m_ids.ContainsKey(AvatarID))
666 m_ids.Add(AvatarID, rnd.Next(30000000));
667 }
668
669
670 int thisID = 0;
671 lock (m_ids)
672 thisID = m_ids[AvatarID];
673
674 BlockingLLSDQueue queue = GetQueue(AvatarID);
675 OSDArray array = new OSDArray();
676 LLSD element = queue.Dequeue(15000); // 15s timeout
677 if (element == null)
678 {
679
680 array.Add(EventQueueHelper.KeepAliveEvent());
681 }
682 else
683 {
684 array.Add(element);
685 while (queue.Count() > 0)
686 {
687 array.Add(queue.Dequeue(1));
688 thisID++;
689 }
690 }
691 OSDMap events = new OSDMap();
692 events.Add("events", array);
693
694 events.Add("id", new LLSDInteger(thisID));
695
696 lock (m_ids)
697 {
698 m_ids[AvatarID] = thisID + 1;
699 }
700
701 return events;
702 }
703 else
704 {
705 return new LLSD();
706 }
707*
708*/
709 }
710 else
711 {
712 //return new LLSD();
713 }
714
715 return new OSDString("shutdown404!");
716 }
717
718 public void DisableSimulator(ulong handle, UUID avatarID)
719 {
720 OSD item = EventQueueHelper.DisableSimulator(handle);
721 Enqueue(item, avatarID);
722 }
723
724 public virtual void EnableSimulator(ulong handle, IPEndPoint endPoint, UUID avatarID, int regionSizeX, int regionSizeY)
725 {
726 if (DebugLevel > 0)
727 m_log.DebugFormat("{0} EnableSimulator. handle={1}, endPoint={2}, avatarID={3}",
728 LogHeader, handle, endPoint, avatarID, regionSizeX, regionSizeY);
729
730 OSD item = EventQueueHelper.EnableSimulator(handle, endPoint, regionSizeX, regionSizeY);
731 Enqueue(item, avatarID);
732 }
733
734 public virtual void EstablishAgentCommunication(UUID avatarID, IPEndPoint endPoint, string capsPath,
735 ulong regionHandle, int regionSizeX, int regionSizeY)
736 {
737 if (DebugLevel > 0)
738 m_log.DebugFormat("{0} EstablishAgentCommunication. handle={1}, endPoint={2}, avatarID={3}",
739 LogHeader, regionHandle, endPoint, avatarID, regionSizeX, regionSizeY);
740
741 OSD item = EventQueueHelper.EstablishAgentCommunication(avatarID, endPoint.ToString(), capsPath, regionHandle, regionSizeX, regionSizeY);
742 Enqueue(item, avatarID);
743 }
744
745 public virtual void TeleportFinishEvent(ulong regionHandle, byte simAccess,
746 IPEndPoint regionExternalEndPoint,
747 uint locationID, uint flags, string capsURL,
748 UUID avatarID, int regionSizeX, int regionSizeY)
749 {
750 if (DebugLevel > 0)
751 m_log.DebugFormat("{0} TeleportFinishEvent. handle={1}, endPoint={2}, avatarID={3}",
752 LogHeader, regionHandle, regionExternalEndPoint, avatarID, regionSizeX, regionSizeY);
753
754 OSD item = EventQueueHelper.TeleportFinishEvent(regionHandle, simAccess, regionExternalEndPoint,
755 locationID, flags, capsURL, avatarID, regionSizeX, regionSizeY);
756 Enqueue(item, avatarID);
757 }
758
759 public virtual void CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
760 IPEndPoint newRegionExternalEndPoint,
761 string capsURL, UUID avatarID, UUID sessionID, int regionSizeX, int regionSizeY)
762 {
763 if (DebugLevel > 0)
764 m_log.DebugFormat("{0} CrossRegion. handle={1}, avatarID={2}, regionSize={3},{4}>",
765 LogHeader, handle, avatarID, regionSizeX, regionSizeY);
766
767 OSD item = EventQueueHelper.CrossRegion(handle, pos, lookAt, newRegionExternalEndPoint,
768 capsURL, avatarID, sessionID, regionSizeX, regionSizeY);
769 Enqueue(item, avatarID);
770 }
771
772 public void ChatterboxInvitation(UUID sessionID, string sessionName,
773 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
774 uint timeStamp, bool offline, int parentEstateID, Vector3 position,
775 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
776 {
777 OSD item = EventQueueHelper.ChatterboxInvitation(sessionID, sessionName, fromAgent, message, toAgent, fromName, dialog,
778 timeStamp, offline, parentEstateID, position, ttl, transactionID,
779 fromGroup, binaryBucket);
780 Enqueue(item, toAgent);
781 //m_log.InfoFormat("########### eq ChatterboxInvitation #############\n{0}", item);
782
783 }
784
785 public void ChatterBoxSessionAgentListUpdates(UUID sessionID, UUID fromAgent, UUID anotherAgent, bool canVoiceChat,
786 bool isModerator, bool textMute)
787 {
788 OSD item = EventQueueHelper.ChatterBoxSessionAgentListUpdates(sessionID, fromAgent, canVoiceChat,
789 isModerator, textMute);
790 Enqueue(item, fromAgent);
791 //m_log.InfoFormat("########### eq ChatterBoxSessionAgentListUpdates #############\n{0}", item);
792 }
793
794 public void ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage, UUID avatarID)
795 {
796 OSD item = EventQueueHelper.ParcelProperties(parcelPropertiesMessage);
797 Enqueue(item, avatarID);
798 }
799
800 public void GroupMembership(AgentGroupDataUpdatePacket groupUpdate, UUID avatarID)
801 {
802 OSD item = EventQueueHelper.GroupMembership(groupUpdate);
803 Enqueue(item, avatarID);
804 }
805
806 public void QueryReply(PlacesReplyPacket groupUpdate, UUID avatarID)
807 {
808 OSD item = EventQueueHelper.PlacesQuery(groupUpdate);
809 Enqueue(item, avatarID);
810 }
811
812 public OSD ScriptRunningEvent(UUID objectID, UUID itemID, bool running, bool mono)
813 {
814 return EventQueueHelper.ScriptRunningReplyEvent(objectID, itemID, running, mono);
815 }
816
817 public OSD BuildEvent(string eventName, OSD eventBody)
818 {
819 return EventQueueHelper.BuildEvent(eventName, eventBody);
820 }
821
822 public void partPhysicsProperties(uint localID, byte physhapetype,
823 float density, float friction, float bounce, float gravmod,UUID avatarID)
824 {
825 OSD item = EventQueueHelper.partPhysicsProperties(localID, physhapetype,
826 density, friction, bounce, gravmod);
827 Enqueue(item, avatarID);
828 }
829 }
830} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
new file mode 100644
index 0000000..384af74
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueHelper.cs
@@ -0,0 +1,433 @@
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.Net;
30using OpenMetaverse;
31using OpenMetaverse.Packets;
32using OpenMetaverse.StructuredData;
33using OpenMetaverse.Messages.Linden;
34
35namespace OpenSim.Region.ClientStack.Linden
36{
37 public class EventQueueHelper
38 {
39 private EventQueueHelper() {} // no construction possible, it's an utility class
40
41 private static byte[] ulongToByteArray(ulong uLongValue)
42 {
43 // Reverse endianness of RegionHandle
44 return new byte[]
45 {
46 (byte)((uLongValue >> 56) % 256),
47 (byte)((uLongValue >> 48) % 256),
48 (byte)((uLongValue >> 40) % 256),
49 (byte)((uLongValue >> 32) % 256),
50 (byte)((uLongValue >> 24) % 256),
51 (byte)((uLongValue >> 16) % 256),
52 (byte)((uLongValue >> 8) % 256),
53 (byte)(uLongValue % 256)
54 };
55 }
56
57// private static byte[] uintToByteArray(uint uIntValue)
58// {
59// byte[] result = new byte[4];
60// Utils.UIntToBytesBig(uIntValue, result, 0);
61// return result;
62// }
63
64 public static OSD BuildEvent(string eventName, OSD eventBody)
65 {
66 OSDMap llsdEvent = new OSDMap(2);
67 llsdEvent.Add("message", new OSDString(eventName));
68 llsdEvent.Add("body", eventBody);
69
70 return llsdEvent;
71 }
72
73 public static OSD EnableSimulator(ulong handle, IPEndPoint endPoint, int regionSizeX, int regionSizeY)
74 {
75 OSDMap llsdSimInfo = new OSDMap(5);
76
77 llsdSimInfo.Add("Handle", new OSDBinary(ulongToByteArray(handle)));
78 llsdSimInfo.Add("IP", new OSDBinary(endPoint.Address.GetAddressBytes()));
79 llsdSimInfo.Add("Port", new OSDInteger(endPoint.Port));
80 llsdSimInfo.Add("RegionSizeX", OSD.FromUInteger((uint) regionSizeX));
81 llsdSimInfo.Add("RegionSizeY", OSD.FromUInteger((uint) regionSizeY));
82
83 OSDArray arr = new OSDArray(1);
84 arr.Add(llsdSimInfo);
85
86 OSDMap llsdBody = new OSDMap(1);
87 llsdBody.Add("SimulatorInfo", arr);
88
89 return BuildEvent("EnableSimulator", llsdBody);
90 }
91
92 public static OSD DisableSimulator(ulong handle)
93 {
94 //OSDMap llsdSimInfo = new OSDMap(1);
95
96 //llsdSimInfo.Add("Handle", new OSDBinary(regionHandleToByteArray(handle)));
97
98 //OSDArray arr = new OSDArray(1);
99 //arr.Add(llsdSimInfo);
100
101 OSDMap llsdBody = new OSDMap(0);
102 //llsdBody.Add("SimulatorInfo", arr);
103
104 return BuildEvent("DisableSimulator", llsdBody);
105 }
106
107 public static OSD CrossRegion(ulong handle, Vector3 pos, Vector3 lookAt,
108 IPEndPoint newRegionExternalEndPoint,
109 string capsURL, UUID agentID, UUID sessionID,
110 int regionSizeX, int regionSizeY)
111 {
112 OSDArray lookAtArr = new OSDArray(3);
113 lookAtArr.Add(OSD.FromReal(lookAt.X));
114 lookAtArr.Add(OSD.FromReal(lookAt.Y));
115 lookAtArr.Add(OSD.FromReal(lookAt.Z));
116
117 OSDArray positionArr = new OSDArray(3);
118 positionArr.Add(OSD.FromReal(pos.X));
119 positionArr.Add(OSD.FromReal(pos.Y));
120 positionArr.Add(OSD.FromReal(pos.Z));
121
122 OSDMap infoMap = new OSDMap(2);
123 infoMap.Add("LookAt", lookAtArr);
124 infoMap.Add("Position", positionArr);
125
126 OSDArray infoArr = new OSDArray(1);
127 infoArr.Add(infoMap);
128
129 OSDMap agentDataMap = new OSDMap(2);
130 agentDataMap.Add("AgentID", OSD.FromUUID(agentID));
131 agentDataMap.Add("SessionID", OSD.FromUUID(sessionID));
132
133 OSDArray agentDataArr = new OSDArray(1);
134 agentDataArr.Add(agentDataMap);
135
136 OSDMap regionDataMap = new OSDMap(6);
137 regionDataMap.Add("RegionHandle", OSD.FromBinary(ulongToByteArray(handle)));
138 regionDataMap.Add("SeedCapability", OSD.FromString(capsURL));
139 regionDataMap.Add("SimIP", OSD.FromBinary(newRegionExternalEndPoint.Address.GetAddressBytes()));
140 regionDataMap.Add("SimPort", OSD.FromInteger(newRegionExternalEndPoint.Port));
141 regionDataMap.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
142 regionDataMap.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
143
144 OSDArray regionDataArr = new OSDArray(1);
145 regionDataArr.Add(regionDataMap);
146
147 OSDMap llsdBody = new OSDMap(3);
148 llsdBody.Add("Info", infoArr);
149 llsdBody.Add("AgentData", agentDataArr);
150 llsdBody.Add("RegionData", regionDataArr);
151
152 return BuildEvent("CrossedRegion", llsdBody);
153 }
154
155 public static OSD TeleportFinishEvent(
156 ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
157 uint locationID, uint flags, string capsURL, UUID agentID,
158 int regionSizeX, int regionSizeY)
159 {
160 OSDMap info = new OSDMap();
161 info.Add("AgentID", OSD.FromUUID(agentID));
162 info.Add("LocationID", OSD.FromInteger(4)); // TODO what is this?
163 info.Add("RegionHandle", OSD.FromBinary(ulongToByteArray(regionHandle)));
164 info.Add("SeedCapability", OSD.FromString(capsURL));
165 info.Add("SimAccess", OSD.FromInteger(simAccess));
166 info.Add("SimIP", OSD.FromBinary(regionExternalEndPoint.Address.GetAddressBytes()));
167 info.Add("SimPort", OSD.FromInteger(regionExternalEndPoint.Port));
168 info.Add("TeleportFlags", OSD.FromULong(1L << 4)); // AgentManager.TeleportFlags.ViaLocation
169 info.Add("RegionSizeX", OSD.FromUInteger((uint)regionSizeX));
170 info.Add("RegionSizeY", OSD.FromUInteger((uint)regionSizeY));
171
172 OSDArray infoArr = new OSDArray();
173 infoArr.Add(info);
174
175 OSDMap body = new OSDMap();
176 body.Add("Info", infoArr);
177
178 return BuildEvent("TeleportFinish", body);
179 }
180
181 public static OSD ScriptRunningReplyEvent(UUID objectID, UUID itemID, bool running, bool mono)
182 {
183 OSDMap script = new OSDMap();
184 script.Add("ObjectID", OSD.FromUUID(objectID));
185 script.Add("ItemID", OSD.FromUUID(itemID));
186 script.Add("Running", OSD.FromBoolean(running));
187 script.Add("Mono", OSD.FromBoolean(mono));
188
189 OSDArray scriptArr = new OSDArray();
190 scriptArr.Add(script);
191
192 OSDMap body = new OSDMap();
193 body.Add("Script", scriptArr);
194
195 return BuildEvent("ScriptRunningReply", body);
196 }
197
198 public static OSD EstablishAgentCommunication(UUID agentID, string simIpAndPort, string seedcap,
199 ulong regionHandle, int regionSizeX, int regionSizeY)
200 {
201 OSDMap body = new OSDMap(6)
202 {
203 {"agent-id", new OSDUUID(agentID)},
204 {"sim-ip-and-port", new OSDString(simIpAndPort)},
205 {"seed-capability", new OSDString(seedcap)},
206 {"region-handle", OSD.FromULong(regionHandle)},
207 {"region-size-x", OSD.FromInteger(regionSizeX)},
208 {"region-size-y", OSD.FromInteger(regionSizeY)}
209 };
210
211 return BuildEvent("EstablishAgentCommunication", body);
212 }
213
214 public static OSD KeepAliveEvent()
215 {
216 return BuildEvent("FAKEEVENT", new OSDMap());
217 }
218
219 public static OSD AgentParams(UUID agentID, bool checkEstate, int godLevel, bool limitedToEstate)
220 {
221 OSDMap body = new OSDMap(4);
222
223 body.Add("agent_id", new OSDUUID(agentID));
224 body.Add("check_estate", new OSDInteger(checkEstate ? 1 : 0));
225 body.Add("god_level", new OSDInteger(godLevel));
226 body.Add("limited_to_estate", new OSDInteger(limitedToEstate ? 1 : 0));
227
228 return body;
229 }
230
231 public static OSD InstantMessageParams(UUID fromAgent, string message, UUID toAgent,
232 string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID,
233 Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
234 {
235 OSDMap messageParams = new OSDMap(15);
236 messageParams.Add("type", new OSDInteger((int)dialog));
237
238 OSDArray positionArray = new OSDArray(3);
239 positionArray.Add(OSD.FromReal(position.X));
240 positionArray.Add(OSD.FromReal(position.Y));
241 positionArray.Add(OSD.FromReal(position.Z));
242 messageParams.Add("position", positionArray);
243
244 messageParams.Add("region_id", new OSDUUID(UUID.Zero));
245 messageParams.Add("to_id", new OSDUUID(toAgent));
246 messageParams.Add("source", new OSDInteger(0));
247
248 OSDMap data = new OSDMap(1);
249 data.Add("binary_bucket", OSD.FromBinary(binaryBucket));
250 messageParams.Add("data", data);
251 messageParams.Add("message", new OSDString(message));
252 messageParams.Add("id", new OSDUUID(transactionID));
253 messageParams.Add("from_name", new OSDString(fromName));
254 messageParams.Add("timestamp", new OSDInteger((int)timeStamp));
255 messageParams.Add("offline", new OSDInteger(offline ? 1 : 0));
256 messageParams.Add("parent_estate_id", new OSDInteger(parentEstateID));
257 messageParams.Add("ttl", new OSDInteger((int)ttl));
258 messageParams.Add("from_id", new OSDUUID(fromAgent));
259 messageParams.Add("from_group", new OSDInteger(fromGroup ? 1 : 0));
260
261 return messageParams;
262 }
263
264 public static OSD InstantMessage(UUID fromAgent, string message, UUID toAgent,
265 string fromName, byte dialog, uint timeStamp, bool offline, int parentEstateID,
266 Vector3 position, uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket,
267 bool checkEstate, int godLevel, bool limitedToEstate)
268 {
269 OSDMap im = new OSDMap(2);
270 im.Add("message_params", InstantMessageParams(fromAgent, message, toAgent,
271 fromName, dialog, timeStamp, offline, parentEstateID,
272 position, ttl, transactionID, fromGroup, binaryBucket));
273
274 im.Add("agent_params", AgentParams(fromAgent, checkEstate, godLevel, limitedToEstate));
275
276 return im;
277 }
278
279
280 public static OSD ChatterboxInvitation(UUID sessionID, string sessionName,
281 UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog,
282 uint timeStamp, bool offline, int parentEstateID, Vector3 position,
283 uint ttl, UUID transactionID, bool fromGroup, byte[] binaryBucket)
284 {
285 OSDMap body = new OSDMap(5);
286 body.Add("session_id", new OSDUUID(sessionID));
287 body.Add("from_name", new OSDString(fromName));
288 body.Add("session_name", new OSDString(sessionName));
289 body.Add("from_id", new OSDUUID(fromAgent));
290
291 body.Add("instantmessage", InstantMessage(fromAgent, message, toAgent,
292 fromName, dialog, timeStamp, offline, parentEstateID, position,
293 ttl, transactionID, fromGroup, binaryBucket, true, 0, true));
294
295 OSDMap chatterboxInvitation = new OSDMap(2);
296 chatterboxInvitation.Add("message", new OSDString("ChatterBoxInvitation"));
297 chatterboxInvitation.Add("body", body);
298 return chatterboxInvitation;
299 }
300
301 public static OSD ChatterBoxSessionAgentListUpdates(UUID sessionID,
302 UUID agentID, bool canVoiceChat, bool isModerator, bool textMute)
303 {
304 OSDMap body = new OSDMap();
305 OSDMap agentUpdates = new OSDMap();
306 OSDMap infoDetail = new OSDMap();
307 OSDMap mutes = new OSDMap();
308
309 mutes.Add("text", OSD.FromBoolean(textMute));
310 infoDetail.Add("can_voice_chat", OSD.FromBoolean(canVoiceChat));
311 infoDetail.Add("is_moderator", OSD.FromBoolean(isModerator));
312 infoDetail.Add("mutes", mutes);
313 OSDMap info = new OSDMap();
314 info.Add("info", infoDetail);
315 agentUpdates.Add(agentID.ToString(), info);
316 body.Add("agent_updates", agentUpdates);
317 body.Add("session_id", OSD.FromUUID(sessionID));
318 body.Add("updates", new OSD());
319
320 OSDMap chatterBoxSessionAgentListUpdates = new OSDMap();
321 chatterBoxSessionAgentListUpdates.Add("message", OSD.FromString("ChatterBoxSessionAgentListUpdates"));
322 chatterBoxSessionAgentListUpdates.Add("body", body);
323
324 return chatterBoxSessionAgentListUpdates;
325 }
326
327 public static OSD GroupMembership(AgentGroupDataUpdatePacket groupUpdatePacket)
328 {
329 OSDMap groupUpdate = new OSDMap();
330 groupUpdate.Add("message", OSD.FromString("AgentGroupDataUpdate"));
331
332 OSDMap body = new OSDMap();
333 OSDArray agentData = new OSDArray();
334 OSDMap agentDataMap = new OSDMap();
335 agentDataMap.Add("AgentID", OSD.FromUUID(groupUpdatePacket.AgentData.AgentID));
336 agentData.Add(agentDataMap);
337 body.Add("AgentData", agentData);
338
339 OSDArray groupData = new OSDArray();
340
341 foreach (AgentGroupDataUpdatePacket.GroupDataBlock groupDataBlock in groupUpdatePacket.GroupData)
342 {
343 OSDMap groupDataMap = new OSDMap();
344 groupDataMap.Add("ListInProfile", OSD.FromBoolean(false));
345 groupDataMap.Add("GroupID", OSD.FromUUID(groupDataBlock.GroupID));
346 groupDataMap.Add("GroupInsigniaID", OSD.FromUUID(groupDataBlock.GroupInsigniaID));
347 groupDataMap.Add("Contribution", OSD.FromInteger(groupDataBlock.Contribution));
348 groupDataMap.Add("GroupPowers", OSD.FromBinary(ulongToByteArray(groupDataBlock.GroupPowers)));
349 groupDataMap.Add("GroupName", OSD.FromString(Utils.BytesToString(groupDataBlock.GroupName)));
350 groupDataMap.Add("AcceptNotices", OSD.FromBoolean(groupDataBlock.AcceptNotices));
351
352 groupData.Add(groupDataMap);
353
354 }
355 body.Add("GroupData", groupData);
356 groupUpdate.Add("body", body);
357
358 return groupUpdate;
359 }
360
361 public static OSD PlacesQuery(PlacesReplyPacket PlacesReply)
362 {
363 OSDMap placesReply = new OSDMap();
364 placesReply.Add("message", OSD.FromString("PlacesReplyMessage"));
365
366 OSDMap body = new OSDMap();
367 OSDArray agentData = new OSDArray();
368 OSDMap agentDataMap = new OSDMap();
369 agentDataMap.Add("AgentID", OSD.FromUUID(PlacesReply.AgentData.AgentID));
370 agentDataMap.Add("QueryID", OSD.FromUUID(PlacesReply.AgentData.QueryID));
371 agentDataMap.Add("TransactionID", OSD.FromUUID(PlacesReply.TransactionData.TransactionID));
372 agentData.Add(agentDataMap);
373 body.Add("AgentData", agentData);
374
375 OSDArray QueryData = new OSDArray();
376
377 foreach (PlacesReplyPacket.QueryDataBlock groupDataBlock in PlacesReply.QueryData)
378 {
379 OSDMap QueryDataMap = new OSDMap();
380 QueryDataMap.Add("ActualArea", OSD.FromInteger(groupDataBlock.ActualArea));
381 QueryDataMap.Add("BillableArea", OSD.FromInteger(groupDataBlock.BillableArea));
382 QueryDataMap.Add("Description", OSD.FromBinary(groupDataBlock.Desc));
383 QueryDataMap.Add("Dwell", OSD.FromInteger((int)groupDataBlock.Dwell));
384 QueryDataMap.Add("Flags", OSD.FromString(Convert.ToString(groupDataBlock.Flags)));
385 QueryDataMap.Add("GlobalX", OSD.FromInteger((int)groupDataBlock.GlobalX));
386 QueryDataMap.Add("GlobalY", OSD.FromInteger((int)groupDataBlock.GlobalY));
387 QueryDataMap.Add("GlobalZ", OSD.FromInteger((int)groupDataBlock.GlobalZ));
388 QueryDataMap.Add("Name", OSD.FromBinary(groupDataBlock.Name));
389 QueryDataMap.Add("OwnerID", OSD.FromUUID(groupDataBlock.OwnerID));
390 QueryDataMap.Add("SimName", OSD.FromBinary(groupDataBlock.SimName));
391 QueryDataMap.Add("SnapShotID", OSD.FromUUID(groupDataBlock.SnapshotID));
392 QueryDataMap.Add("ProductSku", OSD.FromInteger(0));
393 QueryDataMap.Add("Price", OSD.FromInteger(groupDataBlock.Price));
394
395 QueryData.Add(QueryDataMap);
396 }
397 body.Add("QueryData", QueryData);
398 placesReply.Add("QueryData[]", body);
399
400 return placesReply;
401 }
402
403 public static OSD ParcelProperties(ParcelPropertiesMessage parcelPropertiesMessage)
404 {
405 OSDMap message = new OSDMap();
406 message.Add("message", OSD.FromString("ParcelProperties"));
407 OSD message_body = parcelPropertiesMessage.Serialize();
408 message.Add("body", message_body);
409 return message;
410 }
411
412 public static OSD partPhysicsProperties(uint localID, byte physhapetype,
413 float density, float friction, float bounce, float gravmod)
414 {
415
416 OSDMap physinfo = new OSDMap(6);
417 physinfo["LocalID"] = localID;
418 physinfo["Density"] = density;
419 physinfo["Friction"] = friction;
420 physinfo["GravityMultiplier"] = gravmod;
421 physinfo["Restitution"] = bounce;
422 physinfo["PhysicsShapeType"] = (int)physhapetype;
423
424 OSDArray array = new OSDArray(1);
425 array.Add(physinfo);
426
427 OSDMap llsdBody = new OSDMap(1);
428 llsdBody.Add("ObjectData", array);
429
430 return BuildEvent("ObjectPhysicsProperties", llsdBody);
431 }
432 }
433}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
new file mode 100644
index 0000000..16a902d
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -0,0 +1,190 @@
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 log4net.Config;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Packets;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Framework.Servers;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Region.ClientStack.Linden;
42using OpenSim.Region.CoreModules.Framework;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Region.OptionalModules.World.NPC;
45using OpenSim.Tests.Common;
46
47namespace OpenSim.Region.ClientStack.Linden.Tests
48{
49 [TestFixture]
50 public class EventQueueTests : OpenSimTestCase
51 {
52 private TestScene m_scene;
53 private EventQueueGetModule m_eqgMod;
54 private NPCModule m_npcMod;
55
56 [SetUp]
57 public override void SetUp()
58 {
59 base.SetUp();
60
61 uint port = 9999;
62 uint sslPort = 9998;
63
64 // This is an unfortunate bit of clean up we have to do because MainServer manages things through static
65 // variables and the VM is not restarted between tests.
66 MainServer.RemoveHttpServer(port);
67
68 BaseHttpServer server = new BaseHttpServer(port, false, sslPort, "");
69 MainServer.AddHttpServer(server);
70 MainServer.Instance = server;
71
72 IConfigSource config = new IniConfigSource();
73 config.AddConfig("Startup");
74 config.Configs["Startup"].Set("EventQueue", "true");
75
76 CapabilitiesModule capsModule = new CapabilitiesModule();
77 m_eqgMod = new EventQueueGetModule();
78
79 // For NPC test support
80 config.AddConfig("NPC");
81 config.Configs["NPC"].Set("Enabled", "true");
82 m_npcMod = new NPCModule();
83
84 m_scene = new SceneHelpers().SetupScene();
85 SceneHelpers.SetupSceneModules(m_scene, config, capsModule, m_eqgMod, m_npcMod);
86 }
87
88 [Test]
89 public void TestAddForClient()
90 {
91 TestHelpers.InMethod();
92// log4net.Config.XmlConfigurator.Configure();
93
94 SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
95
96 // TODO: Add more assertions for the other aspects of event queues
97 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(1));
98 }
99
100 [Test]
101 public void TestRemoveForClient()
102 {
103 TestHelpers.InMethod();
104// TestHelpers.EnableLogging();
105
106 UUID spId = TestHelpers.ParseTail(0x1);
107
108 SceneHelpers.AddScenePresence(m_scene, spId);
109 m_scene.CloseAgent(spId, false);
110
111 // TODO: Add more assertions for the other aspects of event queues
112 Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
113 }
114
115 [Test]
116 public void TestEnqueueMessage()
117 {
118 TestHelpers.InMethod();
119// log4net.Config.XmlConfigurator.Configure();
120
121 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
122
123 string messageName = "TestMessage";
124
125 m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), sp.UUID);
126
127 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, sp.UUID);
128
129 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.OK));
130
131// Console.WriteLine("Response [{0}]", (string)eventsResponse["str_response_string"]);
132
133 OSDMap rawOsd = (OSDMap)OSDParser.DeserializeLLSDXml((string)eventsResponse["str_response_string"]);
134 OSDArray eventsOsd = (OSDArray)rawOsd["events"];
135
136 bool foundUpdate = false;
137 foreach (OSD osd in eventsOsd)
138 {
139 OSDMap eventOsd = (OSDMap)osd;
140
141 if (eventOsd["message"] == messageName)
142 foundUpdate = true;
143 }
144
145 Assert.That(foundUpdate, Is.True, string.Format("Did not find {0} in response", messageName));
146 }
147
148 /// <summary>
149 /// Test an attempt to put a message on the queue of a user that is not in the region.
150 /// </summary>
151 [Test]
152 public void TestEnqueueMessageNoUser()
153 {
154 TestHelpers.InMethod();
155 TestHelpers.EnableLogging();
156
157 string messageName = "TestMessage";
158
159 m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), TestHelpers.ParseTail(0x1));
160
161 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, TestHelpers.ParseTail(0x1));
162
163 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway));
164 }
165
166 /// <summary>
167 /// NPCs do not currently have an event queue but a caller may try to send a message anyway, so check behaviour.
168 /// </summary>
169 [Test]
170 public void TestEnqueueMessageToNpc()
171 {
172 TestHelpers.InMethod();
173// TestHelpers.EnableLogging();
174
175 UUID npcId
176 = m_npcMod.CreateNPC(
177 "John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, new AvatarAppearance());
178
179 ScenePresence npc = m_scene.GetScenePresence(npcId);
180
181 string messageName = "TestMessage";
182
183 m_eqgMod.Enqueue(m_eqgMod.BuildEvent(messageName, new OSDMap()), npc.UUID);
184
185 Hashtable eventsResponse = m_eqgMod.GetEvents(UUID.Zero, npc.UUID);
186
187 Assert.That((int)eventsResponse["int_response_code"], Is.EqualTo((int)HttpStatusCode.BadGateway));
188 }
189 }
190} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
new file mode 100644
index 0000000..e0a11cc
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/FetchInventory2Module.cs
@@ -0,0 +1,144 @@
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 Mono.Addins;
29using Nini.Config;
30using OpenMetaverse;
31using OpenSim.Capabilities.Handlers;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Region.Framework.Interfaces;
34using OpenSim.Region.Framework.Scenes;
35using OpenSim.Services.Interfaces;
36using System;
37using Caps = OpenSim.Framework.Capabilities.Caps;
38
39namespace OpenSim.Region.ClientStack.Linden
40{
41 /// <summary>
42 /// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
43 /// </summary>
44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "FetchInventory2Module")]
45 public class FetchInventory2Module : INonSharedRegionModule
46 {
47// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48
49 public bool Enabled { get; private set; }
50
51 private Scene m_scene;
52
53 private IInventoryService m_inventoryService;
54
55 private string m_fetchInventory2Url;
56
57 #region ISharedRegionModule Members
58
59 public void Initialise(IConfigSource source)
60 {
61 IConfig config = source.Configs["ClientStack.LindenCaps"];
62 if (config == null)
63 return;
64
65 m_fetchInventory2Url = config.GetString("Cap_FetchInventory2", string.Empty);
66
67 if (m_fetchInventory2Url != string.Empty)
68 Enabled = true;
69 }
70
71 public void AddRegion(Scene s)
72 {
73 if (!Enabled)
74 return;
75
76 m_scene = s;
77 }
78
79 public void RemoveRegion(Scene s)
80 {
81 if (!Enabled)
82 return;
83
84 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
85 m_scene = null;
86 }
87
88 public void RegionLoaded(Scene s)
89 {
90 if (!Enabled)
91 return;
92
93 m_inventoryService = m_scene.InventoryService;
94
95 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
96 }
97
98 public void PostInitialise() {}
99
100 public void Close() {}
101
102 public string Name { get { return "FetchInventory2Module"; } }
103
104 public Type ReplaceableInterface
105 {
106 get { return null; }
107 }
108
109 #endregion
110
111 private void RegisterCaps(UUID agentID, Caps caps)
112 {
113 RegisterFetchCap(agentID, caps, "FetchInventory2", m_fetchInventory2Url);
114 }
115
116 private void RegisterFetchCap(UUID agentID, Caps caps, string capName, string url)
117 {
118 string capUrl;
119
120 if (url == "localhost")
121 {
122 capUrl = "/CAPS/" + UUID.Random();
123
124 FetchInventory2Handler fetchHandler = new FetchInventory2Handler(m_inventoryService, agentID);
125
126 IRequestHandler reqHandler
127 = new RestStreamHandler(
128 "POST", capUrl, fetchHandler.FetchInventoryRequest, capName, agentID.ToString());
129
130 caps.RegisterHandler(capName, reqHandler);
131 }
132 else
133 {
134 capUrl = url;
135
136 caps.RegisterHandler(capName, capUrl);
137 }
138
139// m_log.DebugFormat(
140// "[FETCH INVENTORY2 MODULE]: Registered capability {0} at {1} in region {2} for {3}",
141// capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
142 }
143 }
144}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs
new file mode 100644
index 0000000..6617bbc
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetDisplayNamesModule.cs
@@ -0,0 +1,144 @@
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.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection;
34using System.IO;
35using System.Web;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenMetaverse.Imaging;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces;
48using Caps = OpenSim.Framework.Capabilities.Caps;
49using OpenSim.Capabilities.Handlers;
50
51namespace OpenSim.Region.ClientStack.Linden
52{
53
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetDisplayNamesModule")]
55 public class GetDisplayNamesModule : INonSharedRegionModule
56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
60 private Scene m_scene;
61 private IUserManagement m_UserManager;
62
63 private bool m_Enabled = false;
64
65 private string m_URL;
66
67 #region ISharedRegionModule Members
68
69 public void Initialise(IConfigSource source)
70 {
71 IConfig config = source.Configs["ClientStack.LindenCaps"];
72 if (config == null)
73 return;
74
75 m_URL = config.GetString("Cap_GetDisplayNames", string.Empty);
76 if (m_URL != string.Empty)
77 m_Enabled = true;
78 }
79
80 public void AddRegion(Scene s)
81 {
82 if (!m_Enabled)
83 return;
84
85 m_scene = s;
86 }
87
88 public void RemoveRegion(Scene s)
89 {
90 if (!m_Enabled)
91 return;
92
93 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
94 m_scene = null;
95 }
96
97 public void RegionLoaded(Scene s)
98 {
99 if (!m_Enabled)
100 return;
101
102 m_UserManager = m_scene.RequestModuleInterface<IUserManagement>();
103 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
104 }
105
106 public void PostInitialise()
107 {
108 }
109
110 public void Close() { }
111
112 public string Name { get { return "GetDisplayNamesModule"; } }
113
114 public Type ReplaceableInterface
115 {
116 get { return null; }
117 }
118
119 #endregion
120
121 public void RegisterCaps(UUID agentID, Caps caps)
122 {
123 UUID capID = UUID.Random();
124
125 if (m_URL == "localhost")
126 {
127 m_log.DebugFormat("[GET_DISPLAY_NAMES]: /CAPS/agents/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
128 caps.RegisterHandler(
129 "GetDisplayNames",
130 new GetDisplayNamesHandler("/CAPS/agents" + capID + "/", m_UserManager, "GetDisplayNames", agentID.ToString()));
131 }
132 else
133 {
134// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
135 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
136 if (handler != null)
137 handler.RegisterExternalUserCapsHandler(agentID,caps,"GetDisplayNames", m_URL);
138 else
139 caps.RegisterHandler("GetDisplayNames", m_URL);
140 }
141 }
142
143 }
144}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
new file mode 100644
index 0000000..f57d857
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -0,0 +1,169 @@
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.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Capabilities.Handlers;
40using OpenSim.Framework;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47
48namespace OpenSim.Region.ClientStack.Linden
49{
50 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetMeshModule")]
51 public class GetMeshModule : INonSharedRegionModule
52 {
53// private static readonly ILog m_log =
54// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57 private IAssetService m_AssetService;
58 private bool m_Enabled = true;
59 private string m_URL;
60 private string m_URL2;
61 private string m_RedirectURL = null;
62 private string m_RedirectURL2 = null;
63
64 #region Region Module interfaceBase Members
65
66 public Type ReplaceableInterface
67 {
68 get { return null; }
69 }
70
71 public void Initialise(IConfigSource source)
72 {
73 IConfig config = source.Configs["ClientStack.LindenCaps"];
74 if (config == null)
75 return;
76
77 m_URL = config.GetString("Cap_GetMesh", string.Empty);
78 // Cap doesn't exist
79 if (m_URL != string.Empty)
80 {
81 m_Enabled = true;
82 m_RedirectURL = config.GetString("GetMeshRedirectURL");
83 }
84
85 m_URL2 = config.GetString("Cap_GetMesh2", string.Empty);
86 // Cap doesn't exist
87 if (m_URL2 != string.Empty)
88 {
89 m_Enabled = true;
90 m_RedirectURL2 = config.GetString("GetMesh2RedirectURL");
91 }
92 }
93
94 public void AddRegion(Scene pScene)
95 {
96 if (!m_Enabled)
97 return;
98
99 m_scene = pScene;
100 }
101
102 public void RemoveRegion(Scene scene)
103 {
104 if (!m_Enabled)
105 return;
106
107 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
108 m_scene = null;
109 }
110
111 public void RegionLoaded(Scene scene)
112 {
113 if (!m_Enabled)
114 return;
115
116 m_AssetService = m_scene.RequestModuleInterface<IAssetService>();
117 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
118 }
119
120
121 public void Close() { }
122
123 public string Name { get { return "GetMeshModule"; } }
124
125 #endregion
126
127
128 public void RegisterCaps(UUID agentID, Caps caps)
129 {
130 UUID capID = UUID.Random();
131 bool getMeshRegistered = false;
132
133 if (m_URL == string.Empty)
134 {
135
136 }
137 else if (m_URL == "localhost")
138 {
139 getMeshRegistered = true;
140 caps.RegisterHandler(
141 "GetMesh",
142 new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh", agentID.ToString(), m_RedirectURL));
143 }
144 else
145 {
146 caps.RegisterHandler("GetMesh", m_URL);
147 }
148
149 if(m_URL2 == string.Empty)
150 {
151
152 }
153 else if (m_URL2 == "localhost")
154 {
155 if (!getMeshRegistered)
156 {
157 caps.RegisterHandler(
158 "GetMesh2",
159 new GetMeshHandler("/CAPS/" + capID + "/", m_AssetService, "GetMesh2", agentID.ToString(), m_RedirectURL2));
160 }
161 }
162 else
163 {
164 caps.RegisterHandler("GetMesh2", m_URL2);
165 }
166 }
167
168 }
169}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
new file mode 100644
index 0000000..bb932f2
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -0,0 +1,152 @@
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.Specialized;
31using System.Drawing;
32using System.Drawing.Imaging;
33using System.Reflection;
34using System.IO;
35using System.Web;
36using log4net;
37using Nini.Config;
38using Mono.Addins;
39using OpenMetaverse;
40using OpenMetaverse.StructuredData;
41using OpenMetaverse.Imaging;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Services.Interfaces;
48using Caps = OpenSim.Framework.Capabilities.Caps;
49using OpenSim.Capabilities.Handlers;
50
51namespace OpenSim.Region.ClientStack.Linden
52{
53
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "GetTextureModule")]
55 public class GetTextureModule : INonSharedRegionModule
56 {
57// private static readonly ILog m_log =
58// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
60 private Scene m_scene;
61 private IAssetService m_assetService;
62
63 private bool m_Enabled = false;
64
65 // TODO: Change this to a config option
66 private string m_RedirectURL = null;
67
68 private string m_URL;
69
70 #region ISharedRegionModule Members
71
72 public void Initialise(IConfigSource source)
73 {
74 IConfig config = source.Configs["ClientStack.LindenCaps"];
75 if (config == null)
76 return;
77
78 m_URL = config.GetString("Cap_GetTexture", string.Empty);
79 // Cap doesn't exist
80 if (m_URL != string.Empty)
81 {
82 m_Enabled = true;
83 m_RedirectURL = config.GetString("GetTextureRedirectURL");
84 }
85 }
86
87 public void AddRegion(Scene s)
88 {
89 if (!m_Enabled)
90 return;
91
92 m_scene = s;
93 }
94
95 public void RemoveRegion(Scene s)
96 {
97 if (!m_Enabled)
98 return;
99
100 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
101 m_scene = null;
102 }
103
104 public void RegionLoaded(Scene s)
105 {
106 if (!m_Enabled)
107 return;
108
109 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
110 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
111 }
112
113 public void PostInitialise()
114 {
115 }
116
117 public void Close() { }
118
119 public string Name { get { return "GetTextureModule"; } }
120
121 public Type ReplaceableInterface
122 {
123 get { return null; }
124 }
125
126 #endregion
127
128 public void RegisterCaps(UUID agentID, Caps caps)
129 {
130 UUID capID = UUID.Random();
131
132 //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
133 if (m_URL == "localhost")
134 {
135// m_log.DebugFormat("[GETTEXTURE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
136 caps.RegisterHandler(
137 "GetTexture",
138 new GetTextureHandler("/CAPS/" + capID + "/", m_assetService, "GetTexture", agentID.ToString(), m_RedirectURL));
139 }
140 else
141 {
142// m_log.DebugFormat("[GETTEXTURE]: {0} in region {1}", m_URL, m_scene.RegionInfo.RegionName);
143 IExternalCapsModule handler = m_scene.RequestModuleInterface<IExternalCapsModule>();
144 if (handler != null)
145 handler.RegisterExternalUserCapsHandler(agentID,caps,"GetTexture", m_URL);
146 else
147 caps.RegisterHandler("GetTexture", m_URL);
148 }
149 }
150
151 }
152}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
new file mode 100644
index 0000000..45d33cd
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/MeshUploadFlagModule.cs
@@ -0,0 +1,151 @@
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.Reflection;
31using log4net;
32using Nini.Config;
33using Mono.Addins;
34using OpenMetaverse;
35using OpenMetaverse.StructuredData;
36using OpenSim.Framework;
37using OpenSim.Framework.Servers.HttpServer;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using Caps = OpenSim.Framework.Capabilities.Caps;
42
43namespace OpenSim.Region.ClientStack.Linden
44{
45 /// <summary>
46 /// MeshUploadFlag capability. This is required for uploading Mesh.
47 /// </summary>
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MeshUploadFlagModule")]
49 public class MeshUploadFlagModule : INonSharedRegionModule
50 {
51// private static readonly ILog m_log =
52// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 /// <summary>
55 /// Is this module enabled?
56 /// </summary>
57 public bool Enabled { get; private set; }
58
59 private Scene m_scene;
60
61 #region ISharedRegionModule Members
62
63 public MeshUploadFlagModule()
64 {
65 Enabled = true;
66 }
67
68 public void Initialise(IConfigSource source)
69 {
70 IConfig config = source.Configs["Mesh"];
71 if (config == null)
72 {
73 return;
74 }
75 else
76 {
77 Enabled = config.GetBoolean("AllowMeshUpload", Enabled);
78 }
79 }
80
81 public void AddRegion(Scene s)
82 {
83 if (!Enabled)
84 return;
85
86 m_scene = s;
87 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
88 }
89
90 public void RemoveRegion(Scene s)
91 {
92 if (!Enabled)
93 return;
94
95 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
96 }
97
98 public void RegionLoaded(Scene s)
99 {
100 }
101
102 public void PostInitialise()
103 {
104 }
105
106 public void Close() { }
107
108 public string Name { get { return "MeshUploadFlagModule"; } }
109
110 public Type ReplaceableInterface
111 {
112 get { return null; }
113 }
114
115 #endregion
116
117 public void RegisterCaps(UUID agentID, Caps caps)
118 {
119 IRequestHandler reqHandler
120 = new RestHTTPHandler(
121 "GET", "/CAPS/" + UUID.Random(), ht => MeshUploadFlag(ht, agentID), "MeshUploadFlag", agentID.ToString());
122
123 caps.RegisterHandler("MeshUploadFlag", reqHandler);
124
125 }
126
127 private Hashtable MeshUploadFlag(Hashtable mDhttpMethod, UUID agentID)
128 {
129// m_log.DebugFormat("[MESH UPLOAD FLAG MODULE]: MeshUploadFlag request");
130
131 OSDMap data = new OSDMap();
132 ScenePresence sp = m_scene.GetScenePresence(agentID);
133 data["username"] = sp.Firstname + "." + sp.Lastname;
134 data["display_name_next_update"] = new OSDDate(DateTime.Now);
135 data["legacy_first_name"] = sp.Firstname;
136 data["mesh_upload_status"] = "valid";
137 data["display_name"] = sp.Firstname + " " + sp.Lastname;
138 data["legacy_last_name"] = sp.Lastname;
139 data["id"] = agentID;
140 data["is_display_name_default"] = true;
141
142 //Send back data
143 Hashtable responsedata = new Hashtable();
144 responsedata["int_response_code"] = 200;
145 responsedata["content_type"] = "text/plain";
146 responsedata["keepalive"] = false;
147 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(data);
148 return responsedata;
149 }
150 }
151} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
new file mode 100644
index 0000000..f69a0bb
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/NewFileAgentInventoryVariablePriceModule.cs
@@ -0,0 +1,297 @@
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.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenSim.Framework;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Services.Interfaces;
45using Caps = OpenSim.Framework.Capabilities.Caps;
46using OpenSim.Framework.Capabilities;
47using PermissionMask = OpenSim.Framework.PermissionMask;
48
49namespace OpenSim.Region.ClientStack.Linden
50{
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "NewFileAgentInventoryVariablePriceModule")]
52 public class NewFileAgentInventoryVariablePriceModule : INonSharedRegionModule
53 {
54// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Scene m_scene;
57// private IAssetService m_assetService;
58 private bool m_dumpAssetsToFile = false;
59 private bool m_enabled = true;
60 private int m_levelUpload = 0;
61
62 #region Region Module interfaceBase Members
63
64
65 public Type ReplaceableInterface
66 {
67 get { return null; }
68 }
69
70 public void Initialise(IConfigSource source)
71 {
72 IConfig meshConfig = source.Configs["Mesh"];
73 if (meshConfig == null)
74 return;
75
76 m_enabled = meshConfig.GetBoolean("AllowMeshUpload", true);
77 m_levelUpload = meshConfig.GetInt("LevelUpload", 0);
78 }
79
80 public void AddRegion(Scene pScene)
81 {
82 m_scene = pScene;
83 }
84
85 public void RemoveRegion(Scene scene)
86 {
87
88 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
89 m_scene = null;
90 }
91
92 public void RegionLoaded(Scene scene)
93 {
94
95// m_assetService = m_scene.RequestModuleInterface<IAssetService>();
96 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
97 }
98
99 #endregion
100
101
102 #region Region Module interface
103
104
105
106 public void Close() { }
107
108 public string Name { get { return "NewFileAgentInventoryVariablePriceModule"; } }
109
110
111 public void RegisterCaps(UUID agentID, Caps caps)
112 {
113 if(!m_enabled)
114 return;
115
116 UUID capID = UUID.Random();
117
118// m_log.Debug("[NEW FILE AGENT INVENTORY VARIABLE PRICE]: /CAPS/" + capID);
119 caps.RegisterHandler(
120 "NewFileAgentInventoryVariablePrice",
121 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>(
122 "POST",
123 "/CAPS/" + capID.ToString(),
124 req => NewAgentInventoryRequest(req, agentID),
125 "NewFileAgentInventoryVariablePrice",
126 agentID.ToString()));
127 }
128
129 #endregion
130
131 public LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID)
132 {
133 //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit
134 // you need to be aware of this
135
136 //if (llsdRequest.asset_type == "texture" ||
137 // llsdRequest.asset_type == "animation" ||
138 // llsdRequest.asset_type == "sound")
139 // {
140 // check user level
141
142 ScenePresence avatar = null;
143 IClientAPI client = null;
144 m_scene.TryGetScenePresence(agentID, out avatar);
145
146 if (avatar != null)
147 {
148 client = avatar.ControllingClient;
149
150 if (avatar.UserLevel < m_levelUpload)
151 {
152 if (client != null)
153 client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false);
154
155 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
156 errorResponse.rsvp = "";
157 errorResponse.state = "error";
158 return errorResponse;
159 }
160 }
161
162 // check funds
163 IMoneyModule mm = m_scene.RequestModuleInterface<IMoneyModule>();
164
165 if (mm != null)
166 {
167 if (!mm.UploadCovered(agentID, mm.UploadCharge))
168 {
169 if (client != null)
170 client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false);
171
172 LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
173 errorResponse.rsvp = "";
174 errorResponse.state = "error";
175 return errorResponse;
176 }
177 }
178
179 // }
180
181 string assetName = llsdRequest.name;
182 string assetDes = llsdRequest.description;
183 string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/";
184 UUID newAsset = UUID.Random();
185 UUID newInvItem = UUID.Random();
186 UUID parentFolder = llsdRequest.folder_id;
187 string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/";
188
189 AssetUploader uploader =
190 new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type,
191 llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile);
192
193 MainServer.Instance.AddStreamHandler(
194 new BinaryStreamHandler(
195 "POST",
196 capsBase + uploaderPath,
197 uploader.uploaderCaps,
198 "NewFileAgentInventoryVariablePrice",
199 agentID.ToString()));
200
201 string protocol = "http://";
202
203 if (MainServer.Instance.UseSSL)
204 protocol = "https://";
205
206 string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase +
207 uploaderPath;
208
209
210 LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse();
211
212 uploadResponse.rsvp = uploaderURL;
213 uploadResponse.state = "upload";
214 uploadResponse.resource_cost = 0;
215 uploadResponse.upload_price = 0;
216
217 uploader.OnUpLoad += //UploadCompleteHandler;
218
219 delegate(
220 string passetName, string passetDescription, UUID passetID,
221 UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType,
222 string passetType)
223 {
224 UploadCompleteHandler(passetName, passetDescription, passetID,
225 pinventoryItem, pparentFolder, pdata, pinventoryType,
226 passetType,agentID);
227 };
228
229 return uploadResponse;
230 }
231
232 public void UploadCompleteHandler(string assetName, string assetDescription, UUID assetID,
233 UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType,
234 string assetType,UUID AgentID)
235 {
236// m_log.DebugFormat(
237// "[NEW FILE AGENT INVENTORY VARIABLE PRICE MODULE]: Upload complete for {0}", inventoryItem);
238
239 sbyte assType = 0;
240 sbyte inType = 0;
241
242 if (inventoryType == "sound")
243 {
244 inType = 1;
245 assType = 1;
246 }
247 else if (inventoryType == "animation")
248 {
249 inType = 19;
250 assType = 20;
251 }
252 else if (inventoryType == "wearable")
253 {
254 inType = 18;
255 switch (assetType)
256 {
257 case "bodypart":
258 assType = 13;
259 break;
260 case "clothing":
261 assType = 5;
262 break;
263 }
264 }
265 else if (inventoryType == "mesh")
266 {
267 inType = (sbyte)InventoryType.Mesh;
268 assType = (sbyte)AssetType.Mesh;
269 }
270
271 AssetBase asset;
272 asset = new AssetBase(assetID, assetName, assType, AgentID.ToString());
273 asset.Data = data;
274
275 if (m_scene.AssetService != null)
276 m_scene.AssetService.Store(asset);
277
278 InventoryItemBase item = new InventoryItemBase();
279 item.Owner = AgentID;
280 item.CreatorId = AgentID.ToString();
281 item.ID = inventoryItem;
282 item.AssetID = asset.FullID;
283 item.Description = assetDescription;
284 item.Name = assetName;
285 item.AssetType = assType;
286 item.InvType = inType;
287 item.Folder = parentFolder;
288 item.CurrentPermissions
289 = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer);
290 item.BasePermissions = (uint)PermissionMask.All;
291 item.EveryOnePermissions = 0;
292 item.NextPermissions = (uint)PermissionMask.All;
293 item.CreationDate = Util.UnixTimeSinceEpoch();
294 m_scene.AddInventoryItem(item);
295 }
296 }
297}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
new file mode 100644
index 0000000..94f8bc1
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/ObjectAdd.cs
@@ -0,0 +1,389 @@
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.Reflection;
31using log4net;
32using Nini.Config;
33using OpenMetaverse;
34using OpenMetaverse.StructuredData;
35using Mono.Addins;
36using OpenSim.Framework;
37using OpenSim.Framework.Servers;
38using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using Caps=OpenSim.Framework.Capabilities.Caps;
42
43namespace OpenSim.Region.ClientStack.Linden
44{
45 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ObjectAdd")]
46 public class ObjectAdd : INonSharedRegionModule
47 {
48// private static readonly ILog m_log =
49// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50
51 private Scene m_scene;
52
53 #region INonSharedRegionModule Members
54
55 public void Initialise(IConfigSource pSource)
56 {
57 }
58
59 public void AddRegion(Scene scene)
60 {
61 m_scene = scene;
62 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
63 }
64
65 public void RemoveRegion(Scene scene)
66 {
67 if (m_scene == scene)
68 {
69 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
70 m_scene = null;
71 }
72 }
73
74 public void RegionLoaded(Scene scene)
75 {
76 }
77
78 public void Close()
79 {
80 }
81
82 public string Name
83 {
84 get { return "ObjectAddModule"; }
85 }
86
87 public Type ReplaceableInterface
88 {
89 get { return null; }
90 }
91
92 #endregion
93
94 public void RegisterCaps(UUID agentID, Caps caps)
95 {
96 UUID capuuid = UUID.Random();
97
98 // m_log.InfoFormat("[OBJECTADD]: {0}", "/CAPS/OA/" + capuuid + "/");
99
100 caps.RegisterHandler(
101 "ObjectAdd",
102 new RestHTTPHandler(
103 "POST",
104 "/CAPS/OA/" + capuuid + "/",
105 httpMethod => ProcessAdd(httpMethod, agentID, caps),
106 "ObjectAdd",
107 agentID.ToString())); ;
108 }
109
110 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
111 {
112 Hashtable responsedata = new Hashtable();
113 responsedata["int_response_code"] = 400; //501; //410; //404;
114 responsedata["content_type"] = "text/plain";
115 responsedata["keepalive"] = false;
116 responsedata["str_response_string"] = "Request wasn't what was expected";
117 ScenePresence avatar;
118
119 if (!m_scene.TryGetScenePresence(AgentId, out avatar))
120 return responsedata;
121
122
123 OSD r = OSDParser.DeserializeLLSDXml((string)request["requestbody"]);
124 //UUID session_id = UUID.Zero;
125 bool bypass_raycast = false;
126 uint everyone_mask = 0;
127 uint group_mask = 0;
128 uint next_owner_mask = 0;
129 uint flags = 0;
130 UUID group_id = UUID.Zero;
131 int hollow = 0;
132 int material = 0;
133 int p_code = 0;
134 int path_begin = 0;
135 int path_curve = 0;
136 int path_end = 0;
137 int path_radius_offset = 0;
138 int path_revolutions = 0;
139 int path_scale_x = 0;
140 int path_scale_y = 0;
141 int path_shear_x = 0;
142 int path_shear_y = 0;
143 int path_skew = 0;
144 int path_taper_x = 0;
145 int path_taper_y = 0;
146 int path_twist = 0;
147 int path_twist_begin = 0;
148 int profile_begin = 0;
149 int profile_curve = 0;
150 int profile_end = 0;
151 Vector3 ray_end = Vector3.Zero;
152 bool ray_end_is_intersection = false;
153 Vector3 ray_start = Vector3.Zero;
154 UUID ray_target_id = UUID.Zero;
155 Quaternion rotation = Quaternion.Identity;
156 Vector3 scale = Vector3.Zero;
157 int state = 0;
158 int lastattach = 0;
159
160 if (r.Type != OSDType.Map) // not a proper req
161 return responsedata;
162
163 OSDMap rm = (OSDMap)r;
164
165 if (rm.ContainsKey("ObjectData")) //v2
166 {
167 if (rm["ObjectData"].Type != OSDType.Map)
168 {
169 responsedata["str_response_string"] = "Has ObjectData key, but data not in expected format";
170 return responsedata;
171 }
172
173 OSDMap ObjMap = (OSDMap)rm["ObjectData"];
174
175 bypass_raycast = ObjMap["BypassRaycast"].AsBoolean();
176 everyone_mask = readuintval(ObjMap["EveryoneMask"]);
177 flags = readuintval(ObjMap["Flags"]);
178 group_mask = readuintval(ObjMap["GroupMask"]);
179 material = ObjMap["Material"].AsInteger();
180 next_owner_mask = readuintval(ObjMap["NextOwnerMask"]);
181 p_code = ObjMap["PCode"].AsInteger();
182
183 if (ObjMap.ContainsKey("Path"))
184 {
185 if (ObjMap["Path"].Type != OSDType.Map)
186 {
187 responsedata["str_response_string"] = "Has Path key, but data not in expected format";
188 return responsedata;
189 }
190
191 OSDMap PathMap = (OSDMap)ObjMap["Path"];
192 path_begin = PathMap["Begin"].AsInteger();
193 path_curve = PathMap["Curve"].AsInteger();
194 path_end = PathMap["End"].AsInteger();
195 path_radius_offset = PathMap["RadiusOffset"].AsInteger();
196 path_revolutions = PathMap["Revolutions"].AsInteger();
197 path_scale_x = PathMap["ScaleX"].AsInteger();
198 path_scale_y = PathMap["ScaleY"].AsInteger();
199 path_shear_x = PathMap["ShearX"].AsInteger();
200 path_shear_y = PathMap["ShearY"].AsInteger();
201 path_skew = PathMap["Skew"].AsInteger();
202 path_taper_x = PathMap["TaperX"].AsInteger();
203 path_taper_y = PathMap["TaperY"].AsInteger();
204 path_twist = PathMap["Twist"].AsInteger();
205 path_twist_begin = PathMap["TwistBegin"].AsInteger();
206
207 }
208
209 if (ObjMap.ContainsKey("Profile"))
210 {
211 if (ObjMap["Profile"].Type != OSDType.Map)
212 {
213 responsedata["str_response_string"] = "Has Profile key, but data not in expected format";
214 return responsedata;
215 }
216
217 OSDMap ProfileMap = (OSDMap)ObjMap["Profile"];
218
219 profile_begin = ProfileMap["Begin"].AsInteger();
220 profile_curve = ProfileMap["Curve"].AsInteger();
221 profile_end = ProfileMap["End"].AsInteger();
222 hollow = ProfileMap["Hollow"].AsInteger();
223 }
224 ray_end_is_intersection = ObjMap["RayEndIsIntersection"].AsBoolean();
225
226 ray_target_id = ObjMap["RayTargetId"].AsUUID();
227 state = ObjMap["State"].AsInteger();
228 lastattach = ObjMap["LastAttachPoint"].AsInteger();
229 try
230 {
231 ray_end = ((OSDArray)ObjMap["RayEnd"]).AsVector3();
232 ray_start = ((OSDArray)ObjMap["RayStart"]).AsVector3();
233 scale = ((OSDArray)ObjMap["Scale"]).AsVector3();
234 rotation = ((OSDArray)ObjMap["Rotation"]).AsQuaternion();
235 }
236 catch (Exception)
237 {
238 responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
239 return responsedata;
240 }
241
242 if (rm.ContainsKey("AgentData"))
243 {
244 if (rm["AgentData"].Type != OSDType.Map)
245 {
246 responsedata["str_response_string"] = "Has AgentData key, but data not in expected format";
247 return responsedata;
248 }
249
250 OSDMap AgentDataMap = (OSDMap)rm["AgentData"];
251
252 //session_id = AgentDataMap["SessionId"].AsUUID();
253 group_id = AgentDataMap["GroupId"].AsUUID();
254 }
255
256 }
257 else
258 { //v1
259 bypass_raycast = rm["bypass_raycast"].AsBoolean();
260
261 everyone_mask = readuintval(rm["everyone_mask"]);
262 flags = readuintval(rm["flags"]);
263 group_id = rm["group_id"].AsUUID();
264 group_mask = readuintval(rm["group_mask"]);
265 hollow = rm["hollow"].AsInteger();
266 material = rm["material"].AsInteger();
267 next_owner_mask = readuintval(rm["next_owner_mask"]);
268 hollow = rm["hollow"].AsInteger();
269 p_code = rm["p_code"].AsInteger();
270 path_begin = rm["path_begin"].AsInteger();
271 path_curve = rm["path_curve"].AsInteger();
272 path_end = rm["path_end"].AsInteger();
273 path_radius_offset = rm["path_radius_offset"].AsInteger();
274 path_revolutions = rm["path_revolutions"].AsInteger();
275 path_scale_x = rm["path_scale_x"].AsInteger();
276 path_scale_y = rm["path_scale_y"].AsInteger();
277 path_shear_x = rm["path_shear_x"].AsInteger();
278 path_shear_y = rm["path_shear_y"].AsInteger();
279 path_skew = rm["path_skew"].AsInteger();
280 path_taper_x = rm["path_taper_x"].AsInteger();
281 path_taper_y = rm["path_taper_y"].AsInteger();
282 path_twist = rm["path_twist"].AsInteger();
283 path_twist_begin = rm["path_twist_begin"].AsInteger();
284 profile_begin = rm["profile_begin"].AsInteger();
285 profile_curve = rm["profile_curve"].AsInteger();
286 profile_end = rm["profile_end"].AsInteger();
287
288 ray_end_is_intersection = rm["ray_end_is_intersection"].AsBoolean();
289
290 ray_target_id = rm["ray_target_id"].AsUUID();
291
292
293 //session_id = rm["session_id"].AsUUID();
294 state = rm["state"].AsInteger();
295 lastattach = rm["last_attach_point"].AsInteger();
296 try
297 {
298 ray_end = ((OSDArray)rm["ray_end"]).AsVector3();
299 ray_start = ((OSDArray)rm["ray_start"]).AsVector3();
300 rotation = ((OSDArray)rm["rotation"]).AsQuaternion();
301 scale = ((OSDArray)rm["scale"]).AsVector3();
302 }
303 catch (Exception)
304 {
305 responsedata["str_response_string"] = "RayEnd, RayStart, Scale or Rotation wasn't in the expected format";
306 return responsedata;
307 }
308 }
309
310
311
312 Vector3 pos = m_scene.GetNewRezLocation(ray_start, ray_end, ray_target_id, rotation, (bypass_raycast) ? (byte)1 : (byte)0, (ray_end_is_intersection) ? (byte)1 : (byte)0, true, scale, false);
313
314 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
315
316 pbs.PathBegin = (ushort)path_begin;
317 pbs.PathCurve = (byte)path_curve;
318 pbs.PathEnd = (ushort)path_end;
319 pbs.PathRadiusOffset = (sbyte)path_radius_offset;
320 pbs.PathRevolutions = (byte)path_revolutions;
321 pbs.PathScaleX = (byte)path_scale_x;
322 pbs.PathScaleY = (byte)path_scale_y;
323 pbs.PathShearX = (byte)path_shear_x;
324 pbs.PathShearY = (byte)path_shear_y;
325 pbs.PathSkew = (sbyte)path_skew;
326 pbs.PathTaperX = (sbyte)path_taper_x;
327 pbs.PathTaperY = (sbyte)path_taper_y;
328 pbs.PathTwist = (sbyte)path_twist;
329 pbs.PathTwistBegin = (sbyte)path_twist_begin;
330 pbs.HollowShape = (HollowShape)hollow;
331 pbs.PCode = (byte)p_code;
332 pbs.ProfileBegin = (ushort)profile_begin;
333 pbs.ProfileCurve = (byte)profile_curve;
334 pbs.ProfileEnd = (ushort)profile_end;
335 pbs.Scale = scale;
336 pbs.State = (byte)state;
337 pbs.LastAttachPoint = (byte)lastattach;
338
339 SceneObjectGroup obj = null; ;
340
341 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
342 {
343 // rez ON the ground, not IN the ground
344 // pos.Z += 0.25F;
345
346 obj = m_scene.AddNewPrim(avatar.UUID, group_id, pos, rotation, pbs);
347 }
348
349
350 if (obj == null)
351 return responsedata;
352
353 SceneObjectPart rootpart = obj.RootPart;
354 rootpart.Shape = pbs;
355 rootpart.Flags |= (PrimFlags)flags;
356 rootpart.EveryoneMask = everyone_mask;
357 rootpart.GroupID = group_id;
358 rootpart.GroupMask = group_mask;
359 rootpart.NextOwnerMask = next_owner_mask;
360 rootpart.Material = (byte)material;
361
362 m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor);
363
364 responsedata["int_response_code"] = 200; //501; //410; //404;
365 responsedata["content_type"] = "text/plain";
366 responsedata["keepalive"] = false;
367 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(obj.LocalId));
368
369 return responsedata;
370 }
371
372 private uint readuintval(OSD obj)
373 {
374 byte[] tmp = obj.AsBinary();
375 if (BitConverter.IsLittleEndian)
376 Array.Reverse(tmp);
377 return Utils.BytesToUInt(tmp);
378
379 }
380 private string ConvertUintToBytes(uint val)
381 {
382 byte[] resultbytes = Utils.UIntToBytes(val);
383 if (BitConverter.IsLittleEndian)
384 Array.Reverse(resultbytes);
385 return String.Format("<binary encoding=\"base64\">{0}</binary>", Convert.ToBase64String(resultbytes));
386 }
387
388 }
389}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
new file mode 100644
index 0000000..769fe28
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs
@@ -0,0 +1,378 @@
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.Specialized;
31using System.Reflection;
32using System.IO;
33using System.Web;
34using Mono.Addins;
35using log4net;
36using Nini.Config;
37using OpenMetaverse;
38using OpenMetaverse.StructuredData;
39using OpenMetaverse.Messages.Linden;
40using OpenSim.Framework;
41using OpenSim.Framework.Servers;
42using OpenSim.Framework.Servers.HttpServer;
43using OpenSim.Region.Framework.Interfaces;
44using OpenSim.Region.Framework.Scenes;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47using OSD = OpenMetaverse.StructuredData.OSD;
48using OSDMap = OpenMetaverse.StructuredData.OSDMap;
49using OpenSim.Framework.Capabilities;
50using ExtraParamType = OpenMetaverse.ExtraParamType;
51
52namespace OpenSim.Region.ClientStack.Linden
53{
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadObjectAssetModule")]
55 public class UploadObjectAssetModule : INonSharedRegionModule
56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 private Scene m_scene;
60
61 #region Region Module interfaceBase Members
62
63
64 public Type ReplaceableInterface
65 {
66 get { return null; }
67 }
68
69 public void Initialise(IConfigSource source)
70 {
71
72 }
73
74 public void AddRegion(Scene pScene)
75 {
76 m_scene = pScene;
77 }
78
79 public void RemoveRegion(Scene scene)
80 {
81
82 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
83 m_scene = null;
84 }
85
86 public void RegionLoaded(Scene scene)
87 {
88
89 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
90 }
91
92 #endregion
93
94
95 #region Region Module interface
96
97
98
99 public void Close() { }
100
101 public string Name { get { return "UploadObjectAssetModuleModule"; } }
102
103
104 public void RegisterCaps(UUID agentID, Caps caps)
105 {
106 UUID capID = UUID.Random();
107
108// m_log.Debug("[UPLOAD OBJECT ASSET MODULE]: /CAPS/" + capID);
109 caps.RegisterHandler(
110 "UploadObjectAsset",
111 new RestHTTPHandler(
112 "POST",
113 "/CAPS/OA/" + capID + "/",
114 httpMethod => ProcessAdd(httpMethod, agentID, caps),
115 "UploadObjectAsset",
116 agentID.ToString()));
117
118 /*
119 caps.RegisterHandler("NewFileAgentInventoryVariablePrice",
120
121 new LLSDStreamhandler<LLSDAssetUploadRequest, LLSDNewFileAngentInventoryVariablePriceReplyResponse>("POST",
122 "/CAPS/" + capID.ToString(),
123 delegate(LLSDAssetUploadRequest req)
124 {
125 return NewAgentInventoryRequest(req,agentID);
126 }));
127 */
128
129 }
130
131 #endregion
132
133
134 /// <summary>
135 /// Parses add request
136 /// </summary>
137 /// <param name="request"></param>
138 /// <param name="AgentId"></param>
139 /// <param name="cap"></param>
140 /// <returns></returns>
141 public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap)
142 {
143 Hashtable responsedata = new Hashtable();
144 responsedata["int_response_code"] = 400; //501; //410; //404;
145 responsedata["content_type"] = "text/plain";
146 responsedata["keepalive"] = false;
147 responsedata["str_response_string"] = "Request wasn't what was expected";
148 ScenePresence avatar;
149
150 if (!m_scene.TryGetScenePresence(AgentId, out avatar))
151 return responsedata;
152
153 OSDMap r = (OSDMap)OSDParser.Deserialize((string)request["requestbody"]);
154 UploadObjectAssetMessage message = new UploadObjectAssetMessage();
155 try
156 {
157 message.Deserialize(r);
158
159 }
160 catch (Exception ex)
161 {
162 m_log.Error("[UPLOAD OBJECT ASSET MODULE]: Error deserializing message " + ex.ToString());
163 message = null;
164 }
165
166 if (message == null)
167 {
168 responsedata["int_response_code"] = 400; //501; //410; //404;
169 responsedata["content_type"] = "text/plain";
170 responsedata["keepalive"] = false;
171 responsedata["str_response_string"] =
172 "<llsd><map><key>error</key><string>Error parsing Object</string></map></llsd>";
173
174 return responsedata;
175 }
176
177 Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX * avatar.Rotation);
178 Quaternion rot = Quaternion.Identity;
179 Vector3 rootpos = Vector3.Zero;
180// Quaternion rootrot = Quaternion.Identity;
181
182 SceneObjectGroup rootGroup = null;
183 SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length];
184 for (int i = 0; i < message.Objects.Length; i++)
185 {
186 UploadObjectAssetMessage.Object obj = message.Objects[i];
187 PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox();
188
189 if (i == 0)
190 {
191 rootpos = obj.Position;
192// rootrot = obj.Rotation;
193 }
194
195 // Combine the extraparams data into it's ugly blob again....
196 //int bytelength = 0;
197 //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
198 //{
199 // bytelength += obj.ExtraParams[extparams].ExtraParamData.Length;
200 //}
201 //byte[] extraparams = new byte[bytelength];
202 //int position = 0;
203
204
205
206 //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
207 //{
208 // Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position,
209 // obj.ExtraParams[extparams].ExtraParamData.Length);
210 //
211 // position += obj.ExtraParams[extparams].ExtraParamData.Length;
212 // }
213
214 //pbs.ExtraParams = extraparams;
215 for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++)
216 {
217 UploadObjectAssetMessage.Object.ExtraParam extraParam = obj.ExtraParams[extparams];
218 switch ((ushort)extraParam.Type)
219 {
220 case (ushort)ExtraParamType.Sculpt:
221 Primitive.SculptData sculpt = new Primitive.SculptData(extraParam.ExtraParamData, 0);
222
223 pbs.SculptEntry = true;
224
225 pbs.SculptTexture = obj.SculptID;
226 pbs.SculptType = (byte)sculpt.Type;
227
228 break;
229 case (ushort)ExtraParamType.Flexible:
230 Primitive.FlexibleData flex = new Primitive.FlexibleData(extraParam.ExtraParamData, 0);
231 pbs.FlexiEntry = true;
232 pbs.FlexiDrag = flex.Drag;
233 pbs.FlexiForceX = flex.Force.X;
234 pbs.FlexiForceY = flex.Force.Y;
235 pbs.FlexiForceZ = flex.Force.Z;
236 pbs.FlexiGravity = flex.Gravity;
237 pbs.FlexiSoftness = flex.Softness;
238 pbs.FlexiTension = flex.Tension;
239 pbs.FlexiWind = flex.Wind;
240 break;
241 case (ushort)ExtraParamType.Light:
242 Primitive.LightData light = new Primitive.LightData(extraParam.ExtraParamData, 0);
243 pbs.LightColorA = light.Color.A;
244 pbs.LightColorB = light.Color.B;
245 pbs.LightColorG = light.Color.G;
246 pbs.LightColorR = light.Color.R;
247 pbs.LightCutoff = light.Cutoff;
248 pbs.LightEntry = true;
249 pbs.LightFalloff = light.Falloff;
250 pbs.LightIntensity = light.Intensity;
251 pbs.LightRadius = light.Radius;
252 break;
253 case 0x40:
254 pbs.ReadProjectionData(extraParam.ExtraParamData, 0);
255 break;
256 }
257 }
258
259 pbs.PathBegin = (ushort) obj.PathBegin;
260 pbs.PathCurve = (byte) obj.PathCurve;
261 pbs.PathEnd = (ushort) obj.PathEnd;
262 pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset;
263 pbs.PathRevolutions = (byte) obj.Revolutions;
264 pbs.PathScaleX = (byte) obj.ScaleX;
265 pbs.PathScaleY = (byte) obj.ScaleY;
266 pbs.PathShearX = (byte) obj.ShearX;
267 pbs.PathShearY = (byte) obj.ShearY;
268 pbs.PathSkew = (sbyte) obj.Skew;
269 pbs.PathTaperX = (sbyte) obj.TaperX;
270 pbs.PathTaperY = (sbyte) obj.TaperY;
271 pbs.PathTwist = (sbyte) obj.Twist;
272 pbs.PathTwistBegin = (sbyte) obj.TwistBegin;
273 pbs.HollowShape = (HollowShape) obj.ProfileHollow;
274 pbs.PCode = (byte) PCode.Prim;
275 pbs.ProfileBegin = (ushort) obj.ProfileBegin;
276 pbs.ProfileCurve = (byte) obj.ProfileCurve;
277 pbs.ProfileEnd = (ushort) obj.ProfileEnd;
278 pbs.Scale = obj.Scale;
279 pbs.State = (byte) 0;
280 pbs.LastAttachPoint = (byte) 0;
281 SceneObjectPart prim = new SceneObjectPart();
282 prim.UUID = UUID.Random();
283 prim.CreatorID = AgentId;
284 prim.OwnerID = AgentId;
285 prim.GroupID = obj.GroupID;
286 prim.LastOwnerID = prim.OwnerID;
287 prim.CreationDate = Util.UnixTimeSinceEpoch();
288 prim.Name = obj.Name;
289 prim.Description = "";
290
291 prim.PayPrice[0] = -2;
292 prim.PayPrice[1] = -2;
293 prim.PayPrice[2] = -2;
294 prim.PayPrice[3] = -2;
295 prim.PayPrice[4] = -2;
296 Primitive.TextureEntry tmp =
297 new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f"));
298
299 for (int j = 0; j < obj.Faces.Length; j++)
300 {
301 UploadObjectAssetMessage.Object.Face face = obj.Faces[j];
302
303 Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j);
304
305 primFace.Bump = face.Bump;
306 primFace.RGBA = face.Color;
307 primFace.Fullbright = face.Fullbright;
308 primFace.Glow = face.Glow;
309 primFace.TextureID = face.ImageID;
310 primFace.Rotation = face.ImageRot;
311 primFace.MediaFlags = ((face.MediaFlags & 1) != 0);
312
313 primFace.OffsetU = face.OffsetS;
314 primFace.OffsetV = face.OffsetT;
315 primFace.RepeatU = face.ScaleS;
316 primFace.RepeatV = face.ScaleT;
317 primFace.TexMapType = (MappingType) (face.MediaFlags & 6);
318 }
319
320 pbs.TextureEntry = tmp.GetBytes();
321 prim.Shape = pbs;
322 prim.Scale = obj.Scale;
323
324 SceneObjectGroup grp = new SceneObjectGroup();
325
326 grp.SetRootPart(prim);
327 prim.ParentID = 0;
328 if (i == 0)
329 {
330 rootGroup = grp;
331
332 }
333 grp.AttachToScene(m_scene);
334 grp.AbsolutePosition = obj.Position;
335 prim.RotationOffset = obj.Rotation;
336
337 // Required for linking
338 grp.RootPart.ClearUpdateSchedule();
339
340 if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos))
341 {
342 m_scene.AddSceneObject(grp);
343 grp.AbsolutePosition = obj.Position;
344 }
345
346 allparts[i] = grp;
347 }
348
349 for (int j = 1; j < allparts.Length; j++)
350 {
351 // Required for linking
352 rootGroup.RootPart.ClearUpdateSchedule();
353 allparts[j].RootPart.ClearUpdateSchedule();
354 rootGroup.LinkToGroup(allparts[j]);
355 }
356
357 rootGroup.ScheduleGroupForFullUpdate();
358 pos
359 = m_scene.GetNewRezLocation(
360 Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale, false);
361
362 responsedata["int_response_code"] = 200; //501; //410; //404;
363 responsedata["content_type"] = "text/plain";
364 responsedata["keepalive"] = false;
365 responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(allparts[0].LocalId));
366
367 return responsedata;
368 }
369
370 private string ConvertUintToBytes(uint val)
371 {
372 byte[] resultbytes = Utils.UIntToBytes(val);
373 if (BitConverter.IsLittleEndian)
374 Array.Reverse(resultbytes);
375 return String.Format("<binary encoding=\"base64\">{0}</binary>", Convert.ToBase64String(resultbytes));
376 }
377 }
378} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..264eaa3
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3using System.Runtime.InteropServices;
4
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8[assembly: AssemblyTitle("OpenSim.Region.ClientStack.LindenCaps")]
9[assembly: AssemblyDescription("")]
10[assembly: AssemblyConfiguration("")]
11[assembly: AssemblyCompany("http://opensimulator.org")]
12[assembly: AssemblyProduct("OpenSim")]
13[assembly: AssemblyCopyright("OpenSimulator developers")]
14[assembly: AssemblyTrademark("")]
15[assembly: AssemblyCulture("")]
16
17// Setting ComVisible to false makes the types in this assembly not visible
18// to COM components. If you need to access a type in this assembly from
19// COM, set the ComVisible attribute to true on that type.
20[assembly: ComVisible(false)]
21
22// The following GUID is for the ID of the typelib if this project is exposed to COM
23[assembly: Guid("1ae76353-f37f-4fe3-b6df-d11cedf01f2c")]
24
25// Version information for an assembly consists of the following four values:
26//
27// Major Version
28// Minor Version
29// Build Number
30// Revision
31//
32[assembly: AssemblyVersion("0.8.2.*")]
33
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
new file mode 100644
index 0000000..a133a69
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -0,0 +1,234 @@
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.Collections.Specialized;
32using System.Drawing;
33using System.Drawing.Imaging;
34using System.Reflection;
35using System.IO;
36using System.Web;
37using log4net;
38using Nini.Config;
39using Mono.Addins;
40using OpenMetaverse;
41using OpenMetaverse.StructuredData;
42using OpenMetaverse.Imaging;
43using OpenSim.Framework;
44using OpenSim.Framework.Console;
45using OpenSim.Framework.Servers;
46using OpenSim.Framework.Servers.HttpServer;
47using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Services.Interfaces;
50using Caps = OpenSim.Framework.Capabilities.Caps;
51using OpenSim.Capabilities.Handlers;
52
53namespace OpenSim.Region.ClientStack.Linden
54{
55
56 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionConsoleModule")]
57 public class RegionConsoleModule : INonSharedRegionModule, IRegionConsole
58 {
59// private static readonly ILog m_log =
60// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
61
62 private Scene m_scene;
63 private IEventQueue m_eventQueue;
64 private Commands m_commands = new Commands();
65 public ICommands Commands { get { return m_commands; } }
66
67 public void Initialise(IConfigSource source)
68 {
69 m_commands.AddCommand( "Help", false, "help", "help [<item>]", "Display help on a particular command or on a list of commands in a category", Help);
70 }
71
72 public void AddRegion(Scene s)
73 {
74 m_scene = s;
75 m_scene.RegisterModuleInterface<IRegionConsole>(this);
76 }
77
78 public void RemoveRegion(Scene s)
79 {
80 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
81 m_scene = null;
82 }
83
84 public void RegionLoaded(Scene s)
85 {
86 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
87 m_eventQueue = m_scene.RequestModuleInterface<IEventQueue>();
88 }
89
90 public void PostInitialise()
91 {
92 }
93
94 public void Close() { }
95
96 public string Name { get { return "RegionConsoleModule"; } }
97
98 public Type ReplaceableInterface
99 {
100 get { return null; }
101 }
102
103 public void RegisterCaps(UUID agentID, Caps caps)
104 {
105 if (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(agentID))
106 return;
107
108 UUID capID = UUID.Random();
109
110// m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
111 caps.RegisterHandler(
112 "SimConsoleAsync",
113 new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene));
114 }
115
116 public void SendConsoleOutput(UUID agentID, string message)
117 {
118 OSD osd = OSD.FromString(message);
119
120 m_eventQueue.Enqueue(EventQueueHelper.BuildEvent("SimConsoleResponse", osd), agentID);
121 }
122
123 public bool RunCommand(string command, UUID invokerID)
124 {
125 string[] parts = Parser.Parse(command);
126 Array.Resize(ref parts, parts.Length + 1);
127 parts[parts.Length - 1] = invokerID.ToString();
128
129 if (m_commands.Resolve(parts).Length == 0)
130 return false;
131
132 return true;
133 }
134
135 private void Help(string module, string[] cmd)
136 {
137 UUID agentID = new UUID(cmd[cmd.Length - 1]);
138 Array.Resize(ref cmd, cmd.Length - 1);
139
140 List<string> help = Commands.GetHelp(cmd);
141
142 string reply = String.Empty;
143
144 foreach (string s in help)
145 {
146 reply += s + "\n";
147 }
148
149 SendConsoleOutput(agentID, reply);
150 }
151
152 public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn)
153 {
154 m_commands.AddCommand(module, shared, command, help, longhelp, fn);
155 }
156 }
157
158 public class ConsoleHandler : BaseStreamHandler
159 {
160// private static readonly ILog m_log =
161// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
162
163 private RegionConsoleModule m_consoleModule;
164 private UUID m_agentID;
165 private bool m_isGod;
166 private Scene m_scene;
167 private bool m_consoleIsOn = false;
168
169 public ConsoleHandler(string path, string name, UUID agentID, RegionConsoleModule module, Scene scene)
170 :base("POST", path, name, agentID.ToString())
171 {
172 m_agentID = agentID;
173 m_consoleModule = module;
174 m_scene = scene;
175
176 m_isGod = m_scene.Permissions.IsGod(agentID);
177 }
178
179 protected override byte[] ProcessRequest(string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
180 {
181 StreamReader reader = new StreamReader(request);
182 string message = reader.ReadToEnd();
183
184 OSD osd = OSDParser.DeserializeLLSDXml(message);
185
186 string cmd = osd.AsString();
187 if (cmd == "set console on")
188 {
189 if (m_isGod)
190 {
191 MainConsole.Instance.OnOutput += ConsoleSender;
192 m_consoleIsOn = true;
193 m_consoleModule.SendConsoleOutput(m_agentID, "Console is now on");
194 }
195 return new byte[0];
196 }
197 else if (cmd == "set console off")
198 {
199 MainConsole.Instance.OnOutput -= ConsoleSender;
200 m_consoleIsOn = false;
201 m_consoleModule.SendConsoleOutput(m_agentID, "Console is now off");
202 return new byte[0];
203 }
204
205 if (m_consoleIsOn == false && m_consoleModule.RunCommand(osd.AsString().Trim(), m_agentID))
206 return new byte[0];
207
208 if (m_isGod && m_consoleIsOn)
209 {
210 MainConsole.Instance.RunCommand(osd.AsString().Trim());
211 }
212 else
213 {
214 m_consoleModule.SendConsoleOutput(m_agentID, "Unknown command");
215 }
216
217 return new byte[0];
218 }
219
220 private void ConsoleSender(string text)
221 {
222 m_consoleModule.SendConsoleOutput(m_agentID, text);
223 }
224
225 private void OnMakeChildAgent(ScenePresence presence)
226 {
227 if (presence.UUID == m_agentID)
228 {
229 MainConsole.Instance.OnOutput -= ConsoleSender;
230 m_consoleIsOn = false;
231 }
232 }
233 }
234}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
new file mode 100644
index 0000000..e258bcb
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/SimulatorFeaturesModule.cs
@@ -0,0 +1,303 @@
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.Reflection;
32using log4net;
33using Nini.Config;
34using Mono.Addins;
35using OpenMetaverse;
36using OpenMetaverse.StructuredData;
37using OpenSim.Framework;
38using OpenSim.Framework.Servers.HttpServer;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41// using OpenSim.Services.Interfaces;
42using Caps = OpenSim.Framework.Capabilities.Caps;
43
44namespace OpenSim.Region.ClientStack.Linden
45{
46 /// <summary>
47 /// SimulatorFeatures capability.
48 /// </summary>
49 /// <remarks>
50 /// This is required for uploading Mesh.
51 /// Since is accepts an open-ended response, we also send more information
52 /// for viewers that care to interpret it.
53 ///
54 /// NOTE: Part of this code was adapted from the Aurora project, specifically
55 /// the normal part of the response in the capability handler.
56 /// </remarks>
57 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimulatorFeaturesModule")]
58 public class SimulatorFeaturesModule : ISharedRegionModule, ISimulatorFeaturesModule
59 {
60 private static readonly ILog m_log =
61 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
62
63 public event SimulatorFeaturesRequestDelegate OnSimulatorFeaturesRequest;
64
65 private Scene m_scene;
66
67 /// <summary>
68 /// Simulator features
69 /// </summary>
70 private OSDMap m_features = new OSDMap();
71
72 private string m_SearchURL = string.Empty;
73 private string m_DestinationGuideURL = string.Empty;
74 private bool m_ExportSupported = false;
75 private string m_GridName = string.Empty;
76 private string m_GridURL = string.Empty;
77
78 #region ISharedRegionModule Members
79
80 public void Initialise(IConfigSource source)
81 {
82 IConfig config = source.Configs["SimulatorFeatures"];
83
84 if (config != null)
85 {
86 //
87 // All this is obsolete since getting these features from the grid service!!
88 // Will be removed after the next release
89 //
90 m_SearchURL = config.GetString("SearchServerURI", m_SearchURL);
91
92 m_DestinationGuideURL = config.GetString ("DestinationGuideURI", m_DestinationGuideURL);
93
94 if (m_DestinationGuideURL == string.Empty) // Make this consistent with the variable in the LoginService config
95 m_DestinationGuideURL = config.GetString("DestinationGuide", m_DestinationGuideURL);
96
97 m_ExportSupported = config.GetBoolean("ExportSupported", m_ExportSupported);
98
99 m_GridURL = Util.GetConfigVarFromSections<string>(
100 source, "GatekeeperURI", new string[] { "Startup", "Hypergrid", "SimulatorFeatures" }, String.Empty);
101
102 m_GridName = config.GetString("GridName", string.Empty);
103 if (m_GridName == string.Empty)
104 m_GridName = Util.GetConfigVarFromSections<string>(
105 source, "gridname", new string[] { "GridInfo", "SimulatorFeatures" }, String.Empty);
106 }
107
108 AddDefaultFeatures();
109 }
110
111 public void AddRegion(Scene s)
112 {
113 m_scene = s;
114 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
115
116 m_scene.RegisterModuleInterface<ISimulatorFeaturesModule>(this);
117 }
118
119 public void RemoveRegion(Scene s)
120 {
121 m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
122 }
123
124 public void RegionLoaded(Scene s)
125 {
126 GetGridExtraFeatures(s);
127 }
128
129 public void PostInitialise()
130 {
131 }
132
133 public void Close() { }
134
135 public string Name { get { return "SimulatorFeaturesModule"; } }
136
137 public Type ReplaceableInterface
138 {
139 get { return null; }
140 }
141
142 #endregion
143
144 /// <summary>
145 /// Add default features
146 /// </summary>
147 /// <remarks>
148 /// TODO: These should be added from other modules rather than hardcoded.
149 /// </remarks>
150 private void AddDefaultFeatures()
151 {
152
153 lock (m_features)
154 {
155 m_features["MeshRezEnabled"] = true;
156 m_features["MeshUploadEnabled"] = true;
157 m_features["MeshXferEnabled"] = true;
158 m_features["PhysicsMaterialsEnabled"] = true;
159
160 OSDMap typesMap = new OSDMap();
161 typesMap["convex"] = true;
162 typesMap["none"] = true;
163 typesMap["prim"] = true;
164 m_features["PhysicsShapeTypes"] = typesMap;
165
166 // Extra information for viewers that want to use it
167 // TODO: Take these out of here into their respective modules, like map-server-url
168 OSDMap extrasMap;
169 if(m_features.ContainsKey("OpenSimExtras"))
170 {
171 extrasMap = (OSDMap)m_features["OpenSimExtras"];
172 }
173 else
174 extrasMap = new OSDMap();
175
176 if (m_SearchURL != string.Empty)
177 extrasMap["search-server-url"] = m_SearchURL;
178 if (!string.IsNullOrEmpty(m_DestinationGuideURL))
179 extrasMap["destination-guide-url"] = m_DestinationGuideURL;
180 if (m_ExportSupported)
181 extrasMap["ExportSupported"] = true;
182 if (m_GridURL != string.Empty)
183 extrasMap["GridURL"] = m_GridURL;
184 if (m_GridName != string.Empty)
185 extrasMap["GridName"] = m_GridName;
186
187 if (extrasMap.Count > 0)
188 m_features["OpenSimExtras"] = extrasMap;
189 }
190 }
191
192 public void RegisterCaps(UUID agentID, Caps caps)
193 {
194 IRequestHandler reqHandler
195 = new RestHTTPHandler(
196 "GET", "/CAPS/" + UUID.Random(),
197 x => { return HandleSimulatorFeaturesRequest(x, agentID); }, "SimulatorFeatures", agentID.ToString());
198
199 caps.RegisterHandler("SimulatorFeatures", reqHandler);
200 }
201
202 public void AddFeature(string name, OSD value)
203 {
204 lock (m_features)
205 m_features[name] = value;
206 }
207
208 public bool RemoveFeature(string name)
209 {
210 lock (m_features)
211 return m_features.Remove(name);
212 }
213
214 public bool TryGetFeature(string name, out OSD value)
215 {
216 lock (m_features)
217 return m_features.TryGetValue(name, out value);
218 }
219
220 public OSDMap GetFeatures()
221 {
222 lock (m_features)
223 return new OSDMap(m_features);
224 }
225
226 private OSDMap DeepCopy()
227 {
228 // This isn't the cheapest way of doing this but the rate
229 // of occurrence is low (on sim entry only) and it's a sure
230 // way to get a true deep copy.
231 OSD copy = OSDParser.DeserializeLLSDXml(OSDParser.SerializeLLSDXmlString(m_features));
232
233 return (OSDMap)copy;
234 }
235
236 private Hashtable HandleSimulatorFeaturesRequest(Hashtable mDhttpMethod, UUID agentID)
237 {
238// m_log.DebugFormat("[SIMULATOR FEATURES MODULE]: SimulatorFeatures request");
239
240 OSDMap copy = DeepCopy();
241
242 // Let's add the agentID to the destination guide, if it is expecting that.
243 if (copy.ContainsKey("OpenSimExtras") && ((OSDMap)(copy["OpenSimExtras"])).ContainsKey("destination-guide-url"))
244 ((OSDMap)copy["OpenSimExtras"])["destination-guide-url"] = Replace(((OSDMap)copy["OpenSimExtras"])["destination-guide-url"], "[USERID]", agentID.ToString());
245
246 SimulatorFeaturesRequestDelegate handlerOnSimulatorFeaturesRequest = OnSimulatorFeaturesRequest;
247
248 if (handlerOnSimulatorFeaturesRequest != null)
249 handlerOnSimulatorFeaturesRequest(agentID, ref copy);
250
251 //Send back data
252 Hashtable responsedata = new Hashtable();
253 responsedata["int_response_code"] = 200;
254 responsedata["content_type"] = "text/plain";
255 responsedata["keepalive"] = false;
256
257 responsedata["str_response_string"] = OSDParser.SerializeLLSDXmlString(copy);
258
259 return responsedata;
260 }
261
262 /// <summary>
263 /// Gets the grid extra features.
264 /// </summary>
265 /// <param name='featuresURI'>
266 /// The URI Robust uses to handle the get_extra_features request
267 /// </param>
268 private void GetGridExtraFeatures(Scene scene)
269 {
270 Dictionary<string, object> extraFeatures = scene.GridService.GetExtraFeatures();
271 if (extraFeatures.ContainsKey("Result") && extraFeatures["Result"] != null && extraFeatures["Result"].ToString() == "Failure")
272 {
273 m_log.WarnFormat("[SIMULATOR FEATURES MODULE]: Unable to retrieve grid-wide features");
274 return;
275 }
276
277 lock (m_features)
278 {
279 OSDMap extrasMap = new OSDMap();
280
281 foreach(string key in extraFeatures.Keys)
282 {
283 extrasMap[key] = (string)extraFeatures[key];
284
285 if (key == "ExportSupported")
286 {
287 bool.TryParse(extraFeatures[key].ToString(), out m_ExportSupported);
288 }
289 }
290 m_features["OpenSimExtras"] = extrasMap;
291
292 }
293 }
294
295 private string Replace(string url, string substring, string replacement)
296 {
297 if (!String.IsNullOrEmpty(url) && url.Contains(substring))
298 return url.Replace(substring, replacement);
299
300 return url;
301 }
302 }
303}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs
new file mode 100644
index 0000000..dd4a691
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/Tests/WebFetchInvDescModuleTests.cs
@@ -0,0 +1,159 @@
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.IO;
32using System.Net;
33using System.Text;
34using HttpServer;
35using log4net.Config;
36using Nini.Config;
37using NUnit.Framework;
38using OpenMetaverse;
39using OpenMetaverse.Packets;
40using OpenMetaverse.StructuredData;
41using OpenSim.Framework;
42using OpenSim.Framework.Capabilities;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.HttpServer;
45using OpenSim.Region.ClientStack.Linden;
46using OpenSim.Region.CoreModules.Framework;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Services.Interfaces;
49using OpenSim.Tests.Common;
50using OSDArray = OpenMetaverse.StructuredData.OSDArray;
51using OSDMap = OpenMetaverse.StructuredData.OSDMap;
52
53namespace OpenSim.Region.ClientStack.Linden.Caps.Tests
54{
55 [TestFixture]
56 public class WebFetchInvDescModuleTests : OpenSimTestCase
57 {
58 [TestFixtureSetUp]
59 public void TestFixtureSetUp()
60 {
61 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
62 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
63 }
64
65 [TestFixtureTearDown]
66 public void TestFixureTearDown()
67 {
68 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
69 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
70 // tests really shouldn't).
71 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
72 }
73
74 [SetUp]
75 public override void SetUp()
76 {
77 base.SetUp();
78
79 // This is an unfortunate bit of clean up we have to do because MainServer manages things through static
80 // variables and the VM is not restarted between tests.
81 uint port = 9999;
82 MainServer.RemoveHttpServer(port);
83
84 BaseHttpServer server = new BaseHttpServer(port, false, 0, "");
85 MainServer.AddHttpServer(server);
86 MainServer.Instance = server;
87
88 server.Start(false);
89 }
90
91 [Test]
92 public void TestInventoryDescendentsFetch()
93 {
94 TestHelpers.InMethod();
95 TestHelpers.EnableLogging();
96
97 BaseHttpServer httpServer = MainServer.Instance;
98 Scene scene = new SceneHelpers().SetupScene();
99
100 CapabilitiesModule capsModule = new CapabilitiesModule();
101 WebFetchInvDescModule wfidModule = new WebFetchInvDescModule(false);
102
103 IConfigSource config = new IniConfigSource();
104 config.AddConfig("ClientStack.LindenCaps");
105 config.Configs["ClientStack.LindenCaps"].Set("Cap_FetchInventoryDescendents2", "localhost");
106
107 SceneHelpers.SetupSceneModules(scene, config, capsModule, wfidModule);
108
109 UserAccount ua = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(0x1));
110
111 // We need a user present to have any capabilities set up
112 SceneHelpers.AddScenePresence(scene, ua.PrincipalID);
113
114 TestHttpRequest req = new TestHttpRequest();
115 OpenSim.Framework.Capabilities.Caps userCaps = capsModule.GetCapsForUser(ua.PrincipalID);
116 PollServiceEventArgs pseArgs;
117 userCaps.TryGetPollHandler("FetchInventoryDescendents2", out pseArgs);
118 req.UriPath = pseArgs.Url;
119 req.Uri = new Uri("file://" + req.UriPath);
120
121 // Retrieve root folder details directly so that we can request
122 InventoryFolderBase folder = scene.InventoryService.GetRootFolder(ua.PrincipalID);
123
124 OSDMap osdFolder = new OSDMap();
125 osdFolder["folder_id"] = folder.ID;
126 osdFolder["owner_id"] = ua.PrincipalID;
127 osdFolder["fetch_folders"] = true;
128 osdFolder["fetch_items"] = true;
129 osdFolder["sort_order"] = 0;
130
131 OSDArray osdFoldersArray = new OSDArray();
132 osdFoldersArray.Add(osdFolder);
133
134 OSDMap osdReqMap = new OSDMap();
135 osdReqMap["folders"] = osdFoldersArray;
136
137 req.Body = new MemoryStream(OSDParser.SerializeLLSDXmlBytes(osdReqMap));
138
139 TestHttpClientContext context = new TestHttpClientContext(false);
140
141 // WARNING: This results in a caught exception, because queryString is null
142 MainServer.Instance.OnRequest(context, new RequestEventArgs(req));
143
144 // Drive processing of the queued inventory request synchronously.
145 wfidModule.WaitProcessQueuedInventoryRequest();
146 MainServer.Instance.PollServiceRequestManager.WaitPerformResponse();
147
148// System.Threading.Thread.Sleep(10000);
149
150 OSDMap responseOsd = (OSDMap)OSDParser.DeserializeLLSDXml(context.ResponseBody);
151 OSDArray foldersOsd = (OSDArray)responseOsd["folders"];
152 OSDMap folderOsd = (OSDMap)foldersOsd[0];
153
154 // A sanity check that the response has the expected number of descendents for a default inventory
155 // TODO: Need a more thorough check.
156 Assert.That((int)folderOsd["descendents"], Is.EqualTo(16));
157 }
158 }
159} \ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
new file mode 100644
index 0000000..8cdebcd
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/UploadBakedTextureModule.cs
@@ -0,0 +1,302 @@
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.Collections.Specialized;
32using System.Drawing;
33using System.Drawing.Imaging;
34using System.Reflection;
35using System.IO;
36using System.Web;
37using log4net;
38using Nini.Config;
39using Mono.Addins;
40using OpenMetaverse;
41using OpenMetaverse.StructuredData;
42using OpenMetaverse.Imaging;
43using OpenSim.Framework;
44using OpenSim.Framework.Servers;
45using OpenSim.Framework.Servers.HttpServer;
46using OpenSim.Region.Framework.Interfaces;
47using OpenSim.Region.Framework.Scenes;
48using OpenSim.Services.Interfaces;
49using Caps = OpenSim.Framework.Capabilities.Caps;
50using OpenSim.Capabilities.Handlers;
51
52namespace OpenSim.Region.ClientStack.Linden
53{
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadBakedTextureModule")]
55 public class UploadBakedTextureModule : INonSharedRegionModule
56 {
57 private static readonly ILog m_log =
58 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59
60 /// <summary>
61 /// For historical reasons this is fixed, but there
62 /// </summary>
63 private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule.
64
65 private Scene m_scene;
66 private bool m_persistBakedTextures;
67
68 private IBakedTextureModule m_BakedTextureModule;
69
70 public void Initialise(IConfigSource source)
71 {
72 IConfig appearanceConfig = source.Configs["Appearance"];
73 if (appearanceConfig != null)
74 m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
75
76
77 }
78
79 public void AddRegion(Scene s)
80 {
81 m_scene = s;
82
83 }
84
85 public void RemoveRegion(Scene s)
86 {
87 s.EventManager.OnRegisterCaps -= RegisterCaps;
88 s.EventManager.OnNewPresence -= RegisterNewPresence;
89 s.EventManager.OnRemovePresence -= DeRegisterPresence;
90 m_BakedTextureModule = null;
91 m_scene = null;
92 }
93
94
95
96 public void RegionLoaded(Scene s)
97 {
98 m_scene.EventManager.OnRegisterCaps += RegisterCaps;
99 m_scene.EventManager.OnNewPresence += RegisterNewPresence;
100 m_scene.EventManager.OnRemovePresence += DeRegisterPresence;
101
102 }
103
104 private void DeRegisterPresence(UUID agentId)
105 {
106 ScenePresence presence = null;
107 if (m_scene.TryGetScenePresence(agentId, out presence))
108 {
109 presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings;
110 }
111
112 }
113
114 private void RegisterNewPresence(ScenePresence presence)
115 {
116 presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings;
117
118 }
119
120 private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
121 {
122 int maxCacheitemsLoop = cacheItems.Length;
123 if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES)
124 {
125 maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
126 m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
127 }
128
129 m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
130 if (cacheItems.Length > 0)
131 {
132// m_log.Debug("[Cacheitems]: " + cacheItems.Length);
133// for (int iter = 0; iter < maxCacheitemsLoop; iter++)
134// {
135// m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
136// cacheItems[iter].TextureID);
137// }
138
139 ScenePresence p = null;
140 if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
141 {
142
143 WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems;
144 if (existingitems == null)
145 {
146 if (m_BakedTextureModule != null)
147 {
148 WearableCacheItem[] savedcache = null;
149 try
150 {
151 if (p.Appearance.WearableCacheItemsDirty)
152 {
153 savedcache = m_BakedTextureModule.Get(p.UUID);
154 p.Appearance.WearableCacheItems = savedcache;
155 p.Appearance.WearableCacheItemsDirty = false;
156 }
157
158 }
159 /*
160 * The following Catch types DO NOT WORK with m_BakedTextureModule.Get
161 * it jumps to the General Packet Exception Handler if you don't catch Exception!
162 *
163 catch (System.Net.Sockets.SocketException)
164 {
165 cacheItems = null;
166 }
167 catch (WebException)
168 {
169 cacheItems = null;
170 }
171 catch (InvalidOperationException)
172 {
173 cacheItems = null;
174 } */
175 catch (Exception)
176 {
177 // The service logs a sufficient error message.
178 }
179
180
181 if (savedcache != null)
182 existingitems = savedcache;
183 }
184 }
185 // Existing items null means it's a fully new appearance
186 if (existingitems == null)
187 {
188
189 for (int i = 0; i < maxCacheitemsLoop; i++)
190 {
191 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
192 {
193 Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
194 if (face == null)
195 {
196 textureEntry.CreateFace(cacheItems[i].TextureIndex);
197 textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
198 AppearanceManager.DEFAULT_AVATAR_TEXTURE;
199 continue;
200 }
201 cacheItems[i].TextureID =face.TextureID;
202 if (m_scene.AssetService != null)
203 cacheItems[i].TextureAsset =
204 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
205 }
206 else
207 {
208 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
209 }
210
211
212 }
213 }
214 else
215
216
217 {
218 // for each uploaded baked texture
219 for (int i = 0; i < maxCacheitemsLoop; i++)
220 {
221 if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
222 {
223 Primitive.TextureEntryFace face = textureEntry.FaceTextures[cacheItems[i].TextureIndex];
224 if (face == null)
225 {
226 textureEntry.CreateFace(cacheItems[i].TextureIndex);
227 textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID =
228 AppearanceManager.DEFAULT_AVATAR_TEXTURE;
229 continue;
230 }
231 cacheItems[i].TextureID =
232 face.TextureID;
233 }
234 else
235 {
236 m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
237 }
238 }
239
240 for (int i = 0; i < maxCacheitemsLoop; i++)
241 {
242 if (cacheItems[i].TextureAsset == null)
243 {
244 cacheItems[i].TextureAsset =
245 m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
246 }
247 }
248 }
249
250
251
252 p.Appearance.WearableCacheItems = cacheItems;
253
254
255
256 if (m_BakedTextureModule != null)
257 {
258 m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems);
259 p.Appearance.WearableCacheItemsDirty = true;
260
261 }
262 }
263 }
264 }
265
266 public void PostInitialise()
267 {
268 }
269
270
271
272 public void Close() { }
273
274 public string Name { get { return "UploadBakedTextureModule"; } }
275
276 public Type ReplaceableInterface
277 {
278 get { return null; }
279 }
280
281 public void RegisterCaps(UUID agentID, Caps caps)
282 {
283 UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
284 caps, m_scene.AssetService, m_persistBakedTextures);
285
286
287
288 caps.RegisterHandler(
289 "UploadBakedTexture",
290 new RestStreamHandler(
291 "POST",
292 "/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
293 avatarhandler.UploadBakedTexture,
294 "UploadBakedTexture",
295 agentID.ToString()));
296
297
298
299
300 }
301 }
302}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
new file mode 100644
index 0000000..025ffea
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs
@@ -0,0 +1,454 @@
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.Reflection;
32using System.Threading;
33using log4net;
34using Nini.Config;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Framework.Monitoring;
40using OpenSim.Framework.Servers;
41using OpenSim.Framework.Servers.HttpServer;
42using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes;
44using OpenSim.Framework.Capabilities;
45using OpenSim.Services.Interfaces;
46using Caps = OpenSim.Framework.Capabilities.Caps;
47using OpenSim.Capabilities.Handlers;
48
49namespace OpenSim.Region.ClientStack.Linden
50{
51 /// <summary>
52 /// This module implements both WebFetchInventoryDescendents and FetchInventoryDescendents2 capabilities.
53 /// </summary>
54 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "WebFetchInvDescModule")]
55 public class WebFetchInvDescModule : INonSharedRegionModule
56 {
57 class aPollRequest
58 {
59 public PollServiceInventoryEventArgs thepoll;
60 public UUID reqID;
61 public Hashtable request;
62 public ScenePresence presence;
63 public List<UUID> folders;
64 }
65
66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
67
68 /// <summary>
69 /// Control whether requests will be processed asynchronously.
70 /// </summary>
71 /// <remarks>
72 /// Defaults to true. Can currently not be changed once a region has been added to the module.
73 /// </remarks>
74 public bool ProcessQueuedRequestsAsync { get; private set; }
75
76 /// <summary>
77 /// Number of inventory requests processed by this module.
78 /// </summary>
79 /// <remarks>
80 /// It's the PollServiceRequestManager that actually sends completed requests back to the requester.
81 /// </remarks>
82 public static int ProcessedRequestsCount { get; set; }
83
84 private static Stat s_queuedRequestsStat;
85 private static Stat s_processedRequestsStat;
86
87 public Scene Scene { get; private set; }
88
89 private IInventoryService m_InventoryService;
90 private ILibraryService m_LibraryService;
91
92 private bool m_Enabled;
93
94 private string m_fetchInventoryDescendents2Url;
95 private string m_webFetchInventoryDescendentsUrl;
96
97 private static FetchInvDescHandler m_webFetchHandler;
98
99 private static Thread[] m_workerThreads = null;
100
101 private static DoubleQueue<aPollRequest> m_queue =
102 new DoubleQueue<aPollRequest>();
103
104 #region ISharedRegionModule Members
105
106 public WebFetchInvDescModule() : this(true) {}
107
108 public WebFetchInvDescModule(bool processQueuedResultsAsync)
109 {
110 ProcessQueuedRequestsAsync = processQueuedResultsAsync;
111 }
112
113 public void Initialise(IConfigSource source)
114 {
115 IConfig config = source.Configs["ClientStack.LindenCaps"];
116 if (config == null)
117 return;
118
119 m_fetchInventoryDescendents2Url = config.GetString("Cap_FetchInventoryDescendents2", string.Empty);
120 m_webFetchInventoryDescendentsUrl = config.GetString("Cap_WebFetchInventoryDescendents", string.Empty);
121
122 if (m_fetchInventoryDescendents2Url != string.Empty || m_webFetchInventoryDescendentsUrl != string.Empty)
123 {
124 m_Enabled = true;
125 }
126 }
127
128 public void AddRegion(Scene s)
129 {
130 if (!m_Enabled)
131 return;
132
133 Scene = s;
134 }
135
136 public void RemoveRegion(Scene s)
137 {
138 if (!m_Enabled)
139 return;
140
141 Scene.EventManager.OnRegisterCaps -= RegisterCaps;
142
143 StatsManager.DeregisterStat(s_processedRequestsStat);
144 StatsManager.DeregisterStat(s_queuedRequestsStat);
145
146 if (ProcessQueuedRequestsAsync)
147 {
148 if (m_workerThreads != null)
149 {
150 foreach (Thread t in m_workerThreads)
151 Watchdog.AbortThread(t.ManagedThreadId);
152
153 m_workerThreads = null;
154 }
155 }
156
157 Scene = null;
158 }
159
160 public void RegionLoaded(Scene s)
161 {
162 if (!m_Enabled)
163 return;
164
165 if (s_processedRequestsStat == null)
166 s_processedRequestsStat =
167 new Stat(
168 "ProcessedFetchInventoryRequests",
169 "Number of processed fetch inventory requests",
170 "These have not necessarily yet been dispatched back to the requester.",
171 "",
172 "inventory",
173 "httpfetch",
174 StatType.Pull,
175 MeasuresOfInterest.AverageChangeOverTime,
176 stat => { stat.Value = ProcessedRequestsCount; },
177 StatVerbosity.Debug);
178
179 if (s_queuedRequestsStat == null)
180 s_queuedRequestsStat =
181 new Stat(
182 "QueuedFetchInventoryRequests",
183 "Number of fetch inventory requests queued for processing",
184 "",
185 "",
186 "inventory",
187 "httpfetch",
188 StatType.Pull,
189 MeasuresOfInterest.AverageChangeOverTime,
190 stat => { stat.Value = m_queue.Count; },
191 StatVerbosity.Debug);
192
193 StatsManager.RegisterStat(s_processedRequestsStat);
194 StatsManager.RegisterStat(s_queuedRequestsStat);
195
196 m_InventoryService = Scene.InventoryService;
197 m_LibraryService = Scene.LibraryService;
198
199 // We'll reuse the same handler for all requests.
200 m_webFetchHandler = new FetchInvDescHandler(m_InventoryService, m_LibraryService, Scene);
201
202 Scene.EventManager.OnRegisterCaps += RegisterCaps;
203
204 int nworkers = 2; // was 2
205 if (ProcessQueuedRequestsAsync && m_workerThreads == null)
206 {
207 m_workerThreads = new Thread[nworkers];
208
209 for (uint i = 0; i < nworkers; i++)
210 {
211 m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests,
212 String.Format("InventoryWorkerThread{0}", i),
213 ThreadPriority.Normal,
214 false,
215 true,
216 null,
217 int.MaxValue);
218 }
219 }
220 }
221
222 public void PostInitialise()
223 {
224 }
225
226 public void Close() { }
227
228 public string Name { get { return "WebFetchInvDescModule"; } }
229
230 public Type ReplaceableInterface
231 {
232 get { return null; }
233 }
234
235 #endregion
236
237 private class PollServiceInventoryEventArgs : PollServiceEventArgs
238 {
239 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
240
241 private Dictionary<UUID, Hashtable> responses =
242 new Dictionary<UUID, Hashtable>();
243
244 private WebFetchInvDescModule m_module;
245
246 public PollServiceInventoryEventArgs(WebFetchInvDescModule module, string url, UUID pId) :
247 base(null, url, null, null, null, pId, int.MaxValue)
248 {
249 m_module = module;
250
251 HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); };
252 GetEvents = (x, y) =>
253 {
254 lock (responses)
255 {
256 try
257 {
258 return responses[x];
259 }
260 finally
261 {
262 responses.Remove(x);
263 }
264 }
265 };
266
267 Request = (x, y) =>
268 {
269 ScenePresence sp = m_module.Scene.GetScenePresence(Id);
270
271 aPollRequest reqinfo = new aPollRequest();
272 reqinfo.thepoll = this;
273 reqinfo.reqID = x;
274 reqinfo.request = y;
275 reqinfo.presence = sp;
276 reqinfo.folders = new List<UUID>();
277
278 // Decode the request here
279 string request = y["body"].ToString();
280
281 request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>");
282
283 request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>");
284 request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>");
285
286 Hashtable hash = new Hashtable();
287 try
288 {
289 hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request));
290 }
291 catch (LLSD.LLSDParseException e)
292 {
293 m_log.ErrorFormat("[INVENTORY]: Fetch error: {0}{1}" + e.Message, e.StackTrace);
294 m_log.Error("Request: " + request);
295 return;
296 }
297 catch (System.Xml.XmlException)
298 {
299 m_log.ErrorFormat("[INVENTORY]: XML Format error");
300 }
301
302 ArrayList foldersrequested = (ArrayList)hash["folders"];
303
304 bool highPriority = false;
305
306 for (int i = 0; i < foldersrequested.Count; i++)
307 {
308 Hashtable inventoryhash = (Hashtable)foldersrequested[i];
309 string folder = inventoryhash["folder_id"].ToString();
310 UUID folderID;
311 if (UUID.TryParse(folder, out folderID))
312 {
313 if (!reqinfo.folders.Contains(folderID))
314 {
315 //TODO: Port COF handling from Avination
316 reqinfo.folders.Add(folderID);
317 }
318 }
319 }
320
321 if (highPriority)
322 m_queue.EnqueueHigh(reqinfo);
323 else
324 m_queue.EnqueueLow(reqinfo);
325 };
326
327 NoEvents = (x, y) =>
328 {
329/*
330 lock (requests)
331 {
332 Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
333 requests.Remove(request);
334 }
335*/
336 Hashtable response = new Hashtable();
337
338 response["int_response_code"] = 500;
339 response["str_response_string"] = "Script timeout";
340 response["content_type"] = "text/plain";
341 response["keepalive"] = false;
342 response["reusecontext"] = false;
343
344 return response;
345 };
346 }
347
348 public void Process(aPollRequest requestinfo)
349 {
350 UUID requestID = requestinfo.reqID;
351
352 Hashtable response = new Hashtable();
353
354 response["int_response_code"] = 200;
355 response["content_type"] = "text/plain";
356 response["keepalive"] = false;
357 response["reusecontext"] = false;
358
359 response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(
360 requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null);
361
362 lock (responses)
363 {
364 if (responses.ContainsKey(requestID))
365 m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054");
366 responses[requestID] = response;
367 }
368
369 WebFetchInvDescModule.ProcessedRequestsCount++;
370 }
371 }
372
373 private void RegisterCaps(UUID agentID, Caps caps)
374 {
375 RegisterFetchDescendentsCap(agentID, caps, "FetchInventoryDescendents2", m_fetchInventoryDescendents2Url);
376 }
377
378 private void RegisterFetchDescendentsCap(UUID agentID, Caps caps, string capName, string url)
379 {
380 string capUrl;
381
382 // disable the cap clause
383 if (url == "")
384 {
385 return;
386 }
387 // handled by the simulator
388 else if (url == "localhost")
389 {
390 capUrl = "/CAPS/" + UUID.Random() + "/";
391
392 // Register this as a poll service
393 PollServiceInventoryEventArgs args = new PollServiceInventoryEventArgs(this, capUrl, agentID);
394 args.Type = PollServiceEventArgs.EventType.Inventory;
395
396 caps.RegisterPollHandler(capName, args);
397 }
398 // external handler
399 else
400 {
401 capUrl = url;
402 IExternalCapsModule handler = Scene.RequestModuleInterface<IExternalCapsModule>();
403 if (handler != null)
404 handler.RegisterExternalUserCapsHandler(agentID,caps,capName,capUrl);
405 else
406 caps.RegisterHandler(capName, capUrl);
407 }
408
409 // m_log.DebugFormat(
410 // "[FETCH INVENTORY DESCENDENTS2 MODULE]: Registered capability {0} at {1} in region {2} for {3}",
411 // capName, capUrl, m_scene.RegionInfo.RegionName, agentID);
412 }
413
414// private void DeregisterCaps(UUID agentID, Caps caps)
415// {
416// string capUrl;
417//
418// if (m_capsDict.TryGetValue(agentID, out capUrl))
419// {
420// MainServer.Instance.RemoveHTTPHandler("", capUrl);
421// m_capsDict.Remove(agentID);
422// }
423// }
424
425 private void DoInventoryRequests()
426 {
427 while (true)
428 {
429 Watchdog.UpdateThread();
430
431 WaitProcessQueuedInventoryRequest();
432 }
433 }
434
435 public void WaitProcessQueuedInventoryRequest()
436 {
437 aPollRequest poolreq = m_queue.Dequeue();
438
439 if (poolreq != null && poolreq.thepoll != null)
440 {
441 try
442 {
443 poolreq.thepoll.Process(poolreq);
444 }
445 catch (Exception e)
446 {
447 m_log.ErrorFormat(
448 "[INVENTORY]: Failed to process queued inventory request {0} for {1} in {2}. Exception {3}",
449 poolreq.reqID, poolreq.presence != null ? poolreq.presence.Name : "unknown", Scene.Name, e);
450 }
451 }
452 }
453 }
454}