diff options
Diffstat (limited to '')
125 files changed, 5364 insertions, 1777 deletions
diff --git a/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs b/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs index 5ad087a..0a7fb5f 100644 --- a/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs +++ b/OpenSim/Addons/Groups/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | [assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: Addin("OpenSim.Groups", OpenSim.VersionInfo.VersionNumber)] |
36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/Addons/OfflineIM/Properties/AssemblyInfo.cs b/OpenSim/Addons/OfflineIM/Properties/AssemblyInfo.cs index 3868912..3e993b4 100644 --- a/OpenSim/Addons/OfflineIM/Properties/AssemblyInfo.cs +++ b/OpenSim/Addons/OfflineIM/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | [assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: Addin("OpenSim.OfflineIM", OpenSim.VersionInfo.VersionNumber)] |
36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs index 0ed47a3..6c3c3e3 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/Properties/AssemblyInfo.cs | |||
@@ -63,7 +63,7 @@ using Mono.Addins; | |||
63 | // by using the '*' as shown below: | 63 | // by using the '*' as shown below: |
64 | // [assembly: AssemblyVersion("0.7.6.*")] | 64 | // [assembly: AssemblyVersion("0.7.6.*")] |
65 | 65 | ||
66 | [assembly : AssemblyVersion("0.8.1.*")] | 66 | [assembly : AssemblyVersion("0.8.2.*")] |
67 | 67 | ||
68 | [assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)] | 68 | [assembly: Addin("OpenSim.ApplicationPlugins.LoadRegions", OpenSim.VersionInfo.VersionNumber)] |
69 | [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] | 69 | [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs index d14938f..021209f 100644 --- a/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs +++ b/OpenSim/ApplicationPlugins/RegionModulesController/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | [assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: Addin("OpenSim.ApplicationPlugins.RegionModulesController", OpenSim.VersionInfo.VersionNumber)] |
36 | [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs b/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs index ffeff3a..443e323 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | [assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: Addin("OpenSim.ApplicationPlugins.RemoteController", OpenSim.VersionInfo.VersionNumber)] |
36 | [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: AddinDependency("OpenSim", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs new file mode 100644 index 0000000..810096f --- /dev/null +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescHandler.cs | |||
@@ -0,0 +1,840 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.StructuredData; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Capabilities; | ||
38 | using OpenSim.Region.Framework.Interfaces; | ||
39 | using OpenSim.Framework.Servers.HttpServer; | ||
40 | using OpenSim.Services.Interfaces; | ||
41 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
42 | |||
43 | namespace OpenSim.Capabilities.Handlers | ||
44 | { | ||
45 | public class FetchInvDescHandler | ||
46 | { | ||
47 | private static readonly ILog m_log = | ||
48 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private IInventoryService m_InventoryService; | ||
51 | private ILibraryService m_LibraryService; | ||
52 | // private object m_fetchLock = new Object(); | ||
53 | |||
54 | public FetchInvDescHandler(IInventoryService invService, ILibraryService libService) | ||
55 | { | ||
56 | m_InventoryService = invService; | ||
57 | m_LibraryService = libService; | ||
58 | } | ||
59 | |||
60 | |||
61 | public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
62 | { | ||
63 | |||
64 | // nasty temporary hack here, the linden client falsely | ||
65 | // identifies the uuid 00000000-0000-0000-0000-000000000000 | ||
66 | // as a string which breaks us | ||
67 | // | ||
68 | // correctly mark it as a uuid | ||
69 | // | ||
70 | request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>"); | ||
71 | |||
72 | // another hack <integer>1</integer> results in a | ||
73 | // System.ArgumentException: Object type System.Int32 cannot | ||
74 | // be converted to target type: System.Boolean | ||
75 | // | ||
76 | request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>"); | ||
77 | request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>"); | ||
78 | |||
79 | Hashtable hash = new Hashtable(); | ||
80 | try | ||
81 | { | ||
82 | hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); | ||
83 | } | ||
84 | catch (LLSD.LLSDParseException e) | ||
85 | { | ||
86 | m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace); | ||
87 | m_log.Error("Request: " + request); | ||
88 | } | ||
89 | |||
90 | ArrayList foldersrequested = (ArrayList)hash["folders"]; | ||
91 | |||
92 | string response = ""; | ||
93 | string bad_folders_response = ""; | ||
94 | |||
95 | List<LLSDFetchInventoryDescendents> folders = new List<LLSDFetchInventoryDescendents>(); | ||
96 | for (int i = 0; i < foldersrequested.Count; i++) | ||
97 | { | ||
98 | Hashtable inventoryhash = (Hashtable)foldersrequested[i]; | ||
99 | |||
100 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); | ||
101 | |||
102 | try | ||
103 | { | ||
104 | LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); | ||
105 | } | ||
106 | catch (Exception e) | ||
107 | { | ||
108 | m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e); | ||
109 | continue; | ||
110 | } | ||
111 | |||
112 | // Filter duplicate folder ids that bad viewers may send | ||
113 | if (folders.Find(f => f.folder_id == llsdRequest.folder_id) == null) | ||
114 | folders.Add(llsdRequest); | ||
115 | } | ||
116 | |||
117 | if (folders.Count > 0) | ||
118 | { | ||
119 | List<UUID> bad_folders = new List<UUID>(); | ||
120 | List<InventoryCollectionWithDescendents> invcollSet = Fetch(folders, bad_folders); | ||
121 | //m_log.DebugFormat("[XXX]: Got {0} folders from a request of {1}", invcollSet.Count, folders.Count); | ||
122 | |||
123 | if (invcollSet == null) | ||
124 | { | ||
125 | m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Multiple folder fetch failed. Trying old protocol."); | ||
126 | return FetchInventoryDescendentsRequest(foldersrequested, httpRequest, httpResponse); | ||
127 | } | ||
128 | |||
129 | string inventoryitemstr = string.Empty; | ||
130 | foreach (InventoryCollectionWithDescendents icoll in invcollSet) | ||
131 | { | ||
132 | LLSDInventoryDescendents reply = ToLLSD(icoll.Collection, icoll.Descendents); | ||
133 | |||
134 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); | ||
135 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); | ||
136 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); | ||
137 | |||
138 | response += inventoryitemstr; | ||
139 | } | ||
140 | |||
141 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Bad folders {0}", string.Join(", ", bad_folders)); | ||
142 | foreach (UUID bad in bad_folders) | ||
143 | bad_folders_response += "<uuid>" + bad + "</uuid>"; | ||
144 | } | ||
145 | |||
146 | if (response.Length == 0) | ||
147 | { | ||
148 | /* Viewers expect a bad_folders array when not available */ | ||
149 | if (bad_folders_response.Length != 0) | ||
150 | { | ||
151 | response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
152 | } | ||
153 | else | ||
154 | { | ||
155 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; | ||
156 | } | ||
157 | } | ||
158 | else | ||
159 | { | ||
160 | if (bad_folders_response.Length != 0) | ||
161 | { | ||
162 | response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
163 | } | ||
164 | else | ||
165 | { | ||
166 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request for {0} folders. Item count {1}", folders.Count, item_count); | ||
171 | //m_log.Debug("[WEB FETCH INV DESC HANDLER] " + response); | ||
172 | |||
173 | return response; | ||
174 | |||
175 | } | ||
176 | |||
177 | /// <summary> | ||
178 | /// Construct an LLSD reply packet to a CAPS inventory request | ||
179 | /// </summary> | ||
180 | /// <param name="invFetch"></param> | ||
181 | /// <returns></returns> | ||
182 | private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) | ||
183 | { | ||
184 | LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); | ||
185 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); | ||
186 | contents.agent_id = invFetch.owner_id; | ||
187 | contents.owner_id = invFetch.owner_id; | ||
188 | contents.folder_id = invFetch.folder_id; | ||
189 | |||
190 | reply.folders.Array.Add(contents); | ||
191 | InventoryCollection inv = new InventoryCollection(); | ||
192 | inv.Folders = new List<InventoryFolderBase>(); | ||
193 | inv.Items = new List<InventoryItemBase>(); | ||
194 | int version = 0; | ||
195 | int descendents = 0; | ||
196 | |||
197 | inv | ||
198 | = Fetch( | ||
199 | invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, | ||
200 | invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents); | ||
201 | |||
202 | if (inv != null && inv.Folders != null) | ||
203 | { | ||
204 | foreach (InventoryFolderBase invFolder in inv.Folders) | ||
205 | { | ||
206 | contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); | ||
207 | } | ||
208 | |||
209 | descendents += inv.Folders.Count; | ||
210 | } | ||
211 | |||
212 | if (inv != null && inv.Items != null) | ||
213 | { | ||
214 | foreach (InventoryItemBase invItem in inv.Items) | ||
215 | { | ||
216 | contents.items.Array.Add(ConvertInventoryItem(invItem)); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | contents.descendents = descendents; | ||
221 | contents.version = version; | ||
222 | |||
223 | //m_log.DebugFormat( | ||
224 | // "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}", | ||
225 | // invFetch.folder_id, | ||
226 | // invFetch.fetch_items, | ||
227 | // invFetch.fetch_folders, | ||
228 | // contents.items.Array.Count, | ||
229 | // contents.categories.Array.Count, | ||
230 | // invFetch.owner_id); | ||
231 | |||
232 | return reply; | ||
233 | } | ||
234 | |||
235 | private LLSDInventoryDescendents ToLLSD(InventoryCollection inv, int descendents) | ||
236 | { | ||
237 | LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); | ||
238 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); | ||
239 | contents.agent_id = inv.OwnerID; | ||
240 | contents.owner_id = inv.OwnerID; | ||
241 | contents.folder_id = inv.FolderID; | ||
242 | |||
243 | reply.folders.Array.Add(contents); | ||
244 | |||
245 | if (inv.Folders != null) | ||
246 | { | ||
247 | foreach (InventoryFolderBase invFolder in inv.Folders) | ||
248 | { | ||
249 | contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); | ||
250 | } | ||
251 | |||
252 | descendents += inv.Folders.Count; | ||
253 | } | ||
254 | |||
255 | if (inv.Items != null) | ||
256 | { | ||
257 | foreach (InventoryItemBase invItem in inv.Items) | ||
258 | { | ||
259 | contents.items.Array.Add(ConvertInventoryItem(invItem)); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | contents.descendents = descendents; | ||
264 | contents.version = inv.Version; | ||
265 | |||
266 | return reply; | ||
267 | } | ||
268 | /// <summary> | ||
269 | /// Old style. Soon to be deprecated. | ||
270 | /// </summary> | ||
271 | /// <param name="request"></param> | ||
272 | /// <param name="httpRequest"></param> | ||
273 | /// <param name="httpResponse"></param> | ||
274 | /// <returns></returns> | ||
275 | [Obsolete] | ||
276 | private string FetchInventoryDescendentsRequest(ArrayList foldersrequested, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
277 | { | ||
278 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request for {0} folders", foldersrequested.Count); | ||
279 | |||
280 | string response = ""; | ||
281 | string bad_folders_response = ""; | ||
282 | |||
283 | for (int i = 0; i < foldersrequested.Count; i++) | ||
284 | { | ||
285 | string inventoryitemstr = ""; | ||
286 | Hashtable inventoryhash = (Hashtable)foldersrequested[i]; | ||
287 | |||
288 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); | ||
289 | |||
290 | try | ||
291 | { | ||
292 | LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); | ||
293 | } | ||
294 | catch (Exception e) | ||
295 | { | ||
296 | m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e); | ||
297 | } | ||
298 | |||
299 | LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); | ||
300 | |||
301 | if (null == reply) | ||
302 | { | ||
303 | bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>"; | ||
304 | } | ||
305 | else | ||
306 | { | ||
307 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); | ||
308 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); | ||
309 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); | ||
310 | } | ||
311 | |||
312 | response += inventoryitemstr; | ||
313 | } | ||
314 | |||
315 | if (response.Length == 0) | ||
316 | { | ||
317 | /* Viewers expect a bad_folders array when not available */ | ||
318 | if (bad_folders_response.Length != 0) | ||
319 | { | ||
320 | response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; | ||
325 | } | ||
326 | } | ||
327 | else | ||
328 | { | ||
329 | if (bad_folders_response.Length != 0) | ||
330 | { | ||
331 | response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
332 | } | ||
333 | else | ||
334 | { | ||
335 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; | ||
336 | } | ||
337 | } | ||
338 | |||
339 | // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request"); | ||
340 | //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response); | ||
341 | |||
342 | return response; | ||
343 | |||
344 | // } | ||
345 | } | ||
346 | |||
347 | /// <summary> | ||
348 | /// Handle the caps inventory descendents fetch. | ||
349 | /// </summary> | ||
350 | /// <param name="agentID"></param> | ||
351 | /// <param name="folderID"></param> | ||
352 | /// <param name="ownerID"></param> | ||
353 | /// <param name="fetchFolders"></param> | ||
354 | /// <param name="fetchItems"></param> | ||
355 | /// <param name="sortOrder"></param> | ||
356 | /// <param name="version"></param> | ||
357 | /// <returns>An empty InventoryCollection if the inventory look up failed</returns> | ||
358 | [Obsolete] | ||
359 | private InventoryCollection Fetch( | ||
360 | UUID agentID, UUID folderID, UUID ownerID, | ||
361 | bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents) | ||
362 | { | ||
363 | //m_log.DebugFormat( | ||
364 | // "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", | ||
365 | // fetchFolders, fetchItems, folderID, agentID); | ||
366 | |||
367 | // FIXME MAYBE: We're not handling sortOrder! | ||
368 | |||
369 | version = 0; | ||
370 | descendents = 0; | ||
371 | |||
372 | InventoryFolderImpl fold; | ||
373 | if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner) | ||
374 | { | ||
375 | if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null) | ||
376 | { | ||
377 | InventoryCollection ret = new InventoryCollection(); | ||
378 | ret.Folders = new List<InventoryFolderBase>(); | ||
379 | ret.Items = fold.RequestListOfItems(); | ||
380 | descendents = ret.Folders.Count + ret.Items.Count; | ||
381 | |||
382 | return ret; | ||
383 | } | ||
384 | } | ||
385 | |||
386 | InventoryCollection contents = new InventoryCollection(); | ||
387 | |||
388 | if (folderID != UUID.Zero) | ||
389 | { | ||
390 | InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID); | ||
391 | |||
392 | if (fetchedContents == null) | ||
393 | { | ||
394 | m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID); | ||
395 | return contents; | ||
396 | } | ||
397 | contents = fetchedContents; | ||
398 | InventoryFolderBase containingFolder = new InventoryFolderBase(); | ||
399 | containingFolder.ID = folderID; | ||
400 | containingFolder.Owner = agentID; | ||
401 | containingFolder = m_InventoryService.GetFolder(containingFolder); | ||
402 | |||
403 | if (containingFolder != null) | ||
404 | { | ||
405 | //m_log.DebugFormat( | ||
406 | // "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}", | ||
407 | // containingFolder.Name, containingFolder.ID, agentID); | ||
408 | |||
409 | version = containingFolder.Version; | ||
410 | |||
411 | if (fetchItems) | ||
412 | { | ||
413 | List<InventoryItemBase> itemsToReturn = contents.Items; | ||
414 | List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn); | ||
415 | |||
416 | // descendents must only include the links, not the linked items we add | ||
417 | descendents = originalItems.Count; | ||
418 | |||
419 | // Add target items for links in this folder before the links themselves. | ||
420 | foreach (InventoryItemBase item in originalItems) | ||
421 | { | ||
422 | if (item.AssetType == (int)AssetType.Link) | ||
423 | { | ||
424 | InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); | ||
425 | |||
426 | // Take care of genuinely broken links where the target doesn't exist | ||
427 | // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
428 | // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
429 | // rather than having to keep track of every folder requested in the recursion. | ||
430 | if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) | ||
431 | itemsToReturn.Insert(0, linkedItem); | ||
432 | } | ||
433 | } | ||
434 | |||
435 | // Now scan for folder links and insert the items they target and those links at the head of the return data | ||
436 | foreach (InventoryItemBase item in originalItems) | ||
437 | { | ||
438 | if (item.AssetType == (int)AssetType.LinkFolder) | ||
439 | { | ||
440 | InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID); | ||
441 | List<InventoryItemBase> links = linkedFolderContents.Items; | ||
442 | |||
443 | itemsToReturn.InsertRange(0, links); | ||
444 | |||
445 | foreach (InventoryItemBase link in linkedFolderContents.Items) | ||
446 | { | ||
447 | // Take care of genuinely broken links where the target doesn't exist | ||
448 | // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
449 | // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
450 | // rather than having to keep track of every folder requested in the recursion. | ||
451 | if (link != null) | ||
452 | { | ||
453 | // m_log.DebugFormat( | ||
454 | // "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}", | ||
455 | // link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name); | ||
456 | |||
457 | InventoryItemBase linkedItem | ||
458 | = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID)); | ||
459 | |||
460 | if (linkedItem != null) | ||
461 | itemsToReturn.Insert(0, linkedItem); | ||
462 | } | ||
463 | } | ||
464 | } | ||
465 | } | ||
466 | } | ||
467 | |||
468 | // foreach (InventoryItemBase item in contents.Items) | ||
469 | // { | ||
470 | // m_log.DebugFormat( | ||
471 | // "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}", | ||
472 | // item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID); | ||
473 | // } | ||
474 | |||
475 | // ===== | ||
476 | |||
477 | // | ||
478 | // foreach (InventoryItemBase linkedItem in linkedItemsToAdd) | ||
479 | // { | ||
480 | // m_log.DebugFormat( | ||
481 | // "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}", | ||
482 | // linkedItem.Name, folderID, agentID); | ||
483 | // | ||
484 | // contents.Items.Add(linkedItem); | ||
485 | // } | ||
486 | // | ||
487 | // // If the folder requested contains links, then we need to send those folders first, otherwise the links | ||
488 | // // will be broken in the viewer. | ||
489 | // HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>(); | ||
490 | // foreach (InventoryItemBase item in contents.Items) | ||
491 | // { | ||
492 | // if (item.AssetType == (int)AssetType.Link) | ||
493 | // { | ||
494 | // InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); | ||
495 | // | ||
496 | // // Take care of genuinely broken links where the target doesn't exist | ||
497 | // // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
498 | // // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
499 | // // rather than having to keep track of every folder requested in the recursion. | ||
500 | // if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) | ||
501 | // { | ||
502 | // // We don't need to send the folder if source and destination of the link are in the same | ||
503 | // // folder. | ||
504 | // if (linkedItem.Folder != containingFolder.ID) | ||
505 | // linkedItemFolderIdsToSend.Add(linkedItem.Folder); | ||
506 | // } | ||
507 | // } | ||
508 | // } | ||
509 | // | ||
510 | // foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend) | ||
511 | // { | ||
512 | // m_log.DebugFormat( | ||
513 | // "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}", | ||
514 | // linkedItemFolderId, folderID, agentID); | ||
515 | // | ||
516 | // int dummyVersion; | ||
517 | // InventoryCollection linkedCollection | ||
518 | // = Fetch( | ||
519 | // agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion); | ||
520 | // | ||
521 | // InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId); | ||
522 | // linkedFolder.Owner = agentID; | ||
523 | // linkedFolder = m_InventoryService.GetFolder(linkedFolder); | ||
524 | // | ||
525 | //// contents.Folders.AddRange(linkedCollection.Folders); | ||
526 | // | ||
527 | // contents.Folders.Add(linkedFolder); | ||
528 | // contents.Items.AddRange(linkedCollection.Items); | ||
529 | // } | ||
530 | // } | ||
531 | } | ||
532 | } | ||
533 | else | ||
534 | { | ||
535 | // Lost items don't really need a version | ||
536 | version = 1; | ||
537 | } | ||
538 | |||
539 | return contents; | ||
540 | |||
541 | } | ||
542 | |||
543 | private void AddLibraryFolders(List<LLSDFetchInventoryDescendents> fetchFolders, List<InventoryCollectionWithDescendents> result) | ||
544 | { | ||
545 | InventoryFolderImpl fold; | ||
546 | if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null) | ||
547 | { | ||
548 | List<LLSDFetchInventoryDescendents> libfolders = fetchFolders.FindAll(f => f.owner_id == m_LibraryService.LibraryRootFolder.Owner); | ||
549 | fetchFolders.RemoveAll(f => libfolders.Contains(f)); | ||
550 | |||
551 | //m_log.DebugFormat("[XXX]: Found {0} library folders in request", libfolders.Count); | ||
552 | |||
553 | foreach (LLSDFetchInventoryDescendents f in libfolders) | ||
554 | { | ||
555 | if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(f.folder_id)) != null) | ||
556 | { | ||
557 | InventoryCollectionWithDescendents ret = new InventoryCollectionWithDescendents(); | ||
558 | ret.Collection = new InventoryCollection(); | ||
559 | ret.Collection.Folders = new List<InventoryFolderBase>(); | ||
560 | ret.Collection.Items = fold.RequestListOfItems(); | ||
561 | ret.Collection.OwnerID = m_LibraryService.LibraryRootFolder.Owner; | ||
562 | ret.Collection.FolderID = f.folder_id; | ||
563 | ret.Collection.Version = fold.Version; | ||
564 | |||
565 | ret.Descendents = ret.Collection.Items.Count; | ||
566 | result.Add(ret); | ||
567 | |||
568 | //m_log.DebugFormat("[XXX]: Added libfolder {0} ({1}) {2}", ret.Collection.FolderID, ret.Collection.OwnerID); | ||
569 | } | ||
570 | } | ||
571 | } | ||
572 | } | ||
573 | |||
574 | private List<InventoryCollectionWithDescendents> Fetch(List<LLSDFetchInventoryDescendents> fetchFolders, List<UUID> bad_folders) | ||
575 | { | ||
576 | //m_log.DebugFormat( | ||
577 | // "[WEB FETCH INV DESC HANDLER]: Fetching {0} folders for owner {1}", fetchFolders.Count, fetchFolders[0].owner_id); | ||
578 | |||
579 | // FIXME MAYBE: We're not handling sortOrder! | ||
580 | |||
581 | List<InventoryCollectionWithDescendents> result = new List<InventoryCollectionWithDescendents>(); | ||
582 | |||
583 | AddLibraryFolders(fetchFolders, result); | ||
584 | |||
585 | if (fetchFolders.Count > 0) | ||
586 | { | ||
587 | UUID[] fids = new UUID[fetchFolders.Count]; | ||
588 | int i = 0; | ||
589 | foreach (LLSDFetchInventoryDescendents f in fetchFolders) | ||
590 | fids[i++] = f.folder_id; | ||
591 | |||
592 | //m_log.DebugFormat("[XXX]: {0}", string.Join(",", fids)); | ||
593 | |||
594 | InventoryCollection[] fetchedContents = m_InventoryService.GetMultipleFoldersContent(fetchFolders[0].owner_id, fids); | ||
595 | |||
596 | if (fetchedContents == null || (fetchedContents != null && fetchedContents.Length == 0)) | ||
597 | { | ||
598 | //m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of multiple folders for user {0}", fetchFolders[0].owner_id); | ||
599 | return null; | ||
600 | } | ||
601 | |||
602 | i = 0; | ||
603 | // Do some post-processing. May need to fetch more from inv server for links | ||
604 | foreach (InventoryCollection contents in fetchedContents) | ||
605 | { | ||
606 | // Find the original request | ||
607 | LLSDFetchInventoryDescendents freq = fetchFolders[i++]; | ||
608 | |||
609 | InventoryCollectionWithDescendents coll = new InventoryCollectionWithDescendents(); | ||
610 | coll.Collection = contents; | ||
611 | |||
612 | if (BadFolder(freq, contents, bad_folders)) | ||
613 | continue; | ||
614 | |||
615 | // Next: link management | ||
616 | ProcessLinks(freq, coll); | ||
617 | |||
618 | result.Add(coll); | ||
619 | } | ||
620 | } | ||
621 | |||
622 | return result; | ||
623 | } | ||
624 | |||
625 | private bool BadFolder(LLSDFetchInventoryDescendents freq, InventoryCollection contents, List<UUID> bad_folders) | ||
626 | { | ||
627 | bool bad = false; | ||
628 | if (contents == null) | ||
629 | { | ||
630 | bad_folders.Add(freq.folder_id); | ||
631 | bad = true; | ||
632 | } | ||
633 | |||
634 | // The inventory server isn't sending FolderID in the collection... | ||
635 | // Must fetch it individually | ||
636 | if (contents.FolderID == UUID.Zero) | ||
637 | { | ||
638 | InventoryFolderBase containingFolder = new InventoryFolderBase(); | ||
639 | containingFolder.ID = freq.folder_id; | ||
640 | containingFolder.Owner = freq.owner_id; | ||
641 | containingFolder = m_InventoryService.GetFolder(containingFolder); | ||
642 | |||
643 | if (containingFolder != null) | ||
644 | { | ||
645 | contents.FolderID = containingFolder.ID; | ||
646 | contents.OwnerID = containingFolder.Owner; | ||
647 | contents.Version = containingFolder.Version; | ||
648 | } | ||
649 | else | ||
650 | { | ||
651 | // Was it really a request for folder Zero? | ||
652 | // This is an overkill, but Firestorm really asks for folder Zero. | ||
653 | // I'm leaving the code here for the time being, but commented. | ||
654 | if (freq.folder_id == UUID.Zero) | ||
655 | { | ||
656 | //coll.Collection.OwnerID = freq.owner_id; | ||
657 | //coll.Collection.FolderID = contents.FolderID; | ||
658 | //containingFolder = m_InventoryService.GetRootFolder(freq.owner_id); | ||
659 | //if (containingFolder != null) | ||
660 | //{ | ||
661 | // m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Request for parent of folder {0}", containingFolder.ID); | ||
662 | // coll.Collection.Folders.Clear(); | ||
663 | // coll.Collection.Folders.Add(containingFolder); | ||
664 | // if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null) | ||
665 | // { | ||
666 | // InventoryFolderBase lib = new InventoryFolderBase(m_LibraryService.LibraryRootFolder.ID, m_LibraryService.LibraryRootFolder.Owner); | ||
667 | // lib.Name = m_LibraryService.LibraryRootFolder.Name; | ||
668 | // lib.Type = m_LibraryService.LibraryRootFolder.Type; | ||
669 | // lib.Version = m_LibraryService.LibraryRootFolder.Version; | ||
670 | // coll.Collection.Folders.Add(lib); | ||
671 | // } | ||
672 | // coll.Collection.Items.Clear(); | ||
673 | //} | ||
674 | } | ||
675 | else | ||
676 | { | ||
677 | m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Unable to fetch folder {0}", freq.folder_id); | ||
678 | bad_folders.Add(freq.folder_id); | ||
679 | } | ||
680 | bad = true; | ||
681 | } | ||
682 | } | ||
683 | |||
684 | return bad; | ||
685 | } | ||
686 | |||
687 | private void ProcessLinks(LLSDFetchInventoryDescendents freq, InventoryCollectionWithDescendents coll) | ||
688 | { | ||
689 | InventoryCollection contents = coll.Collection; | ||
690 | |||
691 | if (freq.fetch_items && contents.Items != null) | ||
692 | { | ||
693 | List<InventoryItemBase> itemsToReturn = contents.Items; | ||
694 | |||
695 | // descendents must only include the links, not the linked items we add | ||
696 | coll.Descendents = itemsToReturn.Count; | ||
697 | |||
698 | // Add target items for links in this folder before the links themselves. | ||
699 | List<UUID> itemIDs = new List<UUID>(); | ||
700 | List<UUID> folderIDs = new List<UUID>(); | ||
701 | foreach (InventoryItemBase item in itemsToReturn) | ||
702 | { | ||
703 | //m_log.DebugFormat("[XXX]: {0} {1}", item.Name, item.AssetType); | ||
704 | if (item.AssetType == (int)AssetType.Link) | ||
705 | itemIDs.Add(item.AssetID); | ||
706 | |||
707 | else if (item.AssetType == (int)AssetType.LinkFolder) | ||
708 | folderIDs.Add(item.AssetID); | ||
709 | } | ||
710 | |||
711 | //m_log.DebugFormat("[XXX]: folder {0} has {1} links and {2} linkfolders", contents.FolderID, itemIDs.Count, folderIDs.Count); | ||
712 | |||
713 | // Scan for folder links and insert the items they target and those links at the head of the return data | ||
714 | if (folderIDs.Count > 0) | ||
715 | { | ||
716 | InventoryCollection[] linkedFolders = m_InventoryService.GetMultipleFoldersContent(coll.Collection.OwnerID, folderIDs.ToArray()); | ||
717 | foreach (InventoryCollection linkedFolderContents in linkedFolders) | ||
718 | { | ||
719 | List<InventoryItemBase> links = linkedFolderContents.Items; | ||
720 | |||
721 | itemsToReturn.InsertRange(0, links); | ||
722 | |||
723 | foreach (InventoryItemBase link in linkedFolderContents.Items) | ||
724 | { | ||
725 | // Take care of genuinely broken links where the target doesn't exist | ||
726 | // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
727 | // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
728 | // rather than having to keep track of every folder requested in the recursion. | ||
729 | if (link != null) | ||
730 | { | ||
731 | //m_log.DebugFormat( | ||
732 | // "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3} ({4} {5})", | ||
733 | // link.Name, (AssetType)link.AssetType, linkedFolderContents.FolderID, contents.FolderID, link.ID, link.AssetID); | ||
734 | itemIDs.Add(link.ID); | ||
735 | } | ||
736 | } | ||
737 | } | ||
738 | } | ||
739 | |||
740 | if (itemIDs.Count > 0) | ||
741 | { | ||
742 | InventoryItemBase[] linked = m_InventoryService.GetMultipleItems(freq.owner_id, itemIDs.ToArray()); | ||
743 | if (linked == null) | ||
744 | { | ||
745 | // OMG!!! One by one!!! This is fallback code, in case the backend isn't updated | ||
746 | m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: GetMultipleItems failed. Falling back to fetching inventory items one by one."); | ||
747 | linked = new InventoryItemBase[itemIDs.Count]; | ||
748 | int i = 0; | ||
749 | InventoryItemBase item = new InventoryItemBase(); | ||
750 | item.Owner = freq.owner_id; | ||
751 | foreach (UUID id in itemIDs) | ||
752 | { | ||
753 | item.ID = id; | ||
754 | linked[i++] = m_InventoryService.GetItem(item); | ||
755 | } | ||
756 | } | ||
757 | |||
758 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Processing folder {0}. Existing items:", freq.folder_id); | ||
759 | //foreach (InventoryItemBase item in itemsToReturn) | ||
760 | // m_log.DebugFormat("[XXX]: {0} {1} {2}", item.Name, item.AssetType, item.Folder); | ||
761 | |||
762 | if (linked != null) | ||
763 | { | ||
764 | foreach (InventoryItemBase linkedItem in linked) | ||
765 | { | ||
766 | // Take care of genuinely broken links where the target doesn't exist | ||
767 | // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
768 | // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
769 | // rather than having to keep track of every folder requested in the recursion. | ||
770 | if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) | ||
771 | { | ||
772 | itemsToReturn.Insert(0, linkedItem); | ||
773 | //m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Added {0} {1} {2}", linkedItem.Name, linkedItem.AssetType, linkedItem.Folder); | ||
774 | } | ||
775 | } | ||
776 | } | ||
777 | } | ||
778 | } | ||
779 | |||
780 | } | ||
781 | |||
782 | /// <summary> | ||
783 | /// Convert an internal inventory folder object into an LLSD object. | ||
784 | /// </summary> | ||
785 | /// <param name="invFolder"></param> | ||
786 | /// <returns></returns> | ||
787 | private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) | ||
788 | { | ||
789 | LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); | ||
790 | llsdFolder.folder_id = invFolder.ID; | ||
791 | llsdFolder.parent_id = invFolder.ParentID; | ||
792 | llsdFolder.name = invFolder.Name; | ||
793 | llsdFolder.type = invFolder.Type; | ||
794 | llsdFolder.preferred_type = -1; | ||
795 | |||
796 | return llsdFolder; | ||
797 | } | ||
798 | |||
799 | /// <summary> | ||
800 | /// Convert an internal inventory item object into an LLSD object. | ||
801 | /// </summary> | ||
802 | /// <param name="invItem"></param> | ||
803 | /// <returns></returns> | ||
804 | private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) | ||
805 | { | ||
806 | LLSDInventoryItem llsdItem = new LLSDInventoryItem(); | ||
807 | llsdItem.asset_id = invItem.AssetID; | ||
808 | llsdItem.created_at = invItem.CreationDate; | ||
809 | llsdItem.desc = invItem.Description; | ||
810 | llsdItem.flags = (int)invItem.Flags; | ||
811 | llsdItem.item_id = invItem.ID; | ||
812 | llsdItem.name = invItem.Name; | ||
813 | llsdItem.parent_id = invItem.Folder; | ||
814 | llsdItem.type = invItem.AssetType; | ||
815 | llsdItem.inv_type = invItem.InvType; | ||
816 | |||
817 | llsdItem.permissions = new LLSDPermissions(); | ||
818 | llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; | ||
819 | llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; | ||
820 | llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; | ||
821 | llsdItem.permissions.group_id = invItem.GroupID; | ||
822 | llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; | ||
823 | llsdItem.permissions.is_owner_group = invItem.GroupOwned; | ||
824 | llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; | ||
825 | llsdItem.permissions.owner_id = invItem.Owner; | ||
826 | llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; | ||
827 | llsdItem.sale_info = new LLSDSaleInfo(); | ||
828 | llsdItem.sale_info.sale_price = invItem.SalePrice; | ||
829 | llsdItem.sale_info.sale_type = invItem.SaleType; | ||
830 | |||
831 | return llsdItem; | ||
832 | } | ||
833 | } | ||
834 | |||
835 | class InventoryCollectionWithDescendents | ||
836 | { | ||
837 | public InventoryCollection Collection; | ||
838 | public int Descendents; | ||
839 | } | ||
840 | } \ No newline at end of file | ||
diff --git a/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescServerConnector.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs index 6fbe173..6fbe173 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescServerConnector.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInvDescServerConnector.cs | |||
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs index b67b326..b67b326 100644 --- a/OpenSim/Capabilities/Handlers/FetchInventory2/FetchInventory2Handler.cs +++ b/OpenSim/Capabilities/Handlers/FetchInventory/FetchInventory2Handler.cs | |||
diff --git a/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs new file mode 100644 index 0000000..d34423d --- /dev/null +++ b/OpenSim/Capabilities/Handlers/FetchInventory/Tests/FetchInventoryDescendents2HandlerTests.cs | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Linq; | ||
31 | using System.Net; | ||
32 | using log4net; | ||
33 | using log4net.Config; | ||
34 | using NUnit.Framework; | ||
35 | using OpenMetaverse; | ||
36 | using OpenSim.Capabilities.Handlers; | ||
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Framework.Servers.HttpServer; | ||
39 | using OpenSim.Region.Framework.Scenes; | ||
40 | using OpenSim.Services.Interfaces; | ||
41 | using OpenSim.Tests.Common; | ||
42 | |||
43 | namespace OpenSim.Capabilities.Handlers.FetchInventory.Tests | ||
44 | { | ||
45 | [TestFixture] | ||
46 | public class FetchInventoryDescendents2HandlerTests : OpenSimTestCase | ||
47 | { | ||
48 | private UUID m_userID = UUID.Zero; | ||
49 | private Scene m_scene; | ||
50 | private UUID m_rootFolderID; | ||
51 | private int m_rootDescendents; | ||
52 | private UUID m_notecardsFolder; | ||
53 | private UUID m_objectsFolder; | ||
54 | |||
55 | private void Init() | ||
56 | { | ||
57 | // Create an inventory that looks like this: | ||
58 | // | ||
59 | // /My Inventory | ||
60 | // <other system folders> | ||
61 | // /Objects | ||
62 | // Some Object | ||
63 | // /Notecards | ||
64 | // Notecard 1 | ||
65 | // Notecard 2 | ||
66 | // /Test Folder | ||
67 | // Link to notecard -> /Notecards/Notecard 2 | ||
68 | // Link to Objects folder -> /Objects | ||
69 | |||
70 | m_scene = new SceneHelpers().SetupScene(); | ||
71 | |||
72 | m_scene.InventoryService.CreateUserInventory(m_userID); | ||
73 | |||
74 | m_rootFolderID = m_scene.InventoryService.GetRootFolder(m_userID).ID; | ||
75 | |||
76 | InventoryFolderBase of = m_scene.InventoryService.GetFolderForType(m_userID, AssetType.Object); | ||
77 | m_objectsFolder = of.ID; | ||
78 | |||
79 | // Add an object | ||
80 | InventoryItemBase item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-00000000000b"), m_userID); | ||
81 | item.AssetID = UUID.Random(); | ||
82 | item.AssetType = (int)AssetType.Object; | ||
83 | item.Folder = m_objectsFolder; | ||
84 | item.Name = "Some Object"; | ||
85 | m_scene.InventoryService.AddItem(item); | ||
86 | |||
87 | InventoryFolderBase ncf = m_scene.InventoryService.GetFolderForType(m_userID, AssetType.Notecard); | ||
88 | m_notecardsFolder = ncf.ID; | ||
89 | |||
90 | // Add a notecard | ||
91 | item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-000000000001"), m_userID); | ||
92 | item.AssetID = UUID.Random(); | ||
93 | item.AssetType = (int)AssetType.Notecard; | ||
94 | item.Folder = m_notecardsFolder; | ||
95 | item.Name = "Test Notecard 1"; | ||
96 | m_scene.InventoryService.AddItem(item); | ||
97 | // Add another notecard | ||
98 | item.ID = new UUID("20000000-0000-0000-0000-000000000002"); | ||
99 | item.AssetID = new UUID("a0000000-0000-0000-0000-00000000000a"); | ||
100 | item.Name = "Test Notecard 2"; | ||
101 | m_scene.InventoryService.AddItem(item); | ||
102 | |||
103 | // Add a folder | ||
104 | InventoryFolderBase folder = new InventoryFolderBase(new UUID("f0000000-0000-0000-0000-00000000000f"), "Test Folder", m_userID, m_rootFolderID); | ||
105 | m_scene.InventoryService.AddFolder(folder); | ||
106 | |||
107 | // Add a link to notecard 2 in Test Folder | ||
108 | item.AssetID = item.ID; // use item ID of notecard 2 | ||
109 | item.ID = new UUID("40000000-0000-0000-0000-000000000004"); | ||
110 | item.AssetType = (int)AssetType.Link; | ||
111 | item.Folder = folder.ID; | ||
112 | item.Name = "Link to notecard"; | ||
113 | m_scene.InventoryService.AddItem(item); | ||
114 | |||
115 | // Add a link to the Objects folder in Test Folder | ||
116 | item.AssetID = m_scene.InventoryService.GetFolderForType(m_userID, AssetType.Object).ID; // use item ID of Objects folder | ||
117 | item.ID = new UUID("50000000-0000-0000-0000-000000000005"); | ||
118 | item.AssetType = (int)AssetType.LinkFolder; | ||
119 | item.Folder = folder.ID; | ||
120 | item.Name = "Link to Objects folder"; | ||
121 | m_scene.InventoryService.AddItem(item); | ||
122 | |||
123 | InventoryCollection coll = m_scene.InventoryService.GetFolderContent(m_userID, m_rootFolderID); | ||
124 | m_rootDescendents = coll.Items.Count + coll.Folders.Count; | ||
125 | Console.WriteLine("Number of descendents: " + m_rootDescendents); | ||
126 | } | ||
127 | |||
128 | [Test] | ||
129 | public void Test_001_SimpleFolder() | ||
130 | { | ||
131 | TestHelpers.InMethod(); | ||
132 | |||
133 | Init(); | ||
134 | |||
135 | FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null); | ||
136 | TestOSHttpRequest req = new TestOSHttpRequest(); | ||
137 | TestOSHttpResponse resp = new TestOSHttpResponse(); | ||
138 | |||
139 | string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>"; | ||
140 | request += m_rootFolderID; | ||
141 | request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>"; | ||
142 | |||
143 | string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp); | ||
144 | |||
145 | Assert.That(llsdresponse != null, Is.True, "Incorrect null response"); | ||
146 | Assert.That(llsdresponse != string.Empty, Is.True, "Incorrect empty response"); | ||
147 | Assert.That(llsdresponse.Contains("00000000-0000-0000-0000-000000000000"), Is.True, "Response should contain userID"); | ||
148 | |||
149 | string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>"; | ||
150 | Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents"); | ||
151 | Console.WriteLine(llsdresponse); | ||
152 | } | ||
153 | |||
154 | [Test] | ||
155 | public void Test_002_MultipleFolders() | ||
156 | { | ||
157 | TestHelpers.InMethod(); | ||
158 | |||
159 | FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null); | ||
160 | TestOSHttpRequest req = new TestOSHttpRequest(); | ||
161 | TestOSHttpResponse resp = new TestOSHttpResponse(); | ||
162 | |||
163 | string request = "<llsd><map><key>folders</key><array>"; | ||
164 | request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>"; | ||
165 | request += m_rootFolderID; | ||
166 | request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>"; | ||
167 | request += "<map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>"; | ||
168 | request += m_notecardsFolder; | ||
169 | request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map>"; | ||
170 | request += "</array></map></llsd>"; | ||
171 | |||
172 | string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp); | ||
173 | Console.WriteLine(llsdresponse); | ||
174 | |||
175 | string descendents = "descendents</key><integer>" + m_rootDescendents + "</integer>"; | ||
176 | Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for root folder"); | ||
177 | descendents = "descendents</key><integer>2</integer>"; | ||
178 | Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Notecard folder"); | ||
179 | |||
180 | Assert.That(llsdresponse.Contains("10000000-0000-0000-0000-000000000001"), Is.True, "Notecard 1 is missing from response"); | ||
181 | Assert.That(llsdresponse.Contains("20000000-0000-0000-0000-000000000002"), Is.True, "Notecard 2 is missing from response"); | ||
182 | } | ||
183 | |||
184 | [Test] | ||
185 | public void Test_003_Links() | ||
186 | { | ||
187 | TestHelpers.InMethod(); | ||
188 | |||
189 | FetchInvDescHandler handler = new FetchInvDescHandler(m_scene.InventoryService, null); | ||
190 | TestOSHttpRequest req = new TestOSHttpRequest(); | ||
191 | TestOSHttpResponse resp = new TestOSHttpResponse(); | ||
192 | |||
193 | string request = "<llsd><map><key>folders</key><array><map><key>fetch_folders</key><integer>1</integer><key>fetch_items</key><boolean>1</boolean><key>folder_id</key><uuid>"; | ||
194 | request += "f0000000-0000-0000-0000-00000000000f"; | ||
195 | request += "</uuid><key>owner_id</key><uuid>00000000-0000-0000-0000-000000000000</uuid><key>sort_order</key><integer>1</integer></map></array></map></llsd>"; | ||
196 | |||
197 | string llsdresponse = handler.FetchInventoryDescendentsRequest(request, "/FETCH", string.Empty, req, resp); | ||
198 | Console.WriteLine(llsdresponse); | ||
199 | |||
200 | string descendents = "descendents</key><integer>2</integer>"; | ||
201 | Assert.That(llsdresponse.Contains(descendents), Is.True, "Incorrect number of descendents for Test Folder"); | ||
202 | |||
203 | // Make sure that the note card link is included | ||
204 | Assert.That(llsdresponse.Contains("Link to notecard"), Is.True, "Link to notecard is missing"); | ||
205 | |||
206 | //Make sure the notecard item itself is included | ||
207 | Assert.That(llsdresponse.Contains("Test Notecard 2"), Is.True, "Notecard 2 item (the source) is missing"); | ||
208 | |||
209 | // Make sure that the source item is before the link item | ||
210 | int pos1 = llsdresponse.IndexOf("Test Notecard 2"); | ||
211 | int pos2 = llsdresponse.IndexOf("Link to notecard"); | ||
212 | Assert.Less(pos1, pos2, "Source of link is after link"); | ||
213 | |||
214 | // Make sure the folder link is included | ||
215 | Assert.That(llsdresponse.Contains("Link to Objects folder"), Is.True, "Link to Objects folder is missing"); | ||
216 | |||
217 | // Make sure the objects inside the Objects folder are included | ||
218 | // Note: I'm not entirely sure this is needed, but that's what I found in the implementation | ||
219 | Assert.That(llsdresponse.Contains("Some Object"), Is.True, "Some Object item (contents of the source) is missing"); | ||
220 | |||
221 | // Make sure that the source item is before the link item | ||
222 | pos1 = llsdresponse.IndexOf("Some Object"); | ||
223 | pos2 = llsdresponse.IndexOf("Link to Objects folder"); | ||
224 | Assert.Less(pos1, pos2, "Contents of source of folder link is after folder link"); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | } \ No newline at end of file | ||
diff --git a/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs b/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs deleted file mode 100644 index 451575f..0000000 --- a/OpenSim/Capabilities/Handlers/FetchInventoryDescendents/FetchInvDescHandler.cs +++ /dev/null | |||
@@ -1,465 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | using OpenMetaverse; | ||
35 | using OpenMetaverse.StructuredData; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Capabilities; | ||
38 | using OpenSim.Region.Framework.Interfaces; | ||
39 | using OpenSim.Framework.Servers.HttpServer; | ||
40 | using OpenSim.Services.Interfaces; | ||
41 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
42 | |||
43 | namespace OpenSim.Capabilities.Handlers | ||
44 | { | ||
45 | public class FetchInvDescHandler | ||
46 | { | ||
47 | private static readonly ILog m_log = | ||
48 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | private IInventoryService m_InventoryService; | ||
51 | private ILibraryService m_LibraryService; | ||
52 | // private object m_fetchLock = new Object(); | ||
53 | |||
54 | public FetchInvDescHandler(IInventoryService invService, ILibraryService libService) | ||
55 | { | ||
56 | m_InventoryService = invService; | ||
57 | m_LibraryService = libService; | ||
58 | } | ||
59 | |||
60 | public string FetchInventoryDescendentsRequest(string request, string path, string param, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) | ||
61 | { | ||
62 | // lock (m_fetchLock) | ||
63 | // { | ||
64 | // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Received request {0}", request); | ||
65 | |||
66 | // nasty temporary hack here, the linden client falsely | ||
67 | // identifies the uuid 00000000-0000-0000-0000-000000000000 | ||
68 | // as a string which breaks us | ||
69 | // | ||
70 | // correctly mark it as a uuid | ||
71 | // | ||
72 | request = request.Replace("<string>00000000-0000-0000-0000-000000000000</string>", "<uuid>00000000-0000-0000-0000-000000000000</uuid>"); | ||
73 | |||
74 | // another hack <integer>1</integer> results in a | ||
75 | // System.ArgumentException: Object type System.Int32 cannot | ||
76 | // be converted to target type: System.Boolean | ||
77 | // | ||
78 | request = request.Replace("<key>fetch_folders</key><integer>0</integer>", "<key>fetch_folders</key><boolean>0</boolean>"); | ||
79 | request = request.Replace("<key>fetch_folders</key><integer>1</integer>", "<key>fetch_folders</key><boolean>1</boolean>"); | ||
80 | |||
81 | Hashtable hash = new Hashtable(); | ||
82 | try | ||
83 | { | ||
84 | hash = (Hashtable)LLSD.LLSDDeserialize(Utils.StringToBytes(request)); | ||
85 | } | ||
86 | catch (LLSD.LLSDParseException e) | ||
87 | { | ||
88 | m_log.ErrorFormat("[WEB FETCH INV DESC HANDLER]: Fetch error: {0}{1}" + e.Message, e.StackTrace); | ||
89 | m_log.Error("Request: " + request); | ||
90 | } | ||
91 | |||
92 | ArrayList foldersrequested = (ArrayList)hash["folders"]; | ||
93 | |||
94 | string response = ""; | ||
95 | string bad_folders_response = ""; | ||
96 | |||
97 | for (int i = 0; i < foldersrequested.Count; i++) | ||
98 | { | ||
99 | string inventoryitemstr = ""; | ||
100 | Hashtable inventoryhash = (Hashtable)foldersrequested[i]; | ||
101 | |||
102 | LLSDFetchInventoryDescendents llsdRequest = new LLSDFetchInventoryDescendents(); | ||
103 | |||
104 | try | ||
105 | { | ||
106 | LLSDHelpers.DeserialiseOSDMap(inventoryhash, llsdRequest); | ||
107 | } | ||
108 | catch (Exception e) | ||
109 | { | ||
110 | m_log.Debug("[WEB FETCH INV DESC HANDLER]: caught exception doing OSD deserialize" + e); | ||
111 | } | ||
112 | LLSDInventoryDescendents reply = FetchInventoryReply(llsdRequest); | ||
113 | |||
114 | if (null == reply) | ||
115 | { | ||
116 | bad_folders_response += "<uuid>" + llsdRequest.folder_id.ToString() + "</uuid>"; | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | inventoryitemstr = LLSDHelpers.SerialiseLLSDReply(reply); | ||
121 | inventoryitemstr = inventoryitemstr.Replace("<llsd><map><key>folders</key><array>", ""); | ||
122 | inventoryitemstr = inventoryitemstr.Replace("</array></map></llsd>", ""); | ||
123 | } | ||
124 | |||
125 | response += inventoryitemstr; | ||
126 | } | ||
127 | |||
128 | if (response.Length == 0) | ||
129 | { | ||
130 | /* Viewers expect a bad_folders array when not available */ | ||
131 | if (bad_folders_response.Length != 0) | ||
132 | { | ||
133 | response = "<llsd><map><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | response = "<llsd><map><key>folders</key><array /></map></llsd>"; | ||
138 | } | ||
139 | } | ||
140 | else | ||
141 | { | ||
142 | if (bad_folders_response.Length != 0) | ||
143 | { | ||
144 | response = "<llsd><map><key>folders</key><array>" + response + "</array><key>bad_folders</key><array>" + bad_folders_response + "</array></map></llsd>"; | ||
145 | } | ||
146 | else | ||
147 | { | ||
148 | response = "<llsd><map><key>folders</key><array>" + response + "</array></map></llsd>"; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | // m_log.DebugFormat("[WEB FETCH INV DESC HANDLER]: Replying to CAPS fetch inventory request"); | ||
153 | //m_log.Debug("[WEB FETCH INV DESC HANDLER] "+response); | ||
154 | |||
155 | return response; | ||
156 | |||
157 | // } | ||
158 | } | ||
159 | |||
160 | /// <summary> | ||
161 | /// Construct an LLSD reply packet to a CAPS inventory request | ||
162 | /// </summary> | ||
163 | /// <param name="invFetch"></param> | ||
164 | /// <returns></returns> | ||
165 | private LLSDInventoryDescendents FetchInventoryReply(LLSDFetchInventoryDescendents invFetch) | ||
166 | { | ||
167 | LLSDInventoryDescendents reply = new LLSDInventoryDescendents(); | ||
168 | LLSDInventoryFolderContents contents = new LLSDInventoryFolderContents(); | ||
169 | contents.agent_id = invFetch.owner_id; | ||
170 | contents.owner_id = invFetch.owner_id; | ||
171 | contents.folder_id = invFetch.folder_id; | ||
172 | |||
173 | reply.folders.Array.Add(contents); | ||
174 | InventoryCollection inv = new InventoryCollection(); | ||
175 | inv.Folders = new List<InventoryFolderBase>(); | ||
176 | inv.Items = new List<InventoryItemBase>(); | ||
177 | int version = 0; | ||
178 | int descendents = 0; | ||
179 | |||
180 | inv | ||
181 | = Fetch( | ||
182 | invFetch.owner_id, invFetch.folder_id, invFetch.owner_id, | ||
183 | invFetch.fetch_folders, invFetch.fetch_items, invFetch.sort_order, out version, out descendents); | ||
184 | |||
185 | if (inv != null && inv.Folders != null) | ||
186 | { | ||
187 | foreach (InventoryFolderBase invFolder in inv.Folders) | ||
188 | { | ||
189 | contents.categories.Array.Add(ConvertInventoryFolder(invFolder)); | ||
190 | } | ||
191 | |||
192 | descendents += inv.Folders.Count; | ||
193 | } | ||
194 | |||
195 | if (inv != null && inv.Items != null) | ||
196 | { | ||
197 | foreach (InventoryItemBase invItem in inv.Items) | ||
198 | { | ||
199 | contents.items.Array.Add(ConvertInventoryItem(invItem)); | ||
200 | } | ||
201 | } | ||
202 | |||
203 | contents.descendents = descendents; | ||
204 | contents.version = version; | ||
205 | |||
206 | // m_log.DebugFormat( | ||
207 | // "[WEB FETCH INV DESC HANDLER]: Replying to request for folder {0} (fetch items {1}, fetch folders {2}) with {3} items and {4} folders for agent {5}", | ||
208 | // invFetch.folder_id, | ||
209 | // invFetch.fetch_items, | ||
210 | // invFetch.fetch_folders, | ||
211 | // contents.items.Array.Count, | ||
212 | // contents.categories.Array.Count, | ||
213 | // invFetch.owner_id); | ||
214 | |||
215 | return reply; | ||
216 | } | ||
217 | |||
218 | /// <summary> | ||
219 | /// Handle the caps inventory descendents fetch. | ||
220 | /// </summary> | ||
221 | /// <param name="agentID"></param> | ||
222 | /// <param name="folderID"></param> | ||
223 | /// <param name="ownerID"></param> | ||
224 | /// <param name="fetchFolders"></param> | ||
225 | /// <param name="fetchItems"></param> | ||
226 | /// <param name="sortOrder"></param> | ||
227 | /// <param name="version"></param> | ||
228 | /// <returns>An empty InventoryCollection if the inventory look up failed</returns> | ||
229 | private InventoryCollection Fetch( | ||
230 | UUID agentID, UUID folderID, UUID ownerID, | ||
231 | bool fetchFolders, bool fetchItems, int sortOrder, out int version, out int descendents) | ||
232 | { | ||
233 | //m_log.DebugFormat( | ||
234 | // "[WEB FETCH INV DESC HANDLER]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", | ||
235 | // fetchFolders, fetchItems, folderID, agentID); | ||
236 | |||
237 | // FIXME MAYBE: We're not handling sortOrder! | ||
238 | |||
239 | version = 0; | ||
240 | descendents = 0; | ||
241 | |||
242 | InventoryFolderImpl fold; | ||
243 | if (m_LibraryService != null && m_LibraryService.LibraryRootFolder != null && agentID == m_LibraryService.LibraryRootFolder.Owner) | ||
244 | { | ||
245 | if ((fold = m_LibraryService.LibraryRootFolder.FindFolder(folderID)) != null) | ||
246 | { | ||
247 | InventoryCollection ret = new InventoryCollection(); | ||
248 | ret.Folders = new List<InventoryFolderBase>(); | ||
249 | ret.Items = fold.RequestListOfItems(); | ||
250 | descendents = ret.Folders.Count + ret.Items.Count; | ||
251 | |||
252 | return ret; | ||
253 | } | ||
254 | } | ||
255 | |||
256 | InventoryCollection contents = new InventoryCollection(); | ||
257 | |||
258 | if (folderID != UUID.Zero) | ||
259 | { | ||
260 | InventoryCollection fetchedContents = m_InventoryService.GetFolderContent(agentID, folderID); | ||
261 | |||
262 | if (fetchedContents == null) | ||
263 | { | ||
264 | m_log.WarnFormat("[WEB FETCH INV DESC HANDLER]: Could not get contents of folder {0} for user {1}", folderID, agentID); | ||
265 | return contents; | ||
266 | } | ||
267 | |||
268 | contents = fetchedContents; | ||
269 | InventoryFolderBase containingFolder = new InventoryFolderBase(); | ||
270 | containingFolder.ID = folderID; | ||
271 | containingFolder.Owner = agentID; | ||
272 | containingFolder = m_InventoryService.GetFolder(containingFolder); | ||
273 | |||
274 | if (containingFolder != null) | ||
275 | { | ||
276 | // m_log.DebugFormat( | ||
277 | // "[WEB FETCH INV DESC HANDLER]: Retrieved folder {0} {1} for agent id {2}", | ||
278 | // containingFolder.Name, containingFolder.ID, agentID); | ||
279 | |||
280 | version = containingFolder.Version; | ||
281 | |||
282 | if (fetchItems) | ||
283 | { | ||
284 | List<InventoryItemBase> itemsToReturn = contents.Items; | ||
285 | List<InventoryItemBase> originalItems = new List<InventoryItemBase>(itemsToReturn); | ||
286 | |||
287 | // descendents must only include the links, not the linked items we add | ||
288 | descendents = originalItems.Count; | ||
289 | |||
290 | // Add target items for links in this folder before the links themselves. | ||
291 | foreach (InventoryItemBase item in originalItems) | ||
292 | { | ||
293 | if (item.AssetType == (int)AssetType.Link) | ||
294 | { | ||
295 | InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); | ||
296 | |||
297 | // Take care of genuinely broken links where the target doesn't exist | ||
298 | // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
299 | // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
300 | // rather than having to keep track of every folder requested in the recursion. | ||
301 | if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) | ||
302 | itemsToReturn.Insert(0, linkedItem); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | // Now scan for folder links and insert the items they target and those links at the head of the return data | ||
307 | foreach (InventoryItemBase item in originalItems) | ||
308 | { | ||
309 | if (item.AssetType == (int)AssetType.LinkFolder) | ||
310 | { | ||
311 | InventoryCollection linkedFolderContents = m_InventoryService.GetFolderContent(ownerID, item.AssetID); | ||
312 | List<InventoryItemBase> links = linkedFolderContents.Items; | ||
313 | |||
314 | itemsToReturn.InsertRange(0, links); | ||
315 | |||
316 | foreach (InventoryItemBase link in linkedFolderContents.Items) | ||
317 | { | ||
318 | // Take care of genuinely broken links where the target doesn't exist | ||
319 | // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
320 | // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
321 | // rather than having to keep track of every folder requested in the recursion. | ||
322 | if (link != null) | ||
323 | { | ||
324 | // m_log.DebugFormat( | ||
325 | // "[WEB FETCH INV DESC HANDLER]: Adding item {0} {1} from folder {2} linked from {3}", | ||
326 | // link.Name, (AssetType)link.AssetType, item.AssetID, containingFolder.Name); | ||
327 | |||
328 | InventoryItemBase linkedItem | ||
329 | = m_InventoryService.GetItem(new InventoryItemBase(link.AssetID)); | ||
330 | |||
331 | if (linkedItem != null) | ||
332 | itemsToReturn.Insert(0, linkedItem); | ||
333 | } | ||
334 | } | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | |||
339 | // foreach (InventoryItemBase item in contents.Items) | ||
340 | // { | ||
341 | // m_log.DebugFormat( | ||
342 | // "[WEB FETCH INV DESC HANDLER]: Returning item {0}, type {1}, parent {2} in {3} {4}", | ||
343 | // item.Name, (AssetType)item.AssetType, item.Folder, containingFolder.Name, containingFolder.ID); | ||
344 | // } | ||
345 | |||
346 | // ===== | ||
347 | |||
348 | // | ||
349 | // foreach (InventoryItemBase linkedItem in linkedItemsToAdd) | ||
350 | // { | ||
351 | // m_log.DebugFormat( | ||
352 | // "[WEB FETCH INV DESC HANDLER]: Inserted linked item {0} for link in folder {1} for agent {2}", | ||
353 | // linkedItem.Name, folderID, agentID); | ||
354 | // | ||
355 | // contents.Items.Add(linkedItem); | ||
356 | // } | ||
357 | // | ||
358 | // // If the folder requested contains links, then we need to send those folders first, otherwise the links | ||
359 | // // will be broken in the viewer. | ||
360 | // HashSet<UUID> linkedItemFolderIdsToSend = new HashSet<UUID>(); | ||
361 | // foreach (InventoryItemBase item in contents.Items) | ||
362 | // { | ||
363 | // if (item.AssetType == (int)AssetType.Link) | ||
364 | // { | ||
365 | // InventoryItemBase linkedItem = m_InventoryService.GetItem(new InventoryItemBase(item.AssetID)); | ||
366 | // | ||
367 | // // Take care of genuinely broken links where the target doesn't exist | ||
368 | // // HACK: Also, don't follow up links that just point to other links. In theory this is legitimate, | ||
369 | // // but no viewer has been observed to set these up and this is the lazy way of avoiding cycles | ||
370 | // // rather than having to keep track of every folder requested in the recursion. | ||
371 | // if (linkedItem != null && linkedItem.AssetType != (int)AssetType.Link) | ||
372 | // { | ||
373 | // // We don't need to send the folder if source and destination of the link are in the same | ||
374 | // // folder. | ||
375 | // if (linkedItem.Folder != containingFolder.ID) | ||
376 | // linkedItemFolderIdsToSend.Add(linkedItem.Folder); | ||
377 | // } | ||
378 | // } | ||
379 | // } | ||
380 | // | ||
381 | // foreach (UUID linkedItemFolderId in linkedItemFolderIdsToSend) | ||
382 | // { | ||
383 | // m_log.DebugFormat( | ||
384 | // "[WEB FETCH INV DESC HANDLER]: Recursively fetching folder {0} linked by item in folder {1} for agent {2}", | ||
385 | // linkedItemFolderId, folderID, agentID); | ||
386 | // | ||
387 | // int dummyVersion; | ||
388 | // InventoryCollection linkedCollection | ||
389 | // = Fetch( | ||
390 | // agentID, linkedItemFolderId, ownerID, fetchFolders, fetchItems, sortOrder, out dummyVersion); | ||
391 | // | ||
392 | // InventoryFolderBase linkedFolder = new InventoryFolderBase(linkedItemFolderId); | ||
393 | // linkedFolder.Owner = agentID; | ||
394 | // linkedFolder = m_InventoryService.GetFolder(linkedFolder); | ||
395 | // | ||
396 | //// contents.Folders.AddRange(linkedCollection.Folders); | ||
397 | // | ||
398 | // contents.Folders.Add(linkedFolder); | ||
399 | // contents.Items.AddRange(linkedCollection.Items); | ||
400 | // } | ||
401 | // } | ||
402 | } | ||
403 | } | ||
404 | else | ||
405 | { | ||
406 | // Lost items don't really need a version | ||
407 | version = 1; | ||
408 | } | ||
409 | |||
410 | return contents; | ||
411 | |||
412 | } | ||
413 | /// <summary> | ||
414 | /// Convert an internal inventory folder object into an LLSD object. | ||
415 | /// </summary> | ||
416 | /// <param name="invFolder"></param> | ||
417 | /// <returns></returns> | ||
418 | private LLSDInventoryFolder ConvertInventoryFolder(InventoryFolderBase invFolder) | ||
419 | { | ||
420 | LLSDInventoryFolder llsdFolder = new LLSDInventoryFolder(); | ||
421 | llsdFolder.folder_id = invFolder.ID; | ||
422 | llsdFolder.parent_id = invFolder.ParentID; | ||
423 | llsdFolder.name = invFolder.Name; | ||
424 | llsdFolder.type = invFolder.Type; | ||
425 | llsdFolder.preferred_type = -1; | ||
426 | |||
427 | return llsdFolder; | ||
428 | } | ||
429 | |||
430 | /// <summary> | ||
431 | /// Convert an internal inventory item object into an LLSD object. | ||
432 | /// </summary> | ||
433 | /// <param name="invItem"></param> | ||
434 | /// <returns></returns> | ||
435 | private LLSDInventoryItem ConvertInventoryItem(InventoryItemBase invItem) | ||
436 | { | ||
437 | LLSDInventoryItem llsdItem = new LLSDInventoryItem(); | ||
438 | llsdItem.asset_id = invItem.AssetID; | ||
439 | llsdItem.created_at = invItem.CreationDate; | ||
440 | llsdItem.desc = invItem.Description; | ||
441 | llsdItem.flags = (int)invItem.Flags; | ||
442 | llsdItem.item_id = invItem.ID; | ||
443 | llsdItem.name = invItem.Name; | ||
444 | llsdItem.parent_id = invItem.Folder; | ||
445 | llsdItem.type = invItem.AssetType; | ||
446 | llsdItem.inv_type = invItem.InvType; | ||
447 | |||
448 | llsdItem.permissions = new LLSDPermissions(); | ||
449 | llsdItem.permissions.creator_id = invItem.CreatorIdAsUuid; | ||
450 | llsdItem.permissions.base_mask = (int)invItem.CurrentPermissions; | ||
451 | llsdItem.permissions.everyone_mask = (int)invItem.EveryOnePermissions; | ||
452 | llsdItem.permissions.group_id = invItem.GroupID; | ||
453 | llsdItem.permissions.group_mask = (int)invItem.GroupPermissions; | ||
454 | llsdItem.permissions.is_owner_group = invItem.GroupOwned; | ||
455 | llsdItem.permissions.next_owner_mask = (int)invItem.NextPermissions; | ||
456 | llsdItem.permissions.owner_id = invItem.Owner; | ||
457 | llsdItem.permissions.owner_mask = (int)invItem.CurrentPermissions; | ||
458 | llsdItem.sale_info = new LLSDSaleInfo(); | ||
459 | llsdItem.sale_info.sale_price = invItem.SalePrice; | ||
460 | llsdItem.sale_info.sale_type = invItem.SaleType; | ||
461 | |||
462 | return llsdItem; | ||
463 | } | ||
464 | } | ||
465 | } \ No newline at end of file | ||
diff --git a/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs b/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs index 296cb03..3579649 100644 --- a/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs +++ b/OpenSim/Capabilities/Handlers/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs index 249842c..b46d175 100644 --- a/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/MySQL/Properties/AssemblyInfo.cs | |||
@@ -61,5 +61,5 @@ using System.Runtime.InteropServices; | |||
61 | // You can specify all the values or you can default the Revision and Build Numbers | 61 | // You can specify all the values or you can default the Revision and Build Numbers |
62 | // by using the '*' as shown below: | 62 | // by using the '*' as shown below: |
63 | 63 | ||
64 | [assembly : AssemblyVersion("0.8.1.*")] | 64 | [assembly : AssemblyVersion("0.8.2.*")] |
65 | 65 | ||
diff --git a/OpenSim/Data/Null/Properties/AssemblyInfo.cs b/OpenSim/Data/Null/Properties/AssemblyInfo.cs index 13e28a8..a827bd0 100644 --- a/OpenSim/Data/Null/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/Null/Properties/AssemblyInfo.cs | |||
@@ -61,5 +61,5 @@ using System.Runtime.InteropServices; | |||
61 | // You can specify all the values or you can default the Revision and Build Numbers | 61 | // You can specify all the values or you can default the Revision and Build Numbers |
62 | // by using the '*' as shown below: | 62 | // by using the '*' as shown below: |
63 | 63 | ||
64 | [assembly : AssemblyVersion("0.8.1.*")] | 64 | [assembly : AssemblyVersion("0.8.2.*")] |
65 | 65 | ||
diff --git a/OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs b/OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs index 1c65dbe..1e88b2c 100644 --- a/OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/PGSQL/Properties/AssemblyInfo.cs | |||
@@ -61,5 +61,5 @@ using System.Runtime.InteropServices; | |||
61 | // You can specify all the values or you can default the Revision and Build Numbers | 61 | // You can specify all the values or you can default the Revision and Build Numbers |
62 | // by using the '*' as shown below: | 62 | // by using the '*' as shown below: |
63 | 63 | ||
64 | [assembly : AssemblyVersion("0.8.1.*")] | 64 | [assembly : AssemblyVersion("0.8.2.*")] |
65 | 65 | ||
diff --git a/OpenSim/Data/Properties/AssemblyInfo.cs b/OpenSim/Data/Properties/AssemblyInfo.cs index 4e41308..b1f234b 100644 --- a/OpenSim/Data/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/Properties/AssemblyInfo.cs | |||
@@ -61,5 +61,5 @@ using System.Runtime.InteropServices; | |||
61 | // You can specify all the values or you can default the Revision and Build Numbers | 61 | // You can specify all the values or you can default the Revision and Build Numbers |
62 | // by using the '*' as shown below: | 62 | // by using the '*' as shown below: |
63 | 63 | ||
64 | [assembly : AssemblyVersion("0.8.1.*")] | 64 | [assembly : AssemblyVersion("0.8.2.*")] |
65 | 65 | ||
diff --git a/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs b/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs index 2befd13..d2e62d2 100644 --- a/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs +++ b/OpenSim/Data/SQLite/Properties/AssemblyInfo.cs | |||
@@ -61,5 +61,5 @@ using System.Runtime.InteropServices; | |||
61 | // You can specify all the values or you can default the Revision and Build Numbers | 61 | // You can specify all the values or you can default the Revision and Build Numbers |
62 | // by using the '*' as shown below: | 62 | // by using the '*' as shown below: |
63 | 63 | ||
64 | [assembly : AssemblyVersion("0.8.1.*")] | 64 | [assembly : AssemblyVersion("0.8.2.*")] |
65 | 65 | ||
diff --git a/OpenSim/Framework/AssemblyInfo.cs b/OpenSim/Framework/AssemblyInfo.cs index 5a15568..a797424 100644 --- a/OpenSim/Framework/AssemblyInfo.cs +++ b/OpenSim/Framework/AssemblyInfo.cs | |||
@@ -59,4 +59,4 @@ using System.Runtime.InteropServices; | |||
59 | // Revision | 59 | // Revision |
60 | // | 60 | // |
61 | 61 | ||
62 | [assembly : AssemblyVersion("0.8.1.*")] | 62 | [assembly : AssemblyVersion("0.8.2.*")] |
diff --git a/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs b/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs index 26d0351..cd182d6 100644 --- a/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/AssetLoader/Filesystem/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs index 907cebd..b398167 100644 --- a/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Communications/Properties/AssemblyInfo.cs | |||
@@ -61,5 +61,5 @@ using System.Runtime.InteropServices; | |||
61 | // You can specify all the values or you can default the Revision and Build Numbers | 61 | // You can specify all the values or you can default the Revision and Build Numbers |
62 | // by using the '*' as shown below: | 62 | // by using the '*' as shown below: |
63 | 63 | ||
64 | [assembly : AssemblyVersion("0.8.1.*")] | 64 | [assembly : AssemblyVersion("0.8.2.*")] |
65 | 65 | ||
diff --git a/OpenSim/Framework/Console/AssemblyInfo.cs b/OpenSim/Framework/Console/AssemblyInfo.cs index 4e50e44..67af471 100644 --- a/OpenSim/Framework/Console/AssemblyInfo.cs +++ b/OpenSim/Framework/Console/AssemblyInfo.cs | |||
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices; | |||
55 | // You can specify all values by your own or you can build default build and revision | 55 | // You can specify all values by your own or you can build default build and revision |
56 | // numbers with the '*' character (the default): | 56 | // numbers with the '*' character (the default): |
57 | 57 | ||
58 | [assembly : AssemblyVersion("0.8.1.*")] | 58 | [assembly : AssemblyVersion("0.8.2.*")] |
diff --git a/OpenSim/Framework/InventoryCollection.cs b/OpenSim/Framework/InventoryCollection.cs index 7049902..59655eb 100644 --- a/OpenSim/Framework/InventoryCollection.cs +++ b/OpenSim/Framework/InventoryCollection.cs | |||
@@ -37,6 +37,8 @@ namespace OpenSim.Framework | |||
37 | { | 37 | { |
38 | public List<InventoryFolderBase> Folders; | 38 | public List<InventoryFolderBase> Folders; |
39 | public List<InventoryItemBase> Items; | 39 | public List<InventoryItemBase> Items; |
40 | public UUID UserID; | 40 | public UUID OwnerID; |
41 | public UUID FolderID; | ||
42 | public int Version; | ||
41 | } | 43 | } |
42 | } | 44 | } |
diff --git a/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs b/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs index ee82753..b08e4f7 100644 --- a/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Monitoring/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Framework/RegionLoader/Filesystem/Properties/AssemblyInfo.cs b/OpenSim/Framework/RegionLoader/Filesystem/Properties/AssemblyInfo.cs index 4341560..3bcbe2f 100644 --- a/OpenSim/Framework/RegionLoader/Filesystem/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/RegionLoader/Filesystem/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Framework/RegionLoader/Web/Properties/AssemblyInfo.cs b/OpenSim/Framework/RegionLoader/Web/Properties/AssemblyInfo.cs index e7efdf4..1b2519c 100644 --- a/OpenSim/Framework/RegionLoader/Web/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/RegionLoader/Web/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs index 6debf65..64de18b 100644 --- a/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs +++ b/OpenSim/Framework/Serialization/External/ExternalRepresentationUtils.cs | |||
@@ -125,7 +125,8 @@ namespace OpenSim.Framework.Serialization.External | |||
125 | /// <param name="userService">The service for retrieving user account information</param> | 125 | /// <param name="userService">The service for retrieving user account information</param> |
126 | /// <param name="scopeID">The scope of the user account information (Grid ID)</param> | 126 | /// <param name="scopeID">The scope of the user account information (Grid ID)</param> |
127 | /// <returns>The SceneObjectPart represented in XML2</returns> | 127 | /// <returns>The SceneObjectPart represented in XML2</returns> |
128 | public static string RewriteSOP(string xml, string homeURL, IUserAccountService userService, UUID scopeID) | 128 | [Obsolete("This method is deprecated. Use RewriteSOP instead.")] |
129 | public static string RewriteSOP_Old(string xml, string homeURL, IUserAccountService userService, UUID scopeID) | ||
129 | { | 130 | { |
130 | if (xml == string.Empty || homeURL == string.Empty || userService == null) | 131 | if (xml == string.Empty || homeURL == string.Empty || userService == null) |
131 | return xml; | 132 | return xml; |
@@ -173,6 +174,187 @@ namespace OpenSim.Framework.Serialization.External | |||
173 | } | 174 | } |
174 | } | 175 | } |
175 | 176 | ||
177 | /// <summary> | ||
178 | /// Takes a XML representation of a SceneObjectPart and returns another XML representation | ||
179 | /// with creator data added to it. | ||
180 | /// </summary> | ||
181 | /// <param name="xml">The SceneObjectPart represented in XML2</param> | ||
182 | /// <param name="sceneName">An identifier for the component that's calling this function</param> | ||
183 | /// <param name="homeURL">The URL of the user agents service (home) for the creator</param> | ||
184 | /// <param name="userService">The service for retrieving user account information</param> | ||
185 | /// <param name="scopeID">The scope of the user account information (Grid ID)</param> | ||
186 | /// <returns>The SceneObjectPart represented in XML2</returns> | ||
187 | public static string RewriteSOP(string xmlData, string sceneName, string homeURL, IUserAccountService userService, UUID scopeID) | ||
188 | { | ||
189 | // Console.WriteLine("Input XML [{0}]", xmlData); | ||
190 | if (xmlData == string.Empty || homeURL == string.Empty || userService == null) | ||
191 | return xmlData; | ||
192 | |||
193 | using (StringWriter sw = new StringWriter()) | ||
194 | using (XmlTextWriter writer = new XmlTextWriter(sw)) | ||
195 | using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) | ||
196 | using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) | ||
197 | { | ||
198 | TransformXml(reader, writer, sceneName, homeURL, userService, scopeID); | ||
199 | |||
200 | // Console.WriteLine("Output: [{0}]", sw.ToString()); | ||
201 | |||
202 | return sw.ToString(); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | protected static void TransformXml(XmlReader reader, XmlWriter writer, string sceneName, string homeURI, IUserAccountService userAccountService, UUID scopeID) | ||
207 | { | ||
208 | // m_log.DebugFormat("[HG ASSET MAPPER]: Transforming XML"); | ||
209 | |||
210 | int sopDepth = -1; | ||
211 | UserAccount creator = null; | ||
212 | bool hasCreatorData = false; | ||
213 | |||
214 | while (reader.Read()) | ||
215 | { | ||
216 | // Console.WriteLine("Depth: {0}, name {1}", reader.Depth, reader.Name); | ||
217 | |||
218 | switch (reader.NodeType) | ||
219 | { | ||
220 | case XmlNodeType.Attribute: | ||
221 | // Console.WriteLine("FOUND ATTRIBUTE {0}", reader.Name); | ||
222 | writer.WriteAttributeString(reader.Name, reader.Value); | ||
223 | break; | ||
224 | |||
225 | case XmlNodeType.CDATA: | ||
226 | writer.WriteCData(reader.Value); | ||
227 | break; | ||
228 | |||
229 | case XmlNodeType.Comment: | ||
230 | writer.WriteComment(reader.Value); | ||
231 | break; | ||
232 | |||
233 | case XmlNodeType.DocumentType: | ||
234 | writer.WriteDocType(reader.Name, reader.Value, null, null); | ||
235 | break; | ||
236 | |||
237 | case XmlNodeType.Element: | ||
238 | // m_log.DebugFormat("Depth {0} at element {1}", reader.Depth, reader.Name); | ||
239 | |||
240 | writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); | ||
241 | |||
242 | if (reader.HasAttributes) | ||
243 | { | ||
244 | while (reader.MoveToNextAttribute()) | ||
245 | writer.WriteAttributeString(reader.Name, reader.Value); | ||
246 | |||
247 | reader.MoveToElement(); | ||
248 | } | ||
249 | |||
250 | if (reader.LocalName == "SceneObjectPart") | ||
251 | { | ||
252 | if (sopDepth < 0) | ||
253 | { | ||
254 | sopDepth = reader.Depth; | ||
255 | // m_log.DebugFormat("[HG ASSET MAPPER]: Set sopDepth to {0}", sopDepth); | ||
256 | } | ||
257 | } | ||
258 | else | ||
259 | { | ||
260 | if (sopDepth >= 0 && reader.Depth == sopDepth + 1) | ||
261 | { | ||
262 | if (reader.Name == "CreatorID") | ||
263 | { | ||
264 | reader.Read(); | ||
265 | if (reader.NodeType == XmlNodeType.Element && reader.Name == "Guid" || reader.Name == "UUID") | ||
266 | { | ||
267 | reader.Read(); | ||
268 | |||
269 | if (reader.NodeType == XmlNodeType.Text) | ||
270 | { | ||
271 | UUID uuid = UUID.Zero; | ||
272 | UUID.TryParse(reader.Value, out uuid); | ||
273 | creator = userAccountService.GetUserAccount(scopeID, uuid); | ||
274 | writer.WriteElementString("UUID", reader.Value); | ||
275 | reader.Read(); | ||
276 | } | ||
277 | else | ||
278 | { | ||
279 | // If we unexpected run across mixed content in this node, still carry on | ||
280 | // transforming the subtree (this replicates earlier behaviour). | ||
281 | TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID); | ||
282 | } | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | // If we unexpected run across mixed content in this node, still carry on | ||
287 | // transforming the subtree (this replicates earlier behaviour). | ||
288 | TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID); | ||
289 | } | ||
290 | } | ||
291 | else if (reader.Name == "CreatorData") | ||
292 | { | ||
293 | reader.Read(); | ||
294 | if (reader.NodeType == XmlNodeType.Text) | ||
295 | { | ||
296 | hasCreatorData = true; | ||
297 | writer.WriteString(reader.Value); | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | // If we unexpected run across mixed content in this node, still carry on | ||
302 | // transforming the subtree (this replicates earlier behaviour). | ||
303 | TransformXml(reader, writer, sceneName, homeURI, userAccountService, scopeID); | ||
304 | } | ||
305 | } | ||
306 | } | ||
307 | } | ||
308 | |||
309 | if (reader.IsEmptyElement) | ||
310 | { | ||
311 | // m_log.DebugFormat("[HG ASSET MAPPER]: Writing end for empty element {0}", reader.Name); | ||
312 | writer.WriteEndElement(); | ||
313 | } | ||
314 | |||
315 | break; | ||
316 | |||
317 | case XmlNodeType.EndElement: | ||
318 | // m_log.DebugFormat("Depth {0} at EndElement", reader.Depth); | ||
319 | if (sopDepth == reader.Depth) | ||
320 | { | ||
321 | if (!hasCreatorData && creator != null) | ||
322 | writer.WriteElementString(reader.Prefix, "CreatorData", reader.NamespaceURI, string.Format("{0};{1} {2}", homeURI, creator.FirstName, creator.LastName)); | ||
323 | |||
324 | // m_log.DebugFormat("[HG ASSET MAPPER]: Reset sopDepth"); | ||
325 | sopDepth = -1; | ||
326 | creator = null; | ||
327 | hasCreatorData = false; | ||
328 | } | ||
329 | writer.WriteEndElement(); | ||
330 | break; | ||
331 | |||
332 | case XmlNodeType.EntityReference: | ||
333 | writer.WriteEntityRef(reader.Name); | ||
334 | break; | ||
335 | |||
336 | case XmlNodeType.ProcessingInstruction: | ||
337 | writer.WriteProcessingInstruction(reader.Name, reader.Value); | ||
338 | break; | ||
339 | |||
340 | case XmlNodeType.Text: | ||
341 | writer.WriteString(reader.Value); | ||
342 | break; | ||
343 | |||
344 | case XmlNodeType.XmlDeclaration: | ||
345 | // For various reasons, not all serializations have xml declarations (or consistent ones) | ||
346 | // and as it's embedded inside a byte stream we don't need it anyway, so ignore. | ||
347 | break; | ||
348 | |||
349 | default: | ||
350 | m_log.WarnFormat( | ||
351 | "[HG ASSET MAPPER]: Unrecognized node {0} in asset XML transform in {1}", | ||
352 | reader.NodeType, sceneName); | ||
353 | break; | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | |||
176 | public static string CalcCreatorData(string homeURL, string name) | 358 | public static string CalcCreatorData(string homeURL, string name) |
177 | { | 359 | { |
178 | return homeURL + ";" + name; | 360 | return homeURL + ";" + name; |
diff --git a/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs b/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs index 11573d2..0cce722 100644 --- a/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Serialization/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs index ddb7e59..63335bd 100644 --- a/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs +++ b/OpenSim/Framework/Servers/HttpServer/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs index c22c119..e403ba0 100644 --- a/OpenSim/Framework/Servers/ServerBase.cs +++ b/OpenSim/Framework/Servers/ServerBase.cs | |||
@@ -292,11 +292,11 @@ namespace OpenSim.Framework.Servers | |||
292 | + " 3 = full stack trace, including common threads\n", | 292 | + " 3 = full stack trace, including common threads\n", |
293 | HandleDebugThreadpoolLevel); | 293 | HandleDebugThreadpoolLevel); |
294 | 294 | ||
295 | m_console.Commands.AddCommand( | 295 | // m_console.Commands.AddCommand( |
296 | "Debug", false, "show threadpool calls active", | 296 | // "Debug", false, "show threadpool calls active", |
297 | "show threadpool calls active", | 297 | // "show threadpool calls active", |
298 | "Show details about threadpool calls that are still active (currently waiting or in progress)", | 298 | // "Show details about threadpool calls that are still active (currently waiting or in progress)", |
299 | HandleShowThreadpoolCallsActive); | 299 | // HandleShowThreadpoolCallsActive); |
300 | 300 | ||
301 | m_console.Commands.AddCommand( | 301 | m_console.Commands.AddCommand( |
302 | "Debug", false, "show threadpool calls complete", | 302 | "Debug", false, "show threadpool calls complete", |
diff --git a/OpenSim/Region/Application/Properties/AssemblyInfo.cs b/OpenSim/Region/Application/Properties/AssemblyInfo.cs index 650425b..8652312 100644 --- a/OpenSim/Region/Application/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Application/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | [assembly: AddinRoot("OpenSim", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: AddinRoot("OpenSim", OpenSim.VersionInfo.VersionNumber)] |
36 | [assembly: ImportAddinAssembly("OpenSim.Framework.dll")] | 36 | [assembly: ImportAddinAssembly("OpenSim.Framework.dll")] |
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs index 3bc0be8..264eaa3 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 053a6a2..30d1921 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs | |||
@@ -201,11 +201,12 @@ namespace OpenSim.Region.ClientStack.Linden | |||
201 | 201 | ||
202 | Scene.EventManager.OnRegisterCaps += RegisterCaps; | 202 | Scene.EventManager.OnRegisterCaps += RegisterCaps; |
203 | 203 | ||
204 | int nworkers = 2; // was 2 | ||
204 | if (ProcessQueuedRequestsAsync && m_workerThreads == null) | 205 | if (ProcessQueuedRequestsAsync && m_workerThreads == null) |
205 | { | 206 | { |
206 | m_workerThreads = new Thread[2]; | 207 | m_workerThreads = new Thread[nworkers]; |
207 | 208 | ||
208 | for (uint i = 0; i < 2; i++) | 209 | for (uint i = 0; i < nworkers; i++) |
209 | { | 210 | { |
210 | m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests, | 211 | m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests, |
211 | String.Format("InventoryWorkerThread{0}", i), | 212 | String.Format("InventoryWorkerThread{0}", i), |
@@ -364,7 +365,11 @@ namespace OpenSim.Region.ClientStack.Linden | |||
364 | requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); | 365 | requestinfo.request["body"].ToString(), String.Empty, String.Empty, null, null); |
365 | 366 | ||
366 | lock (responses) | 367 | lock (responses) |
368 | { | ||
369 | if (responses.ContainsKey(requestID)) | ||
370 | m_log.WarnFormat("[FETCH INVENTORY DESCENDENTS2 MODULE]: Caught in the act of loosing responses! Please report this on mantis #7054"); | ||
367 | responses[requestID] = response; | 371 | responses[requestID] = response; |
372 | } | ||
368 | 373 | ||
369 | WebFetchInvDescModule.ProcessedRequestsCount++; | 374 | WebFetchInvDescModule.ProcessedRequestsCount++; |
370 | } | 375 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 311dd31..284c5fa 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -3747,6 +3747,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3747 | avp.Sender.IsTrial = false; | 3747 | avp.Sender.IsTrial = false; |
3748 | avp.Sender.ID = agentID; | 3748 | avp.Sender.ID = agentID; |
3749 | avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; | 3749 | avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; |
3750 | avp.AppearanceHover = new AvatarAppearancePacket.AppearanceHoverBlock[0]; | ||
3750 | //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); | 3751 | //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); |
3751 | OutPacket(avp, ThrottleOutPacketType.Task); | 3752 | OutPacket(avp, ThrottleOutPacketType.Task); |
3752 | } | 3753 | } |
@@ -4465,7 +4466,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4465 | { | 4466 | { |
4466 | uint priority = 0; // time based ordering only | 4467 | uint priority = 0; // time based ordering only |
4467 | lock (m_entityProps.SyncRoot) | 4468 | lock (m_entityProps.SyncRoot) |
4468 | m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false)); | 4469 | m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,true)); |
4469 | } | 4470 | } |
4470 | 4471 | ||
4471 | private void ResendPropertyUpdate(ObjectPropertyUpdate update) | 4472 | private void ResendPropertyUpdate(ObjectPropertyUpdate update) |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs index 8ce1b85..8795c0c 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index 75f0774..f54298c 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs | |||
@@ -35,6 +35,7 @@ using System.Xml; | |||
35 | using log4net; | 35 | using log4net; |
36 | using OpenMetaverse; | 36 | using OpenMetaverse; |
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Serialization.External; | ||
38 | 39 | ||
39 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Region.Framework.Scenes.Serialization; | 41 | using OpenSim.Region.Framework.Scenes.Serialization; |
@@ -189,217 +190,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
189 | return Utils.StringToBytes(RewriteSOP(xml)); | 190 | return Utils.StringToBytes(RewriteSOP(xml)); |
190 | } | 191 | } |
191 | 192 | ||
192 | protected void TransformXml(XmlReader reader, XmlWriter writer) | ||
193 | { | ||
194 | // m_log.DebugFormat("[HG ASSET MAPPER]: Transforming XML"); | ||
195 | |||
196 | int sopDepth = -1; | ||
197 | UserAccount creator = null; | ||
198 | bool hasCreatorData = false; | ||
199 | |||
200 | while (reader.Read()) | ||
201 | { | ||
202 | // Console.WriteLine("Depth: {0}, name {1}", reader.Depth, reader.Name); | ||
203 | |||
204 | switch (reader.NodeType) | ||
205 | { | ||
206 | case XmlNodeType.Attribute: | ||
207 | // Console.WriteLine("FOUND ATTRIBUTE {0}", reader.Name); | ||
208 | writer.WriteAttributeString(reader.Prefix, reader.Name, reader.NamespaceURI, reader.Value); | ||
209 | break; | ||
210 | |||
211 | case XmlNodeType.CDATA: | ||
212 | writer.WriteCData(reader.Value); | ||
213 | break; | ||
214 | |||
215 | case XmlNodeType.Comment: | ||
216 | writer.WriteComment(reader.Value); | ||
217 | break; | ||
218 | |||
219 | case XmlNodeType.DocumentType: | ||
220 | writer.WriteDocType(reader.Name, reader.Value, null, null); | ||
221 | break; | ||
222 | |||
223 | case XmlNodeType.Element: | ||
224 | // m_log.DebugFormat("Depth {0} at element {1}", reader.Depth, reader.Name); | ||
225 | |||
226 | writer.WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI); | ||
227 | |||
228 | if (reader.HasAttributes) | ||
229 | { | ||
230 | while (reader.MoveToNextAttribute()) | ||
231 | writer.WriteAttributeString(reader.Prefix, reader.Name, reader.NamespaceURI, reader.Value); | ||
232 | |||
233 | reader.MoveToElement(); | ||
234 | } | ||
235 | |||
236 | if (reader.LocalName == "SceneObjectPart") | ||
237 | { | ||
238 | if (sopDepth < 0) | ||
239 | { | ||
240 | sopDepth = reader.Depth; | ||
241 | // m_log.DebugFormat("[HG ASSET MAPPER]: Set sopDepth to {0}", sopDepth); | ||
242 | } | ||
243 | } | ||
244 | else | ||
245 | { | ||
246 | if (sopDepth >= 0 && reader.Depth == sopDepth + 1) | ||
247 | { | ||
248 | if (reader.Name == "CreatorID") | ||
249 | { | ||
250 | reader.Read(); | ||
251 | if (reader.NodeType == XmlNodeType.Element && reader.Name == "Guid" || reader.Name == "UUID") | ||
252 | { | ||
253 | reader.Read(); | ||
254 | |||
255 | if (reader.NodeType == XmlNodeType.Text) | ||
256 | { | ||
257 | UUID uuid = UUID.Zero; | ||
258 | UUID.TryParse(reader.Value, out uuid); | ||
259 | creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); | ||
260 | writer.WriteElementString("UUID", reader.Value); | ||
261 | reader.Read(); | ||
262 | } | ||
263 | else | ||
264 | { | ||
265 | // If we unexpected run across mixed content in this node, still carry on | ||
266 | // transforming the subtree (this replicates earlier behaviour). | ||
267 | TransformXml(reader, writer); | ||
268 | } | ||
269 | } | ||
270 | else | ||
271 | { | ||
272 | // If we unexpected run across mixed content in this node, still carry on | ||
273 | // transforming the subtree (this replicates earlier behaviour). | ||
274 | TransformXml(reader, writer); | ||
275 | } | ||
276 | } | ||
277 | else if (reader.Name == "CreatorData") | ||
278 | { | ||
279 | reader.Read(); | ||
280 | if (reader.NodeType == XmlNodeType.Text) | ||
281 | { | ||
282 | hasCreatorData = true; | ||
283 | writer.WriteString(reader.Value); | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | // If we unexpected run across mixed content in this node, still carry on | ||
288 | // transforming the subtree (this replicates earlier behaviour). | ||
289 | TransformXml(reader, writer); | ||
290 | } | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | |||
295 | if (reader.IsEmptyElement) | ||
296 | { | ||
297 | // m_log.DebugFormat("[HG ASSET MAPPER]: Writing end for empty element {0}", reader.Name); | ||
298 | writer.WriteEndElement(); | ||
299 | } | ||
300 | |||
301 | break; | ||
302 | |||
303 | case XmlNodeType.EndElement: | ||
304 | // m_log.DebugFormat("Depth {0} at EndElement", reader.Depth); | ||
305 | if (sopDepth == reader.Depth) | ||
306 | { | ||
307 | if (!hasCreatorData && creator != null) | ||
308 | writer.WriteElementString(reader.Prefix, "CreatorData", reader.NamespaceURI, string.Format("{0};{1} {2}", m_HomeURI, creator.FirstName, creator.LastName)); | ||
309 | |||
310 | // m_log.DebugFormat("[HG ASSET MAPPER]: Reset sopDepth"); | ||
311 | sopDepth = -1; | ||
312 | creator = null; | ||
313 | hasCreatorData = false; | ||
314 | } | ||
315 | writer.WriteEndElement(); | ||
316 | break; | ||
317 | |||
318 | case XmlNodeType.EntityReference: | ||
319 | writer.WriteEntityRef(reader.Name); | ||
320 | break; | ||
321 | |||
322 | case XmlNodeType.ProcessingInstruction: | ||
323 | writer.WriteProcessingInstruction(reader.Name, reader.Value); | ||
324 | break; | ||
325 | |||
326 | case XmlNodeType.Text: | ||
327 | writer.WriteString(reader.Value); | ||
328 | break; | ||
329 | |||
330 | case XmlNodeType.XmlDeclaration: | ||
331 | // For various reasons, not all serializations have xml declarations (or consistent ones) | ||
332 | // and as it's embedded inside a byte stream we don't need it anyway, so ignore. | ||
333 | break; | ||
334 | |||
335 | default: | ||
336 | m_log.WarnFormat( | ||
337 | "[HG ASSET MAPPER]: Unrecognized node {0} in asset XML transform in {1}", | ||
338 | reader.NodeType, m_scene.Name); | ||
339 | break; | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | protected string RewriteSOP(string xmlData) | 193 | protected string RewriteSOP(string xmlData) |
345 | { | 194 | { |
346 | // Console.WriteLine("Input XML [{0}]", xmlData); | 195 | // Console.WriteLine("Input XML [{0}]", xmlData); |
196 | return ExternalRepresentationUtils.RewriteSOP(xmlData, m_scene.Name, m_HomeURI, m_scene.UserAccountService, m_scene.RegionInfo.ScopeID); | ||
347 | 197 | ||
348 | using (StringWriter sw = new StringWriter()) | ||
349 | using (XmlTextWriter writer = new XmlTextWriter(sw)) | ||
350 | using (XmlTextReader wrappedReader = new XmlTextReader(xmlData, XmlNodeType.Element, null)) | ||
351 | using (XmlReader reader = XmlReader.Create(wrappedReader, new XmlReaderSettings() { IgnoreWhitespace = true, ConformanceLevel = ConformanceLevel.Fragment })) | ||
352 | { | ||
353 | TransformXml(reader, writer); | ||
354 | |||
355 | // Console.WriteLine("Output: [{0}]", sw.ToString()); | ||
356 | |||
357 | return sw.ToString(); | ||
358 | } | ||
359 | |||
360 | // We are now taking the more complex streaming approach above because some assets can be very large | ||
361 | // and can trigger higher CPU use or possibly memory problems. | ||
362 | // XmlDocument doc = new XmlDocument(); | ||
363 | // doc.LoadXml(xml); | ||
364 | // XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); | ||
365 | // | ||
366 | // foreach (XmlNode sop in sops) | ||
367 | // { | ||
368 | // UserAccount creator = null; | ||
369 | // bool hasCreatorData = false; | ||
370 | // XmlNodeList nodes = sop.ChildNodes; | ||
371 | // foreach (XmlNode node in nodes) | ||
372 | // { | ||
373 | // if (node.Name == "CreatorID") | ||
374 | // { | ||
375 | // UUID uuid = UUID.Zero; | ||
376 | // UUID.TryParse(node.InnerText, out uuid); | ||
377 | // creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); | ||
378 | // } | ||
379 | // if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty) | ||
380 | // hasCreatorData = true; | ||
381 | // | ||
382 | // //if (node.Name == "OwnerID") | ||
383 | // //{ | ||
384 | // // UserAccount owner = GetUser(node.InnerText); | ||
385 | // // if (owner != null) | ||
386 | // // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName; | ||
387 | // //} | ||
388 | // } | ||
389 | // | ||
390 | // if (!hasCreatorData && creator != null) | ||
391 | // { | ||
392 | // XmlElement creatorData = doc.CreateElement("CreatorData"); | ||
393 | // creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName; | ||
394 | // sop.AppendChild(creatorData); | ||
395 | // } | ||
396 | // } | ||
397 | // | ||
398 | // using (StringWriter wr = new StringWriter()) | ||
399 | // { | ||
400 | // doc.Save(wr); | ||
401 | // return wr.ToString(); | ||
402 | // } | ||
403 | } | 198 | } |
404 | 199 | ||
405 | // TODO: unused | 200 | // TODO: unused |
diff --git a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs index 01814a1..e657f53 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs | |||
@@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library | |||
65 | { | 65 | { |
66 | InventoryFolderImpl folder = null; | 66 | InventoryFolderImpl folder = null; |
67 | InventoryCollection inv = new InventoryCollection(); | 67 | InventoryCollection inv = new InventoryCollection(); |
68 | inv.UserID = m_Library.Owner; | 68 | inv.OwnerID = m_Library.Owner; |
69 | 69 | ||
70 | if (folderID != m_Library.ID) | 70 | if (folderID != m_Library.ID) |
71 | { | 71 | { |
@@ -87,6 +87,34 @@ namespace OpenSim.Region.CoreModules.Framework.Library | |||
87 | return inv; | 87 | return inv; |
88 | } | 88 | } |
89 | 89 | ||
90 | public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs) | ||
91 | { | ||
92 | InventoryCollection[] invColl = new InventoryCollection[folderIDs.Length]; | ||
93 | int i = 0; | ||
94 | foreach (UUID fid in folderIDs) | ||
95 | { | ||
96 | invColl[i++] = GetFolderContent(principalID, fid); | ||
97 | } | ||
98 | |||
99 | return invColl; | ||
100 | } | ||
101 | |||
102 | public virtual InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs) | ||
103 | { | ||
104 | InventoryItemBase[] itemColl = new InventoryItemBase[itemIDs.Length]; | ||
105 | int i = 0; | ||
106 | InventoryItemBase item = new InventoryItemBase(); | ||
107 | item.Owner = principalID; | ||
108 | foreach (UUID fid in itemIDs) | ||
109 | { | ||
110 | item.ID = fid; | ||
111 | itemColl[i++] = GetItem(item); | ||
112 | } | ||
113 | |||
114 | return itemColl; | ||
115 | } | ||
116 | |||
117 | |||
90 | /// <summary> | 118 | /// <summary> |
91 | /// Add a new folder to the user's inventory | 119 | /// Add a new folder to the user's inventory |
92 | /// </summary> | 120 | /// </summary> |
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs index ba71dc5..7ecbd26 100644 --- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs +++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs | |||
@@ -154,7 +154,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
154 | 154 | ||
155 | #endregion ISharedRegionModule | 155 | #endregion ISharedRegionModule |
156 | 156 | ||
157 | 157 | ||
158 | #region Event Handlers | 158 | #region Event Handlers |
159 | 159 | ||
160 | void EventManager_OnPrimsLoaded(Scene s) | 160 | void EventManager_OnPrimsLoaded(Scene s) |
@@ -180,7 +180,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
180 | void HandleUUIDNameRequest(UUID uuid, IClientAPI client) | 180 | void HandleUUIDNameRequest(UUID uuid, IClientAPI client) |
181 | { | 181 | { |
182 | // m_log.DebugFormat( | 182 | // m_log.DebugFormat( |
183 | // "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}", | 183 | // "[USER MANAGEMENT MODULE]: Handling request for name binding of UUID {0} from {1}", |
184 | // uuid, remote_client.Name); | 184 | // uuid, remote_client.Name); |
185 | 185 | ||
186 | if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) | 186 | if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) |
@@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
212 | // appear to clear this when the user asks it to clear the cache, but others may not. | 212 | // appear to clear this when the user asks it to clear the cache, but others may not. |
213 | // | 213 | // |
214 | // So to avoid clients | 214 | // So to avoid clients |
215 | // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will | 215 | // (particularly Hypergrid clients) permanently binding "Unknown User" to a given UUID, we will |
216 | // instead drop the request entirely. | 216 | // instead drop the request entirely. |
217 | if (GetUser(uuid, out user)) | 217 | if (GetUser(uuid, out user)) |
218 | { | 218 | { |
@@ -220,7 +220,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
220 | } | 220 | } |
221 | // else | 221 | // else |
222 | // m_log.DebugFormat( | 222 | // m_log.DebugFormat( |
223 | // "[USER MANAGEMENT MODULE]: No bound name for {0} found, ignoring request from {1}", | 223 | // "[USER MANAGEMENT MODULE]: No bound name for {0} found, ignoring request from {1}", |
224 | // uuid, client.Name); | 224 | // uuid, client.Name); |
225 | }); | 225 | }); |
226 | } | 226 | } |
@@ -416,7 +416,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
416 | m_log.Debug("[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e); | 416 | m_log.Debug("[USER MANAGEMENT MODULE]: GetServerURLs call failed ", e); |
417 | userdata.ServerURLs = new Dictionary<string, object>(); | 417 | userdata.ServerURLs = new Dictionary<string, object>(); |
418 | } | 418 | } |
419 | 419 | ||
420 | if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) | 420 | if (userdata.ServerURLs != null && userdata.ServerURLs.ContainsKey(serverType) && userdata.ServerURLs[serverType] != null) |
421 | return userdata.ServerURLs[serverType].ToString(); | 421 | return userdata.ServerURLs[serverType].ToString(); |
422 | } | 422 | } |
@@ -620,7 +620,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
620 | AddUser(id, string.Empty, string.Empty, string.Empty); | 620 | AddUser(id, string.Empty, string.Empty, string.Empty); |
621 | } | 621 | } |
622 | else | 622 | else |
623 | { | 623 | { |
624 | string homeURL; | 624 | string homeURL; |
625 | string firstname = string.Empty; | 625 | string firstname = string.Empty; |
626 | string lastname = string.Empty; | 626 | string lastname = string.Empty; |
@@ -676,7 +676,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
676 | else | 676 | else |
677 | { | 677 | { |
678 | lock(m_UserCache) | 678 | lock(m_UserCache) |
679 | { | 679 | { |
680 | if(!m_UserCache.ContainsKey(id)) | 680 | if(!m_UserCache.ContainsKey(id)) |
681 | { | 681 | { |
682 | UserData newUser = new UserData(); | 682 | UserData newUser = new UserData(); |
@@ -726,6 +726,21 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement | |||
726 | "Show the bindings between user UUIDs and user names", | 726 | "Show the bindings between user UUIDs and user names", |
727 | String.Empty, | 727 | String.Empty, |
728 | HandleShowUsers); | 728 | HandleShowUsers); |
729 | |||
730 | MainConsole.Instance.Commands.AddCommand("Users", true, | ||
731 | "reset user cache", | ||
732 | "reset user cache", | ||
733 | "reset user cache to allow changed settings to be applied", | ||
734 | String.Empty, | ||
735 | HandleResetUserCache); | ||
736 | } | ||
737 | |||
738 | private void HandleResetUserCache(string module, string[] cmd) | ||
739 | { | ||
740 | lock(m_UserCache) | ||
741 | { | ||
742 | m_UserCache.Clear(); | ||
743 | } | ||
729 | } | 744 | } |
730 | 745 | ||
731 | private void HandleShowUser(string module, string[] cmd) | 746 | private void HandleShowUser(string module, string[] cmd) |
diff --git a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs index 1b1b319..64532df 100644 --- a/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/CoreModules/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | 35 | ||
36 | [assembly: Addin("OpenSim.Region.CoreModules", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: Addin("OpenSim.Region.CoreModules", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs index e13ee42..6a83b42 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/HGInventoryBroker.cs | |||
@@ -389,6 +389,25 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
389 | return connector.GetFolderContent(userID, folderID); | 389 | return connector.GetFolderContent(userID, folderID); |
390 | } | 390 | } |
391 | 391 | ||
392 | public InventoryCollection[] GetMultipleFoldersContent(UUID userID, UUID[] folderIDs) | ||
393 | { | ||
394 | string invURL = GetInventoryServiceURL(userID); | ||
395 | |||
396 | if (invURL == null) // not there, forward to local inventory connector to resolve | ||
397 | lock (m_Lock) | ||
398 | return m_LocalGridInventoryService.GetMultipleFoldersContent(userID, folderIDs); | ||
399 | |||
400 | else | ||
401 | { | ||
402 | InventoryCollection[] coll = new InventoryCollection[folderIDs.Length]; | ||
403 | int i = 0; | ||
404 | foreach (UUID fid in folderIDs) | ||
405 | coll[i++] = GetFolderContent(userID, fid); | ||
406 | |||
407 | return coll; | ||
408 | } | ||
409 | } | ||
410 | |||
392 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) | 411 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) |
393 | { | 412 | { |
394 | //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID); | 413 | //m_log.Debug("[HG INVENTORY CONNECTOR]: GetFolderItems " + folderID); |
@@ -596,6 +615,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
596 | return connector.GetItem(item); | 615 | return connector.GetItem(item); |
597 | } | 616 | } |
598 | 617 | ||
618 | public InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] itemIDs) | ||
619 | { | ||
620 | if (itemIDs == null) | ||
621 | return new InventoryItemBase[0]; | ||
622 | //m_log.Debug("[HG INVENTORY CONNECTOR]: GetItem " + item.ID); | ||
623 | |||
624 | string invURL = GetInventoryServiceURL(userID); | ||
625 | |||
626 | if (invURL == null) // not there, forward to local inventory connector to resolve | ||
627 | lock (m_Lock) | ||
628 | return m_LocalGridInventoryService.GetMultipleItems(userID, itemIDs); | ||
629 | |||
630 | IInventoryService connector = GetConnector(invURL); | ||
631 | |||
632 | return connector.GetMultipleItems(userID, itemIDs); | ||
633 | } | ||
634 | |||
599 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) | 635 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) |
600 | { | 636 | { |
601 | if (folder == null) | 637 | if (folder == null) |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs index 499ca5e..71dc337 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/InventoryCache.cs | |||
@@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
106 | if (m_Inventories.TryGetValue(userID, out inv)) | 106 | if (m_Inventories.TryGetValue(userID, out inv)) |
107 | { | 107 | { |
108 | c = new InventoryCollection(); | 108 | c = new InventoryCollection(); |
109 | c.UserID = userID; | 109 | c.OwnerID = userID; |
110 | 110 | ||
111 | c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f) | 111 | c.Folders = inv.Folders.FindAll(delegate(InventoryFolderBase f) |
112 | { | 112 | { |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index cbe0e37..2f29a7c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs | |||
@@ -195,6 +195,19 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
195 | return invCol; | 195 | return invCol; |
196 | } | 196 | } |
197 | 197 | ||
198 | public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs) | ||
199 | { | ||
200 | InventoryCollection[] invColl = new InventoryCollection[folderIDs.Length]; | ||
201 | int i = 0; | ||
202 | foreach (UUID fid in folderIDs) | ||
203 | { | ||
204 | invColl[i++] = GetFolderContent(principalID, fid); | ||
205 | } | ||
206 | |||
207 | return invColl; | ||
208 | |||
209 | } | ||
210 | |||
198 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) | 211 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) |
199 | { | 212 | { |
200 | return m_InventoryService.GetFolderItems(userID, folderID); | 213 | return m_InventoryService.GetFolderItems(userID, folderID); |
@@ -294,6 +307,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
294 | return item; | 307 | return item; |
295 | } | 308 | } |
296 | 309 | ||
310 | public InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] itemIDs) | ||
311 | { | ||
312 | return m_InventoryService.GetMultipleItems(userID, itemIDs); | ||
313 | } | ||
314 | |||
297 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) | 315 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) |
298 | { | 316 | { |
299 | return m_InventoryService.GetFolder(folder); | 317 | return m_InventoryService.GetFolder(folder); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index 166e4a1..e0cc1e8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs | |||
@@ -204,6 +204,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
204 | return invCol; | 204 | return invCol; |
205 | } | 205 | } |
206 | 206 | ||
207 | public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs) | ||
208 | { | ||
209 | return m_RemoteConnector.GetMultipleFoldersContent(principalID, folderIDs); | ||
210 | } | ||
211 | |||
207 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) | 212 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) |
208 | { | 213 | { |
209 | return m_RemoteConnector.GetFolderItems(userID, folderID); | 214 | return m_RemoteConnector.GetFolderItems(userID, folderID); |
@@ -298,6 +303,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory | |||
298 | return m_RemoteConnector.GetItem(item); | 303 | return m_RemoteConnector.GetItem(item); |
299 | } | 304 | } |
300 | 305 | ||
306 | public InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] itemIDs) | ||
307 | { | ||
308 | if (itemIDs == null) | ||
309 | return new InventoryItemBase[0]; | ||
310 | |||
311 | return m_RemoteConnector.GetMultipleItems(userID, itemIDs); | ||
312 | } | ||
313 | |||
301 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) | 314 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) |
302 | { | 315 | { |
303 | //m_log.DebugFormat("[XINVENTORY CONNECTOR]: GetFolder {0}", folder.ID); | 316 | //m_log.DebugFormat("[XINVENTORY CONNECTOR]: GetFolder {0}", folder.ID); |
diff --git a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs index 4d99a6e..db66c83 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/AssetsRequest.cs | |||
@@ -335,7 +335,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver | |||
335 | if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home")) | 335 | if (asset.Type == (sbyte)AssetType.Object && asset.Data != null && m_options.ContainsKey("home")) |
336 | { | 336 | { |
337 | //m_log.DebugFormat("[ARCHIVER]: Rewriting object data for {0}", asset.ID); | 337 | //m_log.DebugFormat("[ARCHIVER]: Rewriting object data for {0}", asset.ID); |
338 | string xml = ExternalRepresentationUtils.RewriteSOP(Utils.BytesToString(asset.Data), m_options["home"].ToString(), m_userAccountService, m_scopeID); | 338 | string xml = ExternalRepresentationUtils.RewriteSOP(Utils.BytesToString(asset.Data), string.Empty, m_options["home"].ToString(), m_userAccountService, m_scopeID); |
339 | asset.Data = Utils.StringToBytes(xml); | 339 | asset.Data = Utils.StringToBytes(xml); |
340 | } | 340 | } |
341 | return asset; | 341 | return asset; |
diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 13485bf..25e1454 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -98,11 +98,17 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
98 | // caches ExtendedLandData | 98 | // caches ExtendedLandData |
99 | private Cache parcelInfoCache; | 99 | private Cache parcelInfoCache; |
100 | 100 | ||
101 | |||
101 | /// <summary> | 102 | /// <summary> |
102 | /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. | 103 | /// Record positions that avatar's are currently being forced to move to due to parcel entry restrictions. |
103 | /// </summary> | 104 | /// </summary> |
104 | private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); | 105 | private Dictionary<UUID, Vector3> forcedPosition = new Dictionary<UUID, Vector3>(); |
105 | 106 | ||
107 | // Enables limiting parcel layer info transmission when doing simple updates | ||
108 | private bool shouldLimitParcelLayerInfoToViewDistance { get; set; } | ||
109 | // "View distance" for sending parcel layer info if asked for from a view point in the region | ||
110 | private int parcelLayerViewDistance { get; set; } | ||
111 | |||
106 | #region INonSharedRegionModule Members | 112 | #region INonSharedRegionModule Members |
107 | 113 | ||
108 | public Type ReplaceableInterface | 114 | public Type ReplaceableInterface |
@@ -112,6 +118,14 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
112 | 118 | ||
113 | public void Initialise(IConfigSource source) | 119 | public void Initialise(IConfigSource source) |
114 | { | 120 | { |
121 | shouldLimitParcelLayerInfoToViewDistance = true; | ||
122 | parcelLayerViewDistance = 128; | ||
123 | IConfig landManagementConfig = source.Configs["LandManagement"]; | ||
124 | if (landManagementConfig != null) | ||
125 | { | ||
126 | shouldLimitParcelLayerInfoToViewDistance = landManagementConfig.GetBoolean("LimitParcelLayerUpdateDistance", shouldLimitParcelLayerInfoToViewDistance); | ||
127 | parcelLayerViewDistance = landManagementConfig.GetInt("ParcelLayerViewDistance", parcelLayerViewDistance); | ||
128 | } | ||
115 | } | 129 | } |
116 | 130 | ||
117 | public void AddRegion(Scene scene) | 131 | public void AddRegion(Scene scene) |
@@ -1129,11 +1143,26 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1129 | 1143 | ||
1130 | #region Parcel Updating | 1144 | #region Parcel Updating |
1131 | 1145 | ||
1146 | // Send parcel layer info for the whole region | ||
1147 | public void SendParcelOverlay(IClientAPI remote_client) | ||
1148 | { | ||
1149 | SendParcelOverlay(remote_client, 0, 0, (int)Constants.MaximumRegionSize); | ||
1150 | } | ||
1151 | |||
1132 | /// <summary> | 1152 | /// <summary> |
1133 | /// Where we send the ParcelOverlay packet to the client | 1153 | /// Send the parcel overlay blocks to the client. We send the overlay packets |
1154 | /// around a location and limited by the 'parcelLayerViewDistance'. This number | ||
1155 | /// is usually 128 and the code is arranged so it sends all the parcel overlay | ||
1156 | /// information for a whole region if the region is legacy sized (256x256). If | ||
1157 | /// the region is larger, only the parcel layer information is sent around | ||
1158 | /// the point specified. This reduces the problem of parcel layer information | ||
1159 | /// blocks increasing exponentially as region size increases. | ||
1134 | /// </summary> | 1160 | /// </summary> |
1135 | /// <param name="remote_client">The object representing the client</param> | 1161 | /// <param name="remote_client">The object representing the client</param> |
1136 | public void SendParcelOverlay(IClientAPI remote_client) | 1162 | /// <param name="xPlace">X position in the region to send surrounding parcel layer info</param> |
1163 | /// <param name="yPlace">y position in the region to send surrounding parcel layer info</param> | ||
1164 | /// <param name="layerViewDistance">Distance from x,y position to send parcel layer info</param> | ||
1165 | private void SendParcelOverlay(IClientAPI remote_client, int xPlace, int yPlace, int layerViewDistance) | ||
1137 | { | 1166 | { |
1138 | const int LAND_BLOCKS_PER_PACKET = 1024; | 1167 | const int LAND_BLOCKS_PER_PACKET = 1024; |
1139 | 1168 | ||
@@ -1141,15 +1170,58 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1141 | int byteArrayCount = 0; | 1170 | int byteArrayCount = 0; |
1142 | int sequenceID = 0; | 1171 | int sequenceID = 0; |
1143 | 1172 | ||
1173 | int xLow = 0; | ||
1174 | int xHigh = (int)m_scene.RegionInfo.RegionSizeX; | ||
1175 | int yLow = 0; | ||
1176 | int yHigh = (int)m_scene.RegionInfo.RegionSizeY; | ||
1177 | |||
1178 | if (shouldLimitParcelLayerInfoToViewDistance) | ||
1179 | { | ||
1180 | // Compute view distance around the given point | ||
1181 | int txLow = xPlace - layerViewDistance; | ||
1182 | int txHigh = xPlace + layerViewDistance; | ||
1183 | // If the distance is outside the region area, move the view distance to ba all in the region | ||
1184 | if (txLow < xLow) | ||
1185 | { | ||
1186 | txLow = xLow; | ||
1187 | txHigh = Math.Min(yLow + (layerViewDistance * 2), xHigh); | ||
1188 | } | ||
1189 | if (txHigh > xHigh) | ||
1190 | { | ||
1191 | txLow = Math.Max(xLow, xHigh - (layerViewDistance * 2)); | ||
1192 | txHigh = xHigh; | ||
1193 | } | ||
1194 | xLow = txLow; | ||
1195 | xHigh = txHigh; | ||
1196 | |||
1197 | int tyLow = yPlace - layerViewDistance; | ||
1198 | int tyHigh = yPlace + layerViewDistance; | ||
1199 | if (tyLow < yLow) | ||
1200 | { | ||
1201 | tyLow = yLow; | ||
1202 | tyHigh = Math.Min(yLow + (layerViewDistance * 2), yHigh); | ||
1203 | } | ||
1204 | if (tyHigh > yHigh) | ||
1205 | { | ||
1206 | tyLow = Math.Max(yLow, yHigh - (layerViewDistance * 2)); | ||
1207 | tyHigh = yHigh; | ||
1208 | } | ||
1209 | yLow = tyLow; | ||
1210 | yHigh = tyHigh; | ||
1211 | } | ||
1212 | // m_log.DebugFormat("{0} SendParcelOverlay: place=<{1},{2}>, vDist={3}, xLH=<{4},{5}, yLH=<{6},{7}>", | ||
1213 | // LogHeader, xPlace, yPlace, layerViewDistance, xLow, xHigh, yLow, yHigh); | ||
1214 | |||
1144 | // Layer data is in landUnit (4m) chunks | 1215 | // Layer data is in landUnit (4m) chunks |
1145 | for (int y = 0; y < m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) | 1216 | for (int y = yLow; y < yHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); y++) |
1146 | { | 1217 | { |
1147 | for (int x = 0; x < m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) | 1218 | for (int x = xLow; x < xHigh / Constants.TerrainPatchSize * (Constants.TerrainPatchSize / LandUnit); x++) |
1148 | { | 1219 | { |
1149 | byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * LandUnit, y * LandUnit), x, y, remote_client); | 1220 | byteArray[byteArrayCount] = BuildLayerByte(GetLandObject(x * LandUnit, y * LandUnit), x, y, remote_client); |
1150 | byteArrayCount++; | 1221 | byteArrayCount++; |
1151 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) | 1222 | if (byteArrayCount >= LAND_BLOCKS_PER_PACKET) |
1152 | { | 1223 | { |
1224 | // m_log.DebugFormat("{0} SendParcelOverlay, sending packet, bytes={1}", LogHeader, byteArray.Length); | ||
1153 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); | 1225 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); |
1154 | byteArrayCount = 0; | 1226 | byteArrayCount = 0; |
1155 | sequenceID++; | 1227 | sequenceID++; |
@@ -1162,6 +1234,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1162 | if (byteArrayCount != 0) | 1234 | if (byteArrayCount != 0) |
1163 | { | 1235 | { |
1164 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); | 1236 | remote_client.SendLandParcelOverlay(byteArray, sequenceID); |
1237 | // m_log.DebugFormat("{0} SendParcelOverlay, complete sending packet, bytes={1}", LogHeader, byteArray.Length); | ||
1165 | } | 1238 | } |
1166 | } | 1239 | } |
1167 | 1240 | ||
@@ -1265,7 +1338,8 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1265 | temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client); | 1338 | temp[i].SendLandProperties(sequence_id, snap_selection, requestResult, remote_client); |
1266 | } | 1339 | } |
1267 | 1340 | ||
1268 | SendParcelOverlay(remote_client); | 1341 | // Also send the layer data around the point of interest |
1342 | SendParcelOverlay(remote_client, (start_x + end_x) / 2, (start_y + end_y) / 2, parcelLayerViewDistance); | ||
1269 | } | 1343 | } |
1270 | 1344 | ||
1271 | public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) | 1345 | public void ClientOnParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Features/RectangleFeature.cs b/OpenSim/Region/CoreModules/World/Terrain/Features/RectangleFeature.cs deleted file mode 100644 index 33c3fbe..0000000 --- a/OpenSim/Region/CoreModules/World/Terrain/Features/RectangleFeature.cs +++ /dev/null | |||
@@ -1,149 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using OpenSim.Region.CoreModules.World.Terrain; | ||
30 | using OpenSim.Region.Framework.Interfaces; | ||
31 | |||
32 | namespace OpenSim.Region.CoreModules.World.Terrain.Features | ||
33 | { | ||
34 | public class RectangleFeature : TerrainFeature | ||
35 | { | ||
36 | public RectangleFeature(ITerrainModule module) : base(module) | ||
37 | { | ||
38 | } | ||
39 | |||
40 | public override string CreateFeature(ITerrainChannel map, string[] args) | ||
41 | { | ||
42 | string val; | ||
43 | string result; | ||
44 | if (args.Length < 7) | ||
45 | { | ||
46 | result = "Usage: " + GetUsage(); | ||
47 | } | ||
48 | else | ||
49 | { | ||
50 | result = String.Empty; | ||
51 | |||
52 | float targetElevation; | ||
53 | val = base.parseFloat(args[3], out targetElevation); | ||
54 | if (val != String.Empty) | ||
55 | { | ||
56 | result = val; | ||
57 | } | ||
58 | |||
59 | int xOrigin; | ||
60 | val = base.parseInt(args[4], out xOrigin); | ||
61 | if (val != String.Empty) | ||
62 | { | ||
63 | result = val; | ||
64 | } | ||
65 | else if (xOrigin < 0 || xOrigin >= map.Width) | ||
66 | { | ||
67 | result = "x-origin must be within the region"; | ||
68 | } | ||
69 | |||
70 | int yOrigin; | ||
71 | val = base.parseInt(args[5], out yOrigin); | ||
72 | if (val != String.Empty) | ||
73 | { | ||
74 | result = val; | ||
75 | } | ||
76 | else if (yOrigin < 0 || yOrigin >= map.Height) | ||
77 | { | ||
78 | result = "y-origin must be within the region"; | ||
79 | } | ||
80 | |||
81 | int xDelta; | ||
82 | val = base.parseInt(args[6], out xDelta); | ||
83 | if (val != String.Empty) | ||
84 | { | ||
85 | result = val; | ||
86 | } | ||
87 | else if (xDelta <= 0) | ||
88 | { | ||
89 | result = "x-size must be greater than zero"; | ||
90 | } | ||
91 | |||
92 | int yDelta; | ||
93 | if (args.Length > 7) | ||
94 | { | ||
95 | val = base.parseInt(args[7], out yDelta); | ||
96 | if (val != String.Empty) | ||
97 | { | ||
98 | result = val; | ||
99 | } | ||
100 | else if (yDelta <= 0) | ||
101 | { | ||
102 | result = "y-size must be greater than zero"; | ||
103 | } | ||
104 | } | ||
105 | else | ||
106 | { | ||
107 | // no y-size.. make it square | ||
108 | yDelta = xDelta; | ||
109 | } | ||
110 | |||
111 | // slightly more complex validation, if required. | ||
112 | if (result == String.Empty) | ||
113 | { | ||
114 | if (xOrigin + xDelta > map.Width) | ||
115 | { | ||
116 | result = "(x-origin + x-size) must be within the region size"; | ||
117 | } | ||
118 | else if (yOrigin + yDelta > map.Height) | ||
119 | { | ||
120 | result = "(y-origin + y-size) must be within the region size"; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | // if it's all good, then do the work | ||
125 | if (result == String.Empty) | ||
126 | { | ||
127 | int yPos = yOrigin + yDelta; | ||
128 | while(--yPos >= yOrigin) | ||
129 | { | ||
130 | int xPos = xOrigin + xDelta; | ||
131 | while(--xPos >= xOrigin) | ||
132 | { | ||
133 | map[xPos, yPos] = (double)targetElevation; | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | |||
139 | return result; | ||
140 | } | ||
141 | |||
142 | public override string GetUsage() | ||
143 | { | ||
144 | return "rectangle <height> <x-origin> <y-origin> <x-size> [<y-size>]"; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | } | ||
149 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainFeature.cs b/OpenSim/Region/CoreModules/World/Terrain/ITerrainModifier.cs index 701a729..0e0a0e4 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainFeature.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/ITerrainModifier.cs | |||
@@ -24,65 +24,53 @@ | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | ||
28 | using System.Reflection; | ||
29 | 27 | ||
28 | using System; | ||
30 | using OpenSim.Region.Framework.Interfaces; | 29 | using OpenSim.Region.Framework.Interfaces; |
31 | 30 | ||
32 | namespace OpenSim.Region.CoreModules.World.Terrain | 31 | namespace OpenSim.Region.CoreModules.World.Terrain |
33 | { | 32 | { |
34 | public abstract class TerrainFeature : ITerrainFeature | 33 | public interface ITerrainModifier |
35 | { | 34 | { |
36 | protected ITerrainModule m_module; | 35 | /// <summary> |
37 | 36 | /// Creates the feature. | |
38 | protected TerrainFeature(ITerrainModule module) | 37 | /// </summary> |
39 | { | 38 | /// <returns> |
40 | m_module = module; | 39 | /// Empty string if successful, otherwise error message. |
41 | } | 40 | /// </returns> |
42 | 41 | /// <param name='map'> | |
43 | public abstract string CreateFeature(ITerrainChannel map, string[] args); | 42 | /// ITerrainChannel holding terrain data. |
44 | 43 | /// </param> | |
45 | public abstract string GetUsage(); | 44 | /// <param name='args'> |
46 | 45 | /// command-line arguments from console. | |
47 | protected string parseFloat(String s, out float f) | 46 | /// </param> |
48 | { | 47 | string ModifyTerrain(ITerrainChannel map, string[] args); |
49 | string result; | ||
50 | double d; | ||
51 | if (Double.TryParse(s, out d)) | ||
52 | { | ||
53 | try | ||
54 | { | ||
55 | f = (float)d; | ||
56 | result = String.Empty; | ||
57 | } | ||
58 | catch(InvalidCastException) | ||
59 | { | ||
60 | result = String.Format("{0} is invalid", s); | ||
61 | f = -1.0f; | ||
62 | } | ||
63 | } | ||
64 | else | ||
65 | { | ||
66 | f = -1.0f; | ||
67 | result = String.Format("{0} is invalid", s); | ||
68 | } | ||
69 | return result; | ||
70 | } | ||
71 | 48 | ||
72 | protected string parseInt(String s, out int i) | 49 | /// <summary> |
73 | { | 50 | /// Gets a string describing the usage. |
74 | string result; | 51 | /// </summary> |
75 | if (Int32.TryParse(s, out i)) | 52 | /// <returns> |
76 | { | 53 | /// A string describing parameters for creating the feature. |
77 | result = String.Empty; | 54 | /// Format is "feature-name <arg1> <arg2> ..." |
78 | } | 55 | /// </returns> |
79 | else | 56 | string GetUsage(); |
80 | { | ||
81 | result = String.Format("{0} is invalid", s); | ||
82 | } | ||
83 | return result; | ||
84 | } | ||
85 | 57 | ||
58 | /// <summary> | ||
59 | /// Apply the appropriate operation on the specified map, at (x, y). | ||
60 | /// </summary> | ||
61 | /// <param name='map'> | ||
62 | /// Map. | ||
63 | /// </param> | ||
64 | /// <param name='data'> | ||
65 | /// Data. | ||
66 | /// </param> | ||
67 | /// <param name='x'> | ||
68 | /// X. | ||
69 | /// </param> | ||
70 | /// <param name='y'> | ||
71 | /// Y. | ||
72 | /// </param> | ||
73 | double operate(double[,] map, TerrainModifierData data, int x, int y); | ||
86 | } | 74 | } |
87 | 75 | ||
88 | } | 76 | } |
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Modifiers/FillModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/FillModifier.cs new file mode 100644 index 0000000..32f1de9 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/FillModifier.cs | |||
@@ -0,0 +1,93 @@ | |||
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 | using System; | ||
28 | |||
29 | using OpenSim.Region.CoreModules.World.Terrain; | ||
30 | using OpenSim.Region.Framework.Interfaces; | ||
31 | |||
32 | namespace OpenSim.Region.CoreModules.World.Terrain.Modifiers | ||
33 | { | ||
34 | public class FillModifier : TerrainModifier | ||
35 | { | ||
36 | |||
37 | public FillModifier(ITerrainModule module) : base(module) | ||
38 | { | ||
39 | } | ||
40 | |||
41 | public override string ModifyTerrain(ITerrainChannel map, string[] args) | ||
42 | { | ||
43 | string result; | ||
44 | if (args.Length < 3) | ||
45 | { | ||
46 | result = "Usage: " + GetUsage(); | ||
47 | } | ||
48 | else | ||
49 | { | ||
50 | TerrainModifierData data; | ||
51 | result = this.parseParameters(args, out data); | ||
52 | |||
53 | // Context-specific validation | ||
54 | if (result == String.Empty) | ||
55 | { | ||
56 | if (data.shape == String.Empty) | ||
57 | { | ||
58 | data.shape = "rectangle"; | ||
59 | data.x0 = 0; | ||
60 | data.y0 = 0; | ||
61 | data.dx = map.Width; | ||
62 | data.dy = map.Height; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | // if it's all good, then do the work | ||
67 | if (result == String.Empty) | ||
68 | { | ||
69 | this.applyModification(map, data); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | return result; | ||
74 | } | ||
75 | |||
76 | public override string GetUsage() | ||
77 | { | ||
78 | string val = "fill <height> [ -rec=x1,y1,dx[,dy] | -ell=x0,y0,rx[,ry] ] [-taper=<height2>]" | ||
79 | + "\nSets all points within the specified range to the specified value."; | ||
80 | return val; | ||
81 | } | ||
82 | |||
83 | public override double operate(double[,] map, TerrainModifierData data, int x, int y) | ||
84 | { | ||
85 | double factor = this.computeBevel(data, x, y); | ||
86 | double result = data.elevation - (data.elevation - data.bevelevation) * factor; | ||
87 | return result; | ||
88 | } | ||
89 | |||
90 | } | ||
91 | |||
92 | } | ||
93 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Modifiers/LowerModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/LowerModifier.cs new file mode 100644 index 0000000..2ab4bcc --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/LowerModifier.cs | |||
@@ -0,0 +1,92 @@ | |||
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 | using System; | ||
28 | using OpenSim.Region.CoreModules.World.Terrain; | ||
29 | using OpenSim.Region.Framework.Interfaces; | ||
30 | |||
31 | namespace OpenSim.Region.CoreModules.World.Terrain.Modifiers | ||
32 | { | ||
33 | public class LowerModifier : TerrainModifier | ||
34 | { | ||
35 | public LowerModifier(ITerrainModule module) : base(module) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | public override string ModifyTerrain(ITerrainChannel map, string[] args) | ||
40 | { | ||
41 | string result; | ||
42 | if (args.Length < 3) | ||
43 | { | ||
44 | result = "Usage: " + GetUsage(); | ||
45 | } | ||
46 | else | ||
47 | { | ||
48 | TerrainModifierData data; | ||
49 | result = this.parseParameters(args, out data); | ||
50 | |||
51 | // Context-specific validation | ||
52 | if (result == String.Empty) | ||
53 | { | ||
54 | if (data.shape == String.Empty) | ||
55 | { | ||
56 | data.shape = "rectangle"; | ||
57 | data.x0 = 0; | ||
58 | data.y0 = 0; | ||
59 | data.dx = map.Width; | ||
60 | data.dy = map.Height; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | // if it's all good, then do the work | ||
65 | if (result == String.Empty) | ||
66 | { | ||
67 | this.applyModification(map, data); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | return result; | ||
72 | } | ||
73 | |||
74 | public override string GetUsage() | ||
75 | { | ||
76 | string val = "lower <delta> [ -rec=x1,y1,dx[,dy] | -ell=x0,y0,rx[,ry] ] [-taper=<delta2>]" | ||
77 | + "\nLowers all points within the specified range by the specified amount."; | ||
78 | return val; | ||
79 | |||
80 | } | ||
81 | |||
82 | public override double operate(double[,] map, TerrainModifierData data, int x, int y) | ||
83 | { | ||
84 | double factor = this.computeBevel(data, x, y); | ||
85 | double result = map[x, y] - (data.elevation - (data.elevation - data.bevelevation) * factor); | ||
86 | return result; | ||
87 | } | ||
88 | |||
89 | } | ||
90 | |||
91 | } | ||
92 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Modifiers/MaxModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/MaxModifier.cs new file mode 100644 index 0000000..0939c0a --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/MaxModifier.cs | |||
@@ -0,0 +1,92 @@ | |||
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 | using System; | ||
28 | using OpenSim.Region.CoreModules.World.Terrain; | ||
29 | using OpenSim.Region.Framework.Interfaces; | ||
30 | |||
31 | namespace OpenSim.Region.CoreModules.World.Terrain.Modifiers | ||
32 | { | ||
33 | public class MaxModifier : TerrainModifier | ||
34 | { | ||
35 | public MaxModifier(ITerrainModule module) : base(module) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | public override string ModifyTerrain(ITerrainChannel map, string[] args) | ||
40 | { | ||
41 | string result; | ||
42 | if (args.Length < 3) | ||
43 | { | ||
44 | result = "Usage: " + GetUsage(); | ||
45 | } | ||
46 | else | ||
47 | { | ||
48 | TerrainModifierData data; | ||
49 | result = this.parseParameters(args, out data); | ||
50 | |||
51 | // Context-specific validation | ||
52 | if (result == String.Empty) | ||
53 | { | ||
54 | if (data.shape == String.Empty) | ||
55 | { | ||
56 | data.shape = "rectangle"; | ||
57 | data.x0 = 0; | ||
58 | data.y0 = 0; | ||
59 | data.dx = map.Width; | ||
60 | data.dy = map.Height; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | // if it's all good, then do the work | ||
65 | if (result == String.Empty) | ||
66 | { | ||
67 | this.applyModification(map, data); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | return result; | ||
72 | } | ||
73 | |||
74 | public override string GetUsage() | ||
75 | { | ||
76 | string val = "max <height> [ -rec=x1,y1,dx[,dy] | -ell=x0,y0,rx[,ry] ] [-taper=<height2>]" | ||
77 | + "\nEnsures that all points within the specified range are no higher than the specified value."; | ||
78 | return val; | ||
79 | |||
80 | } | ||
81 | |||
82 | public override double operate(double[,] map, TerrainModifierData data, int x, int y) | ||
83 | { | ||
84 | double factor = this.computeBevel(data, x, y); | ||
85 | double result = Math.Min(data.elevation - (data.elevation - data.bevelevation) * factor, map[x, y]); | ||
86 | return result; | ||
87 | } | ||
88 | |||
89 | } | ||
90 | |||
91 | } | ||
92 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Modifiers/MinModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/MinModifier.cs new file mode 100644 index 0000000..cbbccc0 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/MinModifier.cs | |||
@@ -0,0 +1,92 @@ | |||
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 | using System; | ||
28 | using OpenSim.Region.CoreModules.World.Terrain; | ||
29 | using OpenSim.Region.Framework.Interfaces; | ||
30 | |||
31 | namespace OpenSim.Region.CoreModules.World.Terrain.Modifiers | ||
32 | { | ||
33 | public class MinModifier : TerrainModifier | ||
34 | { | ||
35 | public MinModifier(ITerrainModule module) : base(module) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | public override string ModifyTerrain(ITerrainChannel map, string[] args) | ||
40 | { | ||
41 | string result; | ||
42 | if (args.Length < 3) | ||
43 | { | ||
44 | result = "Usage: " + GetUsage(); | ||
45 | } | ||
46 | else | ||
47 | { | ||
48 | TerrainModifierData data; | ||
49 | result = this.parseParameters(args, out data); | ||
50 | |||
51 | // Context-specific validation | ||
52 | if (result == String.Empty) | ||
53 | { | ||
54 | if (data.shape == String.Empty) | ||
55 | { | ||
56 | data.shape = "rectangle"; | ||
57 | data.x0 = 0; | ||
58 | data.y0 = 0; | ||
59 | data.dx = map.Width; | ||
60 | data.dy = map.Height; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | // if it's all good, then do the work | ||
65 | if (result == String.Empty) | ||
66 | { | ||
67 | this.applyModification(map, data); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | return result; | ||
72 | } | ||
73 | |||
74 | public override string GetUsage() | ||
75 | { | ||
76 | string val = "min <height> [ -rec=x1,y1,dx[,dy] | -ell=x0,y0,rx[,ry] ] [-taper=<height2>]" | ||
77 | + "\nEnsures that all points within the specified range are no lower than the specified value."; | ||
78 | return val; | ||
79 | |||
80 | } | ||
81 | |||
82 | public override double operate(double[,] map, TerrainModifierData data, int x, int y) | ||
83 | { | ||
84 | double factor = this.computeBevel(data, x, y); | ||
85 | double result = Math.Max(data.elevation - (data.elevation - data.bevelevation) * factor, map[x, y]); | ||
86 | return result; | ||
87 | } | ||
88 | |||
89 | } | ||
90 | |||
91 | } | ||
92 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Modifiers/NoiseModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/NoiseModifier.cs new file mode 100644 index 0000000..d6b95d0 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/NoiseModifier.cs | |||
@@ -0,0 +1,108 @@ | |||
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 | using System; | ||
28 | using OpenSim.Region.CoreModules.World.Terrain; | ||
29 | using OpenSim.Region.Framework.Interfaces; | ||
30 | using OpenSim.Region.Framework.Scenes; | ||
31 | |||
32 | namespace OpenSim.Region.CoreModules.World.Terrain.Modifiers | ||
33 | { | ||
34 | public class NoiseModifier : TerrainModifier | ||
35 | { | ||
36 | public NoiseModifier(ITerrainModule module) : base(module) | ||
37 | { | ||
38 | } | ||
39 | |||
40 | public override string ModifyTerrain(ITerrainChannel map, string[] args) | ||
41 | { | ||
42 | string result; | ||
43 | if (args.Length < 3) | ||
44 | { | ||
45 | result = "Usage: " + GetUsage(); | ||
46 | } | ||
47 | else | ||
48 | { | ||
49 | TerrainModifierData data; | ||
50 | result = this.parseParameters(args, out data); | ||
51 | |||
52 | // Context-specific validation | ||
53 | if (result == String.Empty) | ||
54 | { | ||
55 | if (data.bevel == "taper") | ||
56 | { | ||
57 | if (data.bevelevation < 0.0 || data.bevelevation > 1.0) | ||
58 | { | ||
59 | result = String.Format("Taper must be 0.0 to 1.0: {0}", data.bevelevation); | ||
60 | } | ||
61 | } | ||
62 | else | ||
63 | { | ||
64 | data.bevelevation = 1.0f; | ||
65 | } | ||
66 | |||
67 | if (data.elevation < 0.0 || data.elevation > 1.0) | ||
68 | { | ||
69 | result = String.Format("Noise strength must be 0.0 to 1.0: {0}", data.elevation); | ||
70 | } | ||
71 | |||
72 | if (data.shape == String.Empty) | ||
73 | { | ||
74 | data.shape = "rectangle"; | ||
75 | data.x0 = 0; | ||
76 | data.y0 = 0; | ||
77 | data.dx = map.Width; | ||
78 | data.dy = map.Height; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | // if it's all good, then do the work | ||
83 | if (result == String.Empty) | ||
84 | { | ||
85 | this.applyModification(map, data); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | return result; | ||
90 | } | ||
91 | |||
92 | public override string GetUsage() | ||
93 | { | ||
94 | string val = "noise <delta> [ -rec=x1,y1,dx[,dy] | -ell=x0,y0,rx[,ry] ] [-taper=<delta2>]" | ||
95 | + "\nAdds noise to all points within the specified range."; | ||
96 | return val; | ||
97 | } | ||
98 | |||
99 | public override double operate(double[,] map, TerrainModifierData data, int x, int y) | ||
100 | { | ||
101 | double factor = this.computeBevel(data, x, y); | ||
102 | double noise = TerrainUtil.PerlinNoise2D((double)x / map.GetLength(0), (double)y / map.GetLength(1), 8, 1.0); | ||
103 | return map[x, y] + (data.elevation - (data.elevation - data.bevelevation) * factor) * (noise - .5); | ||
104 | } | ||
105 | |||
106 | } | ||
107 | |||
108 | } | ||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Modifiers/RaiseModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/RaiseModifier.cs new file mode 100644 index 0000000..35fb9d6 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/RaiseModifier.cs | |||
@@ -0,0 +1,92 @@ | |||
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 | using System; | ||
28 | using OpenSim.Region.CoreModules.World.Terrain; | ||
29 | using OpenSim.Region.Framework.Interfaces; | ||
30 | |||
31 | namespace OpenSim.Region.CoreModules.World.Terrain.Modifiers | ||
32 | { | ||
33 | public class RaiseModifier : TerrainModifier | ||
34 | { | ||
35 | public RaiseModifier(ITerrainModule module) : base(module) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | public override string ModifyTerrain(ITerrainChannel map, string[] args) | ||
40 | { | ||
41 | string result; | ||
42 | if (args.Length < 3) | ||
43 | { | ||
44 | result = "Usage: " + GetUsage(); | ||
45 | } | ||
46 | else | ||
47 | { | ||
48 | TerrainModifierData data; | ||
49 | result = this.parseParameters(args, out data); | ||
50 | |||
51 | // Context-specific validation | ||
52 | if (result == String.Empty) | ||
53 | { | ||
54 | if (data.shape == String.Empty) | ||
55 | { | ||
56 | data.shape = "rectangle"; | ||
57 | data.x0 = 0; | ||
58 | data.y0 = 0; | ||
59 | data.dx = map.Width; | ||
60 | data.dy = map.Height; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | // if it's all good, then do the work | ||
65 | if (result == String.Empty) | ||
66 | { | ||
67 | this.applyModification(map, data); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | return result; | ||
72 | } | ||
73 | |||
74 | public override string GetUsage() | ||
75 | { | ||
76 | string val = "raise <delta> [ -rec=x1,y1,dx[,dy] | -ell=x0,y0,rx[,ry] ] [-taper=<delta2>]" | ||
77 | + "\nRaises all points within the specified range by the specified amount."; | ||
78 | return val; | ||
79 | |||
80 | } | ||
81 | |||
82 | public override double operate(double[,] map, TerrainModifierData data, int x, int y) | ||
83 | { | ||
84 | double factor = this.computeBevel(data, x, y); | ||
85 | double result = map[x, y] + (data.elevation - (data.elevation - data.bevelevation) * factor); | ||
86 | return result; | ||
87 | } | ||
88 | |||
89 | } | ||
90 | |||
91 | } | ||
92 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/Modifiers/SmoothModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/SmoothModifier.cs new file mode 100644 index 0000000..9f8d5b2 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/Modifiers/SmoothModifier.cs | |||
@@ -0,0 +1,131 @@ | |||
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 | using System; | ||
28 | using OpenSim.Region.CoreModules.World.Terrain; | ||
29 | using OpenSim.Region.Framework.Interfaces; | ||
30 | |||
31 | namespace OpenSim.Region.CoreModules.World.Terrain.Modifiers | ||
32 | { | ||
33 | public class SmoothModifier : TerrainModifier | ||
34 | { | ||
35 | public SmoothModifier(ITerrainModule module) : base(module) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | public override string ModifyTerrain(ITerrainChannel map, string[] args) | ||
40 | { | ||
41 | string result; | ||
42 | if (args.Length < 3) | ||
43 | { | ||
44 | result = "Usage: " + GetUsage(); | ||
45 | } | ||
46 | else | ||
47 | { | ||
48 | TerrainModifierData data; | ||
49 | result = this.parseParameters(args, out data); | ||
50 | |||
51 | // Context-specific validation | ||
52 | if (result == String.Empty) | ||
53 | { | ||
54 | if (data.bevel == "taper") | ||
55 | { | ||
56 | if (data.bevelevation < 0.01 || data.bevelevation > 0.99) | ||
57 | { | ||
58 | result = String.Format("Taper must be 0.01 to 0.99: {0}", data.bevelevation); | ||
59 | } | ||
60 | } | ||
61 | else | ||
62 | { | ||
63 | data.bevelevation = 2.0f / 3.0f; | ||
64 | } | ||
65 | |||
66 | if (data.elevation < 0.0 || data.elevation > 1.0) | ||
67 | { | ||
68 | result = String.Format("Smoothing strength must be 0.0 to 1.0: {0}", data.elevation); | ||
69 | } | ||
70 | |||
71 | if (data.shape == String.Empty) | ||
72 | { | ||
73 | data.shape = "rectangle"; | ||
74 | data.x0 = 0; | ||
75 | data.y0 = 0; | ||
76 | data.dx = map.Width; | ||
77 | data.dy = map.Height; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | // if it's all good, then do the work | ||
82 | if (result == String.Empty) | ||
83 | { | ||
84 | this.applyModification(map, data); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | return result; | ||
89 | } | ||
90 | |||
91 | public override string GetUsage() | ||
92 | { | ||
93 | string val = "smooth <strength> [ -rec=x1,y1,dx[,dy] | -ell=x0,y0,rx[,ry] ] [-taper=<fraction>]" | ||
94 | + "\nSmooths all points within the specified range using a simple averaging algorithm."; | ||
95 | return val; | ||
96 | } | ||
97 | |||
98 | public override double operate(double[,] map, TerrainModifierData data, int x, int y) | ||
99 | { | ||
100 | double[] scale = new double[3]; | ||
101 | scale[0] = data.elevation; | ||
102 | scale[1] = ((1.0 - scale[0]) * data.bevelevation) / 8.0; | ||
103 | scale[2] = ((1.0 - scale[0]) * (1.0 - data.bevelevation)) / 16.0; | ||
104 | int xMax = map.GetLength(0); | ||
105 | int yMax = map.GetLength(1); | ||
106 | double result; | ||
107 | if ((x == 0) || (y == 0) || (x == (xMax - 1)) || (y == (yMax - 1))) | ||
108 | { | ||
109 | result = map[x, y]; | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | result = 0.0; | ||
114 | for(int yPos = (y - 2); yPos < (y + 3); yPos++) | ||
115 | { | ||
116 | int yVal = (yPos <= 0) ? 0 : ((yPos < yMax) ? yPos : yMax - 1); | ||
117 | for(int xPos = (x - 2); xPos < (x + 3); xPos++) | ||
118 | { | ||
119 | int xVal = (xPos <= 0) ? 0 : ((xPos < xMax) ? xPos : xMax - 1); | ||
120 | int dist = Math.Max(Math.Abs(x - xVal), Math.Abs(y - yVal)); | ||
121 | result += map[xVal, yVal] * scale[dist]; | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | return result; | ||
126 | } | ||
127 | |||
128 | } | ||
129 | |||
130 | } | ||
131 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModifier.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModifier.cs new file mode 100644 index 0000000..7ebd08e --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModifier.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 | using System; | ||
28 | using System.Reflection; | ||
29 | using log4net; | ||
30 | |||
31 | using OpenSim.Region.Framework.Interfaces; | ||
32 | |||
33 | namespace OpenSim.Region.CoreModules.World.Terrain | ||
34 | { | ||
35 | public abstract class TerrainModifier : ITerrainModifier | ||
36 | { | ||
37 | protected ITerrainModule m_module; | ||
38 | protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
39 | |||
40 | protected TerrainModifier(ITerrainModule module) | ||
41 | { | ||
42 | m_module = module; | ||
43 | } | ||
44 | |||
45 | public abstract string ModifyTerrain(ITerrainChannel map, string[] args); | ||
46 | |||
47 | public abstract string GetUsage(); | ||
48 | |||
49 | public abstract double operate(double[,] map, TerrainModifierData data, int x, int y); | ||
50 | |||
51 | protected String parseParameters(string[] args, out TerrainModifierData data) | ||
52 | { | ||
53 | string val; | ||
54 | string arg; | ||
55 | string result; | ||
56 | data = new TerrainModifierData(); | ||
57 | data.shape = String.Empty; | ||
58 | data.bevel = String.Empty; | ||
59 | data.dx = 0; | ||
60 | data.dy = 0; | ||
61 | if (args.Length < 4) | ||
62 | { | ||
63 | result = "Usage: " + GetUsage(); | ||
64 | } | ||
65 | else | ||
66 | { | ||
67 | result = this.parseFloat(args[3], out data.elevation); | ||
68 | } | ||
69 | if (result == String.Empty) | ||
70 | { | ||
71 | int index = 3; | ||
72 | while(++index < args.Length && result == String.Empty) | ||
73 | { | ||
74 | arg = args[index]; | ||
75 | // check for shape | ||
76 | if (arg.StartsWith("-rec=") || arg.StartsWith("-ell=")) | ||
77 | { | ||
78 | if (data.shape != String.Empty) | ||
79 | { | ||
80 | result = "Only 1 '-rec' or '-ell' parameter is permitted."; | ||
81 | } | ||
82 | else | ||
83 | { | ||
84 | data.shape = arg.StartsWith("-ell=") ? "ellipse" : "rectangle"; | ||
85 | val = arg.Substring(arg.IndexOf("=") + 1); | ||
86 | string[] coords = val.Split(new char[] {','}); | ||
87 | if ((coords.Length < 3) || (coords.Length > 4)) | ||
88 | { | ||
89 | result = String.Format("Bad format for shape parameter {0}", arg); | ||
90 | } | ||
91 | else | ||
92 | { | ||
93 | result = this.parseInt(coords[0], out data.x0); | ||
94 | if (result == String.Empty) | ||
95 | { | ||
96 | result = this.parseInt(coords[1], out data.y0); | ||
97 | } | ||
98 | if (result == String.Empty) | ||
99 | { | ||
100 | result = this.parseInt(coords[2], out data.dx); | ||
101 | } | ||
102 | if (result == String.Empty) | ||
103 | { | ||
104 | if (coords.Length == 4) | ||
105 | { | ||
106 | result = this.parseInt(coords[3], out data.dy); | ||
107 | } | ||
108 | else | ||
109 | { | ||
110 | data.dy = data.dx; | ||
111 | } | ||
112 | } | ||
113 | if (result == String.Empty) | ||
114 | { | ||
115 | if ((data.dx <= 0) || (data.dy <= 0)) | ||
116 | { | ||
117 | result = "Shape sizes must be positive integers"; | ||
118 | } | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | result = String.Format("Bad value in shape parameters {0}", arg); | ||
123 | } | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | else if (arg.StartsWith("-taper=")) | ||
128 | { | ||
129 | if (data.bevel != String.Empty) | ||
130 | { | ||
131 | result = "Only 1 '-taper' parameter is permitted."; | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | data.bevel = "taper"; | ||
136 | val = arg.Substring(arg.IndexOf("=") + 1); | ||
137 | result = this.parseFloat(val, out data.bevelevation); | ||
138 | if (result != String.Empty) | ||
139 | { | ||
140 | result = String.Format("Bad format for taper parameter {0}", arg); | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | else | ||
145 | { | ||
146 | result = String.Format("Unrecognized parameter {0}", arg); | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | return result; | ||
151 | } | ||
152 | |||
153 | protected string parseFloat(String s, out float f) | ||
154 | { | ||
155 | string result; | ||
156 | double d; | ||
157 | if (Double.TryParse(s, out d)) | ||
158 | { | ||
159 | try | ||
160 | { | ||
161 | f = (float)d; | ||
162 | result = String.Empty; | ||
163 | } | ||
164 | catch(InvalidCastException) | ||
165 | { | ||
166 | result = String.Format("{0} is invalid", s); | ||
167 | f = -1.0f; | ||
168 | } | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | f = -1.0f; | ||
173 | result = String.Format("{0} is invalid", s); | ||
174 | } | ||
175 | return result; | ||
176 | } | ||
177 | |||
178 | protected string parseInt(String s, out int i) | ||
179 | { | ||
180 | string result; | ||
181 | if (Int32.TryParse(s, out i)) | ||
182 | { | ||
183 | result = String.Empty; | ||
184 | } | ||
185 | else | ||
186 | { | ||
187 | result = String.Format("{0} is invalid", s); | ||
188 | } | ||
189 | return result; | ||
190 | } | ||
191 | |||
192 | protected void applyModification(ITerrainChannel map, TerrainModifierData data) | ||
193 | { | ||
194 | bool[,] mask; | ||
195 | int xMax; | ||
196 | int yMax; | ||
197 | int xMid; | ||
198 | int yMid; | ||
199 | if (data.shape == "ellipse") | ||
200 | { | ||
201 | mask = this.ellipticalMask(data.dx, data.dy); | ||
202 | xMax = mask.GetLength(0); | ||
203 | yMax = mask.GetLength(1); | ||
204 | xMid = xMax / 2 + xMax % 2; | ||
205 | yMid = yMax / 2 + yMax % 2; | ||
206 | } | ||
207 | else | ||
208 | { | ||
209 | mask = this.rectangularMask(data.dx, data.dy); | ||
210 | xMax = mask.GetLength(0); | ||
211 | yMax = mask.GetLength(1); | ||
212 | xMid = 0; | ||
213 | yMid = 0; | ||
214 | } | ||
215 | // m_log.DebugFormat("Apply {0} mask {1}x{2} @ {3},{4}", data.shape, xMax, yMax, xMid, yMid); | ||
216 | double[,] buffer = map.GetDoubles(); | ||
217 | int yDim = yMax; | ||
218 | while(--yDim >= 0) | ||
219 | { | ||
220 | int yPos = data.y0 + yDim - yMid; | ||
221 | if ((yPos >= 0) && (yPos < map.Height)) | ||
222 | { | ||
223 | int xDim = xMax; | ||
224 | while(--xDim >= 0) | ||
225 | { | ||
226 | int xPos = data.x0 + xDim - xMid; | ||
227 | if ((xPos >= 0) && (xPos < map.Width) && (mask[xDim, yDim])) | ||
228 | { | ||
229 | double endElevation = this.operate(buffer, data, xPos, yPos); | ||
230 | map[xPos, yPos] = endElevation; | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | |||
237 | protected double computeBevel(TerrainModifierData data, int x, int y) | ||
238 | { | ||
239 | int deltaX; | ||
240 | int deltaY; | ||
241 | int xMax; | ||
242 | int yMax; | ||
243 | double factor; | ||
244 | if (data.bevel == "taper") | ||
245 | { | ||
246 | if (data.shape == "ellipse") | ||
247 | { | ||
248 | deltaX = x - data.x0; | ||
249 | deltaY = y - data.y0; | ||
250 | xMax = data.dx; | ||
251 | yMax = data.dy; | ||
252 | factor = (double)((deltaX * deltaX) + (deltaY * deltaY)); | ||
253 | factor /= ((xMax * xMax) + (yMax * yMax)); | ||
254 | } | ||
255 | else | ||
256 | { | ||
257 | // pyramid | ||
258 | xMax = data.dx / 2 + data.dx % 2; | ||
259 | yMax = data.dy / 2 + data.dy % 2; | ||
260 | deltaX = Math.Abs(data.x0 + xMax - x); | ||
261 | deltaY = Math.Abs(data.y0 + yMax - y); | ||
262 | factor = Math.Max(((double)(deltaY) / yMax), ((double)(deltaX) / xMax)); | ||
263 | } | ||
264 | } | ||
265 | else | ||
266 | { | ||
267 | factor = 0.0; | ||
268 | } | ||
269 | return factor; | ||
270 | } | ||
271 | |||
272 | private bool[,] rectangularMask(int xSize, int ySize) | ||
273 | { | ||
274 | bool[,] mask = new bool[xSize, ySize]; | ||
275 | int yPos = ySize; | ||
276 | while(--yPos >= 0) | ||
277 | { | ||
278 | int xPos = xSize; | ||
279 | while(--xPos >= 0) | ||
280 | { | ||
281 | mask[xPos, yPos] = true; | ||
282 | } | ||
283 | } | ||
284 | return mask; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Fast ellipse-based derivative of Bresenham algorithm. | ||
289 | * https://web.archive.org/web/20120225095359/http://homepage.smc.edu/kennedy_john/belipse.pdf | ||
290 | */ | ||
291 | private bool[,] ellipticalMask(int xRadius, int yRadius) | ||
292 | { | ||
293 | long twoASquared = 2L * xRadius * xRadius; | ||
294 | long twoBSquared = 2L * yRadius * yRadius; | ||
295 | |||
296 | bool[,] mask = new bool[2 * xRadius + 1, 2 * yRadius + 1]; | ||
297 | |||
298 | long ellipseError = 0L; | ||
299 | long stoppingX = twoBSquared * xRadius; | ||
300 | long stoppingY = 0L; | ||
301 | long xChange = yRadius * yRadius * (1L - 2L * xRadius); | ||
302 | long yChange = xRadius * xRadius; | ||
303 | |||
304 | int xPos = xRadius; | ||
305 | int yPos = 0; | ||
306 | |||
307 | // first set of points | ||
308 | while(stoppingX >= stoppingY) | ||
309 | { | ||
310 | int yUpper = yRadius + yPos; | ||
311 | int yLower = yRadius - yPos; | ||
312 | // fill in the mask | ||
313 | int xNow = xPos; | ||
314 | while(xNow >= 0) | ||
315 | { | ||
316 | mask[xRadius + xNow, yUpper] = true; | ||
317 | mask[xRadius - xNow, yUpper] = true; | ||
318 | mask[xRadius + xNow, yLower] = true; | ||
319 | mask[xRadius - xNow, yLower] = true; | ||
320 | --xNow; | ||
321 | } | ||
322 | yPos++; | ||
323 | stoppingY += twoASquared; | ||
324 | ellipseError += yChange; | ||
325 | yChange += twoASquared; | ||
326 | if ((2L * ellipseError + xChange) > 0L) | ||
327 | { | ||
328 | xPos--; | ||
329 | stoppingX -= twoBSquared; | ||
330 | ellipseError += xChange; | ||
331 | xChange += twoBSquared; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | // second set of points | ||
336 | xPos = 0; | ||
337 | yPos = yRadius; | ||
338 | xChange = yRadius * yRadius; | ||
339 | yChange = xRadius * xRadius * (1L - 2L * yRadius); | ||
340 | |||
341 | ellipseError = 0L; | ||
342 | stoppingX = 0L; | ||
343 | stoppingY = twoASquared * yRadius; | ||
344 | |||
345 | while(stoppingX <= stoppingY) | ||
346 | { | ||
347 | int xUpper = xRadius + xPos; | ||
348 | int xLower = xRadius - xPos; | ||
349 | // fill in the mask | ||
350 | int yNow = yPos; | ||
351 | while(yNow >= 0) | ||
352 | { | ||
353 | mask[xUpper, yRadius + yNow] = true; | ||
354 | mask[xUpper, yRadius - yNow] = true; | ||
355 | mask[xLower, yRadius + yNow] = true; | ||
356 | mask[xLower, yRadius - yNow] = true; | ||
357 | --yNow; | ||
358 | } | ||
359 | xPos++; | ||
360 | stoppingX += twoBSquared; | ||
361 | ellipseError += xChange; | ||
362 | xChange += twoBSquared; | ||
363 | if ((2L * ellipseError + yChange) > 0L) | ||
364 | { | ||
365 | yPos--; | ||
366 | stoppingY -= twoASquared; | ||
367 | ellipseError += yChange; | ||
368 | yChange += twoASquared; | ||
369 | } | ||
370 | } | ||
371 | return mask; | ||
372 | } | ||
373 | |||
374 | |||
375 | } | ||
376 | |||
377 | } | ||
378 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModifierData.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModifierData.cs new file mode 100644 index 0000000..4e0f8d7 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModifierData.cs | |||
@@ -0,0 +1,17 @@ | |||
1 | using System; | ||
2 | |||
3 | namespace OpenSim.Region.CoreModules.World.Terrain | ||
4 | { | ||
5 | public struct TerrainModifierData | ||
6 | { | ||
7 | public float elevation; | ||
8 | public string shape; | ||
9 | public int x0; | ||
10 | public int y0; | ||
11 | public int dx; | ||
12 | public int dy; | ||
13 | public string bevel; | ||
14 | public float bevelevation; | ||
15 | } | ||
16 | } | ||
17 | |||
diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 3bb8040..cec17e2 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | |||
@@ -24,7 +24,6 @@ | |||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | |||
28 | using System; | 27 | using System; |
29 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
30 | using System.IO; | 29 | using System.IO; |
@@ -42,7 +41,7 @@ using OpenSim.Framework; | |||
42 | using OpenSim.Framework.Console; | 41 | using OpenSim.Framework.Console; |
43 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; | 42 | using OpenSim.Region.CoreModules.Framework.InterfaceCommander; |
44 | using OpenSim.Region.CoreModules.World.Terrain.FileLoaders; | 43 | using OpenSim.Region.CoreModules.World.Terrain.FileLoaders; |
45 | using OpenSim.Region.CoreModules.World.Terrain.Features; | 44 | using OpenSim.Region.CoreModules.World.Terrain.Modifiers; |
46 | using OpenSim.Region.CoreModules.World.Terrain.FloodBrushes; | 45 | using OpenSim.Region.CoreModules.World.Terrain.FloodBrushes; |
47 | using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes; | 46 | using OpenSim.Region.CoreModules.World.Terrain.PaintBrushes; |
48 | using OpenSim.Region.Framework.Interfaces; | 47 | using OpenSim.Region.Framework.Interfaces; |
@@ -75,14 +74,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
75 | 74 | ||
76 | #endregion | 75 | #endregion |
77 | 76 | ||
78 | /// <summary> | ||
79 | /// Terrain Features | ||
80 | /// </summary> | ||
81 | public enum TerrainFeatures: byte | ||
82 | { | ||
83 | Rectangle = 1, | ||
84 | } | ||
85 | |||
86 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 77 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
87 | 78 | ||
88 | #pragma warning disable 414 | 79 | #pragma warning disable 414 |
@@ -90,26 +81,19 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
90 | #pragma warning restore 414 | 81 | #pragma warning restore 414 |
91 | 82 | ||
92 | private readonly Commander m_commander = new Commander("terrain"); | 83 | private readonly Commander m_commander = new Commander("terrain"); |
93 | |||
94 | private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = | 84 | private readonly Dictionary<StandardTerrainEffects, ITerrainFloodEffect> m_floodeffects = |
95 | new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>(); | 85 | new Dictionary<StandardTerrainEffects, ITerrainFloodEffect>(); |
96 | |||
97 | private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>(); | 86 | private readonly Dictionary<string, ITerrainLoader> m_loaders = new Dictionary<string, ITerrainLoader>(); |
98 | |||
99 | private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = | 87 | private readonly Dictionary<StandardTerrainEffects, ITerrainPaintableEffect> m_painteffects = |
100 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); | 88 | new Dictionary<StandardTerrainEffects, ITerrainPaintableEffect>(); |
101 | |||
102 | private Dictionary<string, ITerrainEffect> m_plugineffects; | 89 | private Dictionary<string, ITerrainEffect> m_plugineffects; |
103 | 90 | private Dictionary<string, ITerrainModifier> m_modifyOperations = | |
104 | private Dictionary<string, ITerrainFeature> m_featureEffects = | 91 | new Dictionary<string, ITerrainModifier>(); |
105 | new Dictionary<string, ITerrainFeature>(); | ||
106 | |||
107 | private ITerrainChannel m_channel; | 92 | private ITerrainChannel m_channel; |
108 | private ITerrainChannel m_revert; | 93 | private ITerrainChannel m_revert; |
109 | private Scene m_scene; | 94 | private Scene m_scene; |
110 | private volatile bool m_tainted; | 95 | private volatile bool m_tainted; |
111 | private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5); | 96 | private readonly Stack<LandUndoState> m_undo = new Stack<LandUndoState>(5); |
112 | |||
113 | private String m_InitialTerrain = "pinhead-island"; | 97 | private String m_InitialTerrain = "pinhead-island"; |
114 | 98 | ||
115 | // If true, send terrain patch updates to clients based on their view distance | 99 | // If true, send terrain patch updates to clients based on their view distance |
@@ -136,14 +120,17 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
136 | { | 120 | { |
137 | return (updateCount > 0); | 121 | return (updateCount > 0); |
138 | } | 122 | } |
123 | |||
139 | public void SetByXY(int x, int y, bool state) | 124 | public void SetByXY(int x, int y, bool state) |
140 | { | 125 | { |
141 | this.SetByPatch(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, state); | 126 | this.SetByPatch(x / Constants.TerrainPatchSize, y / Constants.TerrainPatchSize, state); |
142 | } | 127 | } |
128 | |||
143 | public bool GetByPatch(int patchX, int patchY) | 129 | public bool GetByPatch(int patchX, int patchY) |
144 | { | 130 | { |
145 | return updated[patchX, patchY]; | 131 | return updated[patchX, patchY]; |
146 | } | 132 | } |
133 | |||
147 | public void SetByPatch(int patchX, int patchY, bool state) | 134 | public void SetByPatch(int patchX, int patchY, bool state) |
148 | { | 135 | { |
149 | bool prevState = updated[patchX, patchY]; | 136 | bool prevState = updated[patchX, patchY]; |
@@ -153,11 +140,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
153 | updateCount--; | 140 | updateCount--; |
154 | updated[patchX, patchY] = state; | 141 | updated[patchX, patchY] = state; |
155 | } | 142 | } |
143 | |||
156 | public void SetAll(bool state) | 144 | public void SetAll(bool state) |
157 | { | 145 | { |
158 | updateCount = 0; | 146 | updateCount = 0; |
159 | for (int xx = 0; xx < updated.GetLength(0); xx++) | 147 | for(int xx = 0; xx < updated.GetLength(0); xx++) |
160 | for (int yy = 0; yy < updated.GetLength(1); yy++) | 148 | for(int yy = 0; yy < updated.GetLength(1); yy++) |
161 | updated[xx, yy] = state; | 149 | updated[xx, yy] = state; |
162 | if (state) | 150 | if (state) |
163 | updateCount = updated.GetLength(0) * updated.GetLength(1); | 151 | updateCount = updated.GetLength(0) * updated.GetLength(1); |
@@ -174,9 +162,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
174 | terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize) | 162 | terrData.SizeX / Constants.TerrainPatchSize, terrData.SizeY / Constants.TerrainPatchSize) |
175 | ); | 163 | ); |
176 | } | 164 | } |
177 | for (int xx = 0; xx < terrData.SizeX; xx += Constants.TerrainPatchSize) | 165 | for(int xx = 0; xx < terrData.SizeX; xx += Constants.TerrainPatchSize) |
178 | { | 166 | { |
179 | for (int yy = 0; yy < terrData.SizeY; yy += Constants.TerrainPatchSize) | 167 | for(int yy = 0; yy < terrData.SizeY; yy += Constants.TerrainPatchSize) |
180 | { | 168 | { |
181 | // Only set tainted. The patch bit may be set if the patch was to be sent later. | 169 | // Only set tainted. The patch bit may be set if the patch was to be sent later. |
182 | if (terrData.IsTaintedAt(xx, yy, false)) | 170 | if (terrData.IsTaintedAt(xx, yy, false)) |
@@ -201,8 +189,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
201 | 189 | ||
202 | #region ICommandableModule Members | 190 | #region ICommandableModule Members |
203 | 191 | ||
204 | public ICommander CommandInterface | 192 | public ICommander CommandInterface { |
205 | { | ||
206 | get { return m_commander; } | 193 | get { return m_commander; } |
207 | } | 194 | } |
208 | 195 | ||
@@ -230,7 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
230 | m_scene = scene; | 217 | m_scene = scene; |
231 | 218 | ||
232 | // Install terrain module in the simulator | 219 | // Install terrain module in the simulator |
233 | lock (m_scene) | 220 | lock(m_scene) |
234 | { | 221 | { |
235 | if (m_scene.Heightmap == null) | 222 | if (m_scene.Heightmap == null) |
236 | { | 223 | { |
@@ -262,7 +249,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
262 | string supportedFilesSeparatorForTileSave = ""; | 249 | string supportedFilesSeparatorForTileSave = ""; |
263 | 250 | ||
264 | m_supportFileExtensionsForTileSave = ""; | 251 | m_supportFileExtensionsForTileSave = ""; |
265 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 252 | foreach(KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
266 | { | 253 | { |
267 | m_supportedFileExtensions += supportedFilesSeparator + loader.Key + " (" + loader.Value + ")"; | 254 | m_supportedFileExtensions += supportedFilesSeparator + loader.Key + " (" + loader.Value + ")"; |
268 | supportedFilesSeparator = ", "; | 255 | supportedFilesSeparator = ", "; |
@@ -285,7 +272,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
285 | 272 | ||
286 | public void RemoveRegion(Scene scene) | 273 | public void RemoveRegion(Scene scene) |
287 | { | 274 | { |
288 | lock (m_scene) | 275 | lock(m_scene) |
289 | { | 276 | { |
290 | // remove the commands | 277 | // remove the commands |
291 | m_scene.UnregisterModuleCommander(m_commander.Name); | 278 | m_scene.UnregisterModuleCommander(m_commander.Name); |
@@ -304,13 +291,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
304 | { | 291 | { |
305 | } | 292 | } |
306 | 293 | ||
307 | public Type ReplaceableInterface | 294 | public Type ReplaceableInterface { |
308 | { | ||
309 | get { return null; } | 295 | get { return null; } |
310 | } | 296 | } |
311 | 297 | ||
312 | public string Name | 298 | public string Name { |
313 | { | ||
314 | get { return "TerrainModule"; } | 299 | get { return "TerrainModule"; } |
315 | } | 300 | } |
316 | 301 | ||
@@ -329,11 +314,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
329 | /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> | 314 | /// <param name="filename">Filename to terrain file. Type is determined by extension.</param> |
330 | public void LoadFromFile(string filename) | 315 | public void LoadFromFile(string filename) |
331 | { | 316 | { |
332 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 317 | foreach(KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
333 | { | 318 | { |
334 | if (filename.EndsWith(loader.Key)) | 319 | if (filename.EndsWith(loader.Key)) |
335 | { | 320 | { |
336 | lock (m_scene) | 321 | lock(m_scene) |
337 | { | 322 | { |
338 | try | 323 | try |
339 | { | 324 | { |
@@ -349,20 +334,20 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
349 | m_channel = channel; | 334 | m_channel = channel; |
350 | UpdateRevertMap(); | 335 | UpdateRevertMap(); |
351 | } | 336 | } |
352 | catch (NotImplementedException) | 337 | catch(NotImplementedException) |
353 | { | 338 | { |
354 | m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + | 339 | m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + |
355 | " parser does not support file loading. (May be save only)"); | 340 | " parser does not support file loading. (May be save only)"); |
356 | throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value)); | 341 | throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value)); |
357 | } | 342 | } |
358 | catch (FileNotFoundException) | 343 | catch(FileNotFoundException) |
359 | { | 344 | { |
360 | m_log.Error( | 345 | m_log.Error( |
361 | "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)"); | 346 | "[TERRAIN]: Unable to load heightmap, file not found. (A directory permissions error may also cause this)"); |
362 | throw new TerrainException( | 347 | throw new TerrainException( |
363 | String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename)); | 348 | String.Format("unable to load heightmap: file {0} not found (or permissions do not allow access", filename)); |
364 | } | 349 | } |
365 | catch (ArgumentException e) | 350 | catch(ArgumentException e) |
366 | { | 351 | { |
367 | m_log.ErrorFormat("[TERRAIN]: Unable to load heightmap: {0}", e.Message); | 352 | m_log.ErrorFormat("[TERRAIN]: Unable to load heightmap: {0}", e.Message); |
368 | throw new TerrainException( | 353 | throw new TerrainException( |
@@ -386,7 +371,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
386 | { | 371 | { |
387 | try | 372 | try |
388 | { | 373 | { |
389 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 374 | foreach(KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
390 | { | 375 | { |
391 | if (filename.EndsWith(loader.Key)) | 376 | if (filename.EndsWith(loader.Key)) |
392 | { | 377 | { |
@@ -396,7 +381,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
396 | } | 381 | } |
397 | } | 382 | } |
398 | } | 383 | } |
399 | catch (IOException ioe) | 384 | catch(IOException ioe) |
400 | { | 385 | { |
401 | m_log.Error(String.Format("[TERRAIN]: Unable to save to {0}, {1}", filename, ioe.Message)); | 386 | m_log.Error(String.Format("[TERRAIN]: Unable to save to {0}, {1}", filename, ioe.Message)); |
402 | } | 387 | } |
@@ -429,11 +414,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
429 | public void LoadFromStream(string filename, Vector3 displacement, | 414 | public void LoadFromStream(string filename, Vector3 displacement, |
430 | float radianRotation, Vector2 rotationDisplacement, Stream stream) | 415 | float radianRotation, Vector2 rotationDisplacement, Stream stream) |
431 | { | 416 | { |
432 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 417 | foreach(KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
433 | { | 418 | { |
434 | if (filename.EndsWith(loader.Key)) | 419 | if (filename.EndsWith(loader.Key)) |
435 | { | 420 | { |
436 | lock (m_scene) | 421 | lock(m_scene) |
437 | { | 422 | { |
438 | try | 423 | try |
439 | { | 424 | { |
@@ -441,7 +426,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
441 | m_channel.Merge(channel, displacement, radianRotation, rotationDisplacement); | 426 | m_channel.Merge(channel, displacement, radianRotation, rotationDisplacement); |
442 | UpdateRevertMap(); | 427 | UpdateRevertMap(); |
443 | } | 428 | } |
444 | catch (NotImplementedException) | 429 | catch(NotImplementedException) |
445 | { | 430 | { |
446 | m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + | 431 | m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + |
447 | " parser does not support file loading. (May be save only)"); | 432 | " parser does not support file loading. (May be save only)"); |
@@ -501,7 +486,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
501 | { | 486 | { |
502 | try | 487 | try |
503 | { | 488 | { |
504 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 489 | foreach(KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
505 | { | 490 | { |
506 | if (filename.EndsWith(loader.Key)) | 491 | if (filename.EndsWith(loader.Key)) |
507 | { | 492 | { |
@@ -510,7 +495,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
510 | } | 495 | } |
511 | } | 496 | } |
512 | } | 497 | } |
513 | catch (NotImplementedException) | 498 | catch(NotImplementedException) |
514 | { | 499 | { |
515 | m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented."); | 500 | m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented."); |
516 | throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented")); | 501 | throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented")); |
@@ -519,12 +504,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
519 | 504 | ||
520 | // Someone diddled terrain outside the normal code paths. Set the taintedness for all clients. | 505 | // Someone diddled terrain outside the normal code paths. Set the taintedness for all clients. |
521 | // ITerrainModule.TaintTerrain() | 506 | // ITerrainModule.TaintTerrain() |
522 | public void TaintTerrain () | 507 | public void TaintTerrain() |
523 | { | 508 | { |
524 | lock (m_perClientPatchUpdates) | 509 | lock(m_perClientPatchUpdates) |
525 | { | 510 | { |
526 | // Set the flags for all clients so the tainted patches will be sent out | 511 | // Set the flags for all clients so the tainted patches will be sent out |
527 | foreach (PatchUpdates pups in m_perClientPatchUpdates.Values) | 512 | foreach(PatchUpdates pups in m_perClientPatchUpdates.Values) |
528 | { | 513 | { |
529 | pups.SetAll(m_scene.Heightmap.GetTerrainData()); | 514 | pups.SetAll(m_scene.Heightmap.GetTerrainData()); |
530 | } | 515 | } |
@@ -539,7 +524,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
539 | ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); | 524 | ScenePresence presence = m_scene.GetScenePresence(pClient.AgentId); |
540 | if (presence != null) | 525 | if (presence != null) |
541 | { | 526 | { |
542 | lock (m_perClientPatchUpdates) | 527 | lock(m_perClientPatchUpdates) |
543 | { | 528 | { |
544 | PatchUpdates pups; | 529 | PatchUpdates pups; |
545 | if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups)) | 530 | if (!m_perClientPatchUpdates.TryGetValue(pClient.AgentId, out pups)) |
@@ -566,13 +551,13 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
566 | m_plugineffects = new Dictionary<string, ITerrainEffect>(); | 551 | m_plugineffects = new Dictionary<string, ITerrainEffect>(); |
567 | LoadPlugins(Assembly.GetCallingAssembly()); | 552 | LoadPlugins(Assembly.GetCallingAssembly()); |
568 | string plugineffectsPath = "Terrain"; | 553 | string plugineffectsPath = "Terrain"; |
569 | 554 | ||
570 | // Load the files in the Terrain/ dir | 555 | // Load the files in the Terrain/ dir |
571 | if (!Directory.Exists(plugineffectsPath)) | 556 | if (!Directory.Exists(plugineffectsPath)) |
572 | return; | 557 | return; |
573 | 558 | ||
574 | string[] files = Directory.GetFiles(plugineffectsPath); | 559 | string[] files = Directory.GetFiles(plugineffectsPath); |
575 | foreach (string file in files) | 560 | foreach(string file in files) |
576 | { | 561 | { |
577 | m_log.Info("Loading effects in " + file); | 562 | m_log.Info("Loading effects in " + file); |
578 | try | 563 | try |
@@ -580,7 +565,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
580 | Assembly library = Assembly.LoadFrom(file); | 565 | Assembly library = Assembly.LoadFrom(file); |
581 | LoadPlugins(library); | 566 | LoadPlugins(library); |
582 | } | 567 | } |
583 | catch (BadImageFormatException) | 568 | catch(BadImageFormatException) |
584 | { | 569 | { |
585 | } | 570 | } |
586 | } | 571 | } |
@@ -588,7 +573,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
588 | 573 | ||
589 | private void LoadPlugins(Assembly library) | 574 | private void LoadPlugins(Assembly library) |
590 | { | 575 | { |
591 | foreach (Type pluginType in library.GetTypes()) | 576 | foreach(Type pluginType in library.GetTypes()) |
592 | { | 577 | { |
593 | try | 578 | try |
594 | { | 579 | { |
@@ -610,7 +595,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
610 | m_log.Info("L ... " + typeName); | 595 | m_log.Info("L ... " + typeName); |
611 | } | 596 | } |
612 | } | 597 | } |
613 | catch (AmbiguousMatchException) | 598 | catch(AmbiguousMatchException) |
614 | { | 599 | { |
615 | } | 600 | } |
616 | } | 601 | } |
@@ -618,7 +603,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
618 | 603 | ||
619 | public void InstallPlugin(string pluginName, ITerrainEffect effect) | 604 | public void InstallPlugin(string pluginName, ITerrainEffect effect) |
620 | { | 605 | { |
621 | lock (m_plugineffects) | 606 | lock(m_plugineffects) |
622 | { | 607 | { |
623 | if (!m_plugineffects.ContainsKey(pluginName)) | 608 | if (!m_plugineffects.ContainsKey(pluginName)) |
624 | { | 609 | { |
@@ -661,8 +646,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
661 | m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea(); | 646 | m_floodeffects[StandardTerrainEffects.Flatten] = new FlattenArea(); |
662 | m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert); | 647 | m_floodeffects[StandardTerrainEffects.Revert] = new RevertArea(m_revert); |
663 | 648 | ||
664 | // Terrain Feature effects | 649 | // Terrain Modifier operations |
665 | m_featureEffects["rectangle"] = new RectangleFeature(this); | 650 | m_modifyOperations["min"] = new MinModifier(this); |
651 | m_modifyOperations["max"] = new MaxModifier(this); | ||
652 | m_modifyOperations["raise"] = new RaiseModifier(this); | ||
653 | m_modifyOperations["lower"] = new LowerModifier(this); | ||
654 | m_modifyOperations["fill"] = new FillModifier(this); | ||
655 | m_modifyOperations["smooth"] = new SmoothModifier(this); | ||
656 | m_modifyOperations["noise"] = new NoiseModifier(this); | ||
666 | 657 | ||
667 | // Filesystem load/save loaders | 658 | // Filesystem load/save loaders |
668 | m_loaders[".r32"] = new RAW32(); | 659 | m_loaders[".r32"] = new RAW32(); |
@@ -707,22 +698,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
707 | /// <param name="fileStartY">Where to begin our slice</param> | 698 | /// <param name="fileStartY">Where to begin our slice</param> |
708 | public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) | 699 | public void LoadFromFile(string filename, int fileWidth, int fileHeight, int fileStartX, int fileStartY) |
709 | { | 700 | { |
710 | int offsetX = (int) m_scene.RegionInfo.RegionLocX - fileStartX; | 701 | int offsetX = (int)m_scene.RegionInfo.RegionLocX - fileStartX; |
711 | int offsetY = (int) m_scene.RegionInfo.RegionLocY - fileStartY; | 702 | int offsetY = (int)m_scene.RegionInfo.RegionLocY - fileStartY; |
712 | 703 | ||
713 | if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) | 704 | if (offsetX >= 0 && offsetX < fileWidth && offsetY >= 0 && offsetY < fileHeight) |
714 | { | 705 | { |
715 | // this region is included in the tile request | 706 | // this region is included in the tile request |
716 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 707 | foreach(KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
717 | { | 708 | { |
718 | if (filename.EndsWith(loader.Key)) | 709 | if (filename.EndsWith(loader.Key)) |
719 | { | 710 | { |
720 | lock (m_scene) | 711 | lock(m_scene) |
721 | { | 712 | { |
722 | ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, | 713 | ITerrainChannel channel = loader.Value.LoadFile(filename, offsetX, offsetY, |
723 | fileWidth, fileHeight, | 714 | fileWidth, fileHeight, |
724 | (int) m_scene.RegionInfo.RegionSizeX, | 715 | (int)m_scene.RegionInfo.RegionSizeX, |
725 | (int) m_scene.RegionInfo.RegionSizeY); | 716 | (int)m_scene.RegionInfo.RegionSizeY); |
726 | m_scene.Heightmap = channel; | 717 | m_scene.Heightmap = channel; |
727 | m_channel = channel; | 718 | m_channel = channel; |
728 | UpdateRevertMap(); | 719 | UpdateRevertMap(); |
@@ -761,11 +752,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
761 | } | 752 | } |
762 | 753 | ||
763 | // this region is included in the tile request | 754 | // this region is included in the tile request |
764 | foreach (KeyValuePair<string, ITerrainLoader> loader in m_loaders) | 755 | foreach(KeyValuePair<string, ITerrainLoader> loader in m_loaders) |
765 | { | 756 | { |
766 | if (filename.EndsWith(loader.Key) && loader.Value.SupportsTileSave()) | 757 | if (filename.EndsWith(loader.Key) && loader.Value.SupportsTileSave()) |
767 | { | 758 | { |
768 | lock (m_scene) | 759 | lock(m_scene) |
769 | { | 760 | { |
770 | loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, | 761 | loader.Value.SaveFile(m_channel, filename, offsetX, offsetY, |
771 | fileWidth, fileHeight, | 762 | fileWidth, fileHeight, |
@@ -777,7 +768,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
777 | fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1, | 768 | fileStartX, fileStartY, fileStartX + fileWidth - 1, fileStartY + fileHeight - 1, |
778 | m_scene.RegionInfo.RegionName, filename); | 769 | m_scene.RegionInfo.RegionName, filename); |
779 | } | 770 | } |
780 | 771 | ||
781 | return; | 772 | return; |
782 | } | 773 | } |
783 | } | 774 | } |
@@ -799,9 +790,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
799 | TerrainData terrData = m_channel.GetTerrainData(); | 790 | TerrainData terrData = m_channel.GetTerrainData(); |
800 | 791 | ||
801 | bool shouldTaint = false; | 792 | bool shouldTaint = false; |
802 | for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize) | 793 | for(int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize) |
803 | { | 794 | { |
804 | for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize) | 795 | for(int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize) |
805 | { | 796 | { |
806 | if (terrData.IsTaintedAt(x, y)) | 797 | if (terrData.IsTaintedAt(x, y)) |
807 | { | 798 | { |
@@ -856,7 +847,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
856 | 847 | ||
857 | string[] tmpArgs = new string[args.Length - 2]; | 848 | string[] tmpArgs = new string[args.Length - 2]; |
858 | int i; | 849 | int i; |
859 | for (i = 2; i < args.Length; i++) | 850 | for(i = 2; i < args.Length; i++) |
860 | tmpArgs[i - 2] = args[i]; | 851 | tmpArgs[i - 2] = args[i]; |
861 | 852 | ||
862 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); | 853 | m_commander.ProcessConsoleCommand(args[1], tmpArgs); |
@@ -874,7 +865,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
874 | client.OnLandUndo += client_OnLandUndo; | 865 | client.OnLandUndo += client_OnLandUndo; |
875 | client.OnUnackedTerrain += client_OnUnackedTerrain; | 866 | client.OnUnackedTerrain += client_OnUnackedTerrain; |
876 | } | 867 | } |
877 | 868 | ||
878 | /// <summary> | 869 | /// <summary> |
879 | /// Installs terrain brush hook to IClientAPI | 870 | /// Installs terrain brush hook to IClientAPI |
880 | /// </summary> | 871 | /// </summary> |
@@ -890,10 +881,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
890 | presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain; | 881 | presence.ControllingClient.OnUnackedTerrain -= client_OnUnackedTerrain; |
891 | } | 882 | } |
892 | 883 | ||
893 | lock (m_perClientPatchUpdates) | 884 | lock(m_perClientPatchUpdates) |
894 | m_perClientPatchUpdates.Remove(client); | 885 | m_perClientPatchUpdates.Remove(client); |
895 | } | 886 | } |
896 | 887 | ||
897 | /// <summary> | 888 | /// <summary> |
898 | /// Scan over changes in the terrain and limit height changes. This enforces the | 889 | /// Scan over changes in the terrain and limit height changes. This enforces the |
899 | /// non-estate owner limits on rate of terrain editting. | 890 | /// non-estate owner limits on rate of terrain editting. |
@@ -904,12 +895,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
904 | TerrainData terrData = m_channel.GetTerrainData(); | 895 | TerrainData terrData = m_channel.GetTerrainData(); |
905 | 896 | ||
906 | bool wasLimited = false; | 897 | bool wasLimited = false; |
907 | for (int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize) | 898 | for(int x = 0; x < terrData.SizeX; x += Constants.TerrainPatchSize) |
908 | { | 899 | { |
909 | for (int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize) | 900 | for(int y = 0; y < terrData.SizeY; y += Constants.TerrainPatchSize) |
910 | { | 901 | { |
911 | if (terrData.IsTaintedAt(x, y, false /* clearOnTest */)) | 902 | if (terrData.IsTaintedAt(x, y, false /* clearOnTest */)) |
912 | { | 903 | { |
913 | // If we should respect the estate settings then | 904 | // If we should respect the estate settings then |
914 | // fixup and height deltas that don't respect them. | 905 | // fixup and height deltas that don't respect them. |
915 | // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values. | 906 | // Note that LimitChannelChanges() modifies the TerrainChannel with the limited height values. |
@@ -933,9 +924,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
933 | 924 | ||
934 | // loop through the height map for this patch and compare it against | 925 | // loop through the height map for this patch and compare it against |
935 | // the revert map | 926 | // the revert map |
936 | for (int x = xStart; x < xStart + Constants.TerrainPatchSize; x++) | 927 | for(int x = xStart; x < xStart + Constants.TerrainPatchSize; x++) |
937 | { | 928 | { |
938 | for (int y = yStart; y < yStart + Constants.TerrainPatchSize; y++) | 929 | for(int y = yStart; y < yStart + Constants.TerrainPatchSize; y++) |
939 | { | 930 | { |
940 | float requestedHeight = terrData[x, y]; | 931 | float requestedHeight = terrData[x, y]; |
941 | float bakedHeight = (float)m_revert[x, y]; | 932 | float bakedHeight = (float)m_revert[x, y]; |
@@ -959,7 +950,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
959 | 950 | ||
960 | private void client_OnLandUndo(IClientAPI client) | 951 | private void client_OnLandUndo(IClientAPI client) |
961 | { | 952 | { |
962 | lock (m_undo) | 953 | lock(m_undo) |
963 | { | 954 | { |
964 | if (m_undo.Count > 0) | 955 | if (m_undo.Count > 0) |
965 | { | 956 | { |
@@ -981,19 +972,19 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
981 | if (m_sendTerrainUpdatesByViewDistance) | 972 | if (m_sendTerrainUpdatesByViewDistance) |
982 | { | 973 | { |
983 | // Add that this patch needs to be sent to the accounting for each client. | 974 | // Add that this patch needs to be sent to the accounting for each client. |
984 | lock (m_perClientPatchUpdates) | 975 | lock(m_perClientPatchUpdates) |
985 | { | 976 | { |
986 | m_scene.ForEachScenePresence(presence => | 977 | m_scene.ForEachScenePresence(presence => |
978 | { | ||
979 | PatchUpdates thisClientUpdates; | ||
980 | if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates)) | ||
987 | { | 981 | { |
988 | PatchUpdates thisClientUpdates; | 982 | // There is a ScenePresence without a send patch map. Create one. |
989 | if (!m_perClientPatchUpdates.TryGetValue(presence.UUID, out thisClientUpdates)) | 983 | thisClientUpdates = new PatchUpdates(terrData, presence); |
990 | { | 984 | m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates); |
991 | // There is a ScenePresence without a send patch map. Create one. | ||
992 | thisClientUpdates = new PatchUpdates(terrData, presence); | ||
993 | m_perClientPatchUpdates.Add(presence.UUID, thisClientUpdates); | ||
994 | } | ||
995 | thisClientUpdates.SetByXY(x, y, true); | ||
996 | } | 985 | } |
986 | thisClientUpdates.SetByXY(x, y, true); | ||
987 | } | ||
997 | ); | 988 | ); |
998 | } | 989 | } |
999 | } | 990 | } |
@@ -1005,11 +996,11 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1005 | float[] heightMap = new float[10]; | 996 | float[] heightMap = new float[10]; |
1006 | m_scene.ForEachClient( | 997 | m_scene.ForEachClient( |
1007 | delegate(IClientAPI controller) | 998 | delegate(IClientAPI controller) |
1008 | { | 999 | { |
1009 | controller.SendLayerData(x / Constants.TerrainPatchSize, | 1000 | controller.SendLayerData(x / Constants.TerrainPatchSize, |
1010 | y / Constants.TerrainPatchSize, | 1001 | y / Constants.TerrainPatchSize, |
1011 | heightMap); | 1002 | heightMap); |
1012 | } | 1003 | } |
1013 | ); | 1004 | ); |
1014 | } | 1005 | } |
1015 | } | 1006 | } |
@@ -1019,12 +1010,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1019 | public int PatchX; | 1010 | public int PatchX; |
1020 | public int PatchY; | 1011 | public int PatchY; |
1021 | public float Dist; | 1012 | public float Dist; |
1013 | |||
1022 | public PatchesToSend(int pX, int pY, float pDist) | 1014 | public PatchesToSend(int pX, int pY, float pDist) |
1023 | { | 1015 | { |
1024 | PatchX = pX; | 1016 | PatchX = pX; |
1025 | PatchY = pY; | 1017 | PatchY = pY; |
1026 | Dist = pDist; | 1018 | Dist = pDist; |
1027 | } | 1019 | } |
1020 | |||
1028 | public int CompareTo(PatchesToSend other) | 1021 | public int CompareTo(PatchesToSend other) |
1029 | { | 1022 | { |
1030 | return Dist.CompareTo(other.Dist); | 1023 | return Dist.CompareTo(other.Dist); |
@@ -1036,9 +1029,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1036 | // Loop through all the per-client info and send any patches necessary. | 1029 | // Loop through all the per-client info and send any patches necessary. |
1037 | private void CheckSendingPatchesToClients() | 1030 | private void CheckSendingPatchesToClients() |
1038 | { | 1031 | { |
1039 | lock (m_perClientPatchUpdates) | 1032 | lock(m_perClientPatchUpdates) |
1040 | { | 1033 | { |
1041 | foreach (PatchUpdates pups in m_perClientPatchUpdates.Values) | 1034 | foreach(PatchUpdates pups in m_perClientPatchUpdates.Values) |
1042 | { | 1035 | { |
1043 | if (pups.HasUpdates()) | 1036 | if (pups.HasUpdates()) |
1044 | { | 1037 | { |
@@ -1062,7 +1055,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1062 | int[] yPieces = new int[toSend.Count]; | 1055 | int[] yPieces = new int[toSend.Count]; |
1063 | float[] patchPieces = new float[toSend.Count * 2]; | 1056 | float[] patchPieces = new float[toSend.Count * 2]; |
1064 | int pieceIndex = 0; | 1057 | int pieceIndex = 0; |
1065 | foreach (PatchesToSend pts in toSend) | 1058 | foreach(PatchesToSend pts in toSend) |
1066 | { | 1059 | { |
1067 | patchPieces[pieceIndex++] = pts.PatchX; | 1060 | patchPieces[pieceIndex++] = pts.PatchX; |
1068 | patchPieces[pieceIndex++] = pts.PatchY; | 1061 | patchPieces[pieceIndex++] = pts.PatchY; |
@@ -1083,25 +1076,25 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1083 | return ret; | 1076 | return ret; |
1084 | 1077 | ||
1085 | // Compute the area of patches within our draw distance | 1078 | // Compute the area of patches within our draw distance |
1086 | int startX = (((int) (presence.AbsolutePosition.X - presence.DrawDistance))/Constants.TerrainPatchSize) - 2; | 1079 | int startX = (((int)(presence.AbsolutePosition.X - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2; |
1087 | startX = Math.Max(startX, 0); | 1080 | startX = Math.Max(startX, 0); |
1088 | startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX/Constants.TerrainPatchSize); | 1081 | startX = Math.Min(startX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize); |
1089 | int startY = (((int) (presence.AbsolutePosition.Y - presence.DrawDistance))/Constants.TerrainPatchSize) - 2; | 1082 | int startY = (((int)(presence.AbsolutePosition.Y - presence.DrawDistance)) / Constants.TerrainPatchSize) - 2; |
1090 | startY = Math.Max(startY, 0); | 1083 | startY = Math.Max(startY, 0); |
1091 | startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY/Constants.TerrainPatchSize); | 1084 | startY = Math.Min(startY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize); |
1092 | int endX = (((int) (presence.AbsolutePosition.X + presence.DrawDistance))/Constants.TerrainPatchSize) + 2; | 1085 | int endX = (((int)(presence.AbsolutePosition.X + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2; |
1093 | endX = Math.Max(endX, 0); | 1086 | endX = Math.Max(endX, 0); |
1094 | endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX/Constants.TerrainPatchSize); | 1087 | endX = Math.Min(endX, (int)m_scene.RegionInfo.RegionSizeX / Constants.TerrainPatchSize); |
1095 | int endY = (((int) (presence.AbsolutePosition.Y + presence.DrawDistance))/Constants.TerrainPatchSize) + 2; | 1088 | int endY = (((int)(presence.AbsolutePosition.Y + presence.DrawDistance)) / Constants.TerrainPatchSize) + 2; |
1096 | endY = Math.Max(endY, 0); | 1089 | endY = Math.Max(endY, 0); |
1097 | endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY/Constants.TerrainPatchSize); | 1090 | endY = Math.Min(endY, (int)m_scene.RegionInfo.RegionSizeY / Constants.TerrainPatchSize); |
1098 | // m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, start=<{4},{5}>, end=<{6},{7}>", | 1091 | // m_log.DebugFormat("{0} GetModifiedPatchesInViewDistance. rName={1}, ddist={2}, apos={3}, start=<{4},{5}>, end=<{6},{7}>", |
1099 | // LogHeader, m_scene.RegionInfo.RegionName, | 1092 | // LogHeader, m_scene.RegionInfo.RegionName, |
1100 | // presence.DrawDistance, presence.AbsolutePosition, | 1093 | // presence.DrawDistance, presence.AbsolutePosition, |
1101 | // startX, startY, endX, endY); | 1094 | // startX, startY, endX, endY); |
1102 | for (int x = startX; x < endX; x++) | 1095 | for(int x = startX; x < endX; x++) |
1103 | { | 1096 | { |
1104 | for (int y = startY; y < endY; y++) | 1097 | for(int y = startY; y < endY; y++) |
1105 | { | 1098 | { |
1106 | //Need to make sure we don't send the same ones over and over | 1099 | //Need to make sure we don't send the same ones over and over |
1107 | Vector3 presencePos = presence.AbsolutePosition; | 1100 | Vector3 presencePos = presence.AbsolutePosition; |
@@ -1133,28 +1126,28 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1133 | bool allowed = false; | 1126 | bool allowed = false; |
1134 | if (north == south && east == west) | 1127 | if (north == south && east == west) |
1135 | { | 1128 | { |
1136 | if (m_painteffects.ContainsKey((StandardTerrainEffects) action)) | 1129 | if (m_painteffects.ContainsKey((StandardTerrainEffects)action)) |
1137 | { | 1130 | { |
1138 | bool[,] allowMask = new bool[m_channel.Width,m_channel.Height]; | 1131 | bool[,] allowMask = new bool[m_channel.Width, m_channel.Height]; |
1139 | allowMask.Initialize(); | 1132 | allowMask.Initialize(); |
1140 | int n = size + 1; | 1133 | int n = size + 1; |
1141 | if (n > 2) | 1134 | if (n > 2) |
1142 | n = 4; | 1135 | n = 4; |
1143 | 1136 | ||
1144 | int zx = (int) (west + 0.5); | 1137 | int zx = (int)(west + 0.5); |
1145 | int zy = (int) (north + 0.5); | 1138 | int zy = (int)(north + 0.5); |
1146 | 1139 | ||
1147 | int dx; | 1140 | int dx; |
1148 | for (dx=-n; dx<=n; dx++) | 1141 | for(dx=-n; dx<=n; dx++) |
1149 | { | 1142 | { |
1150 | int dy; | 1143 | int dy; |
1151 | for (dy=-n; dy<=n; dy++) | 1144 | for(dy=-n; dy<=n; dy++) |
1152 | { | 1145 | { |
1153 | int x = zx + dx; | 1146 | int x = zx + dx; |
1154 | int y = zy + dy; | 1147 | int y = zy + dy; |
1155 | if (x>=0 && y>=0 && x<m_channel.Width && y<m_channel.Height) | 1148 | if (x >= 0 && y >= 0 && x < m_channel.Width && y < m_channel.Height) |
1156 | { | 1149 | { |
1157 | if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x,y,0))) | 1150 | if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x, y, 0))) |
1158 | { | 1151 | { |
1159 | allowMask[x, y] = true; | 1152 | allowMask[x, y] = true; |
1160 | allowed = true; | 1153 | allowed = true; |
@@ -1165,7 +1158,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1165 | if (allowed) | 1158 | if (allowed) |
1166 | { | 1159 | { |
1167 | StoreUndoState(); | 1160 | StoreUndoState(); |
1168 | m_painteffects[(StandardTerrainEffects) action].PaintEffect( | 1161 | m_painteffects[(StandardTerrainEffects)action].PaintEffect( |
1169 | m_channel, allowMask, west, south, height, size, seconds); | 1162 | m_channel, allowMask, west, south, height, size, seconds); |
1170 | 1163 | ||
1171 | //revert changes outside estate limits | 1164 | //revert changes outside estate limits |
@@ -1180,22 +1173,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1180 | } | 1173 | } |
1181 | else | 1174 | else |
1182 | { | 1175 | { |
1183 | if (m_floodeffects.ContainsKey((StandardTerrainEffects) action)) | 1176 | if (m_floodeffects.ContainsKey((StandardTerrainEffects)action)) |
1184 | { | 1177 | { |
1185 | bool[,] fillArea = new bool[m_channel.Width,m_channel.Height]; | 1178 | bool[,] fillArea = new bool[m_channel.Width, m_channel.Height]; |
1186 | fillArea.Initialize(); | 1179 | fillArea.Initialize(); |
1187 | 1180 | ||
1188 | int x; | 1181 | int x; |
1189 | for (x = 0; x < m_channel.Width; x++) | 1182 | for(x = 0; x < m_channel.Width; x++) |
1190 | { | 1183 | { |
1191 | int y; | 1184 | int y; |
1192 | for (y = 0; y < m_channel.Height; y++) | 1185 | for(y = 0; y < m_channel.Height; y++) |
1193 | { | 1186 | { |
1194 | if (x < east && x > west) | 1187 | if (x < east && x > west) |
1195 | { | 1188 | { |
1196 | if (y < north && y > south) | 1189 | if (y < north && y > south) |
1197 | { | 1190 | { |
1198 | if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x,y,0))) | 1191 | if (m_scene.Permissions.CanTerraformLand(agentId, new Vector3(x, y, 0))) |
1199 | { | 1192 | { |
1200 | fillArea[x, y] = true; | 1193 | fillArea[x, y] = true; |
1201 | allowed = true; | 1194 | allowed = true; |
@@ -1208,7 +1201,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1208 | if (allowed) | 1201 | if (allowed) |
1209 | { | 1202 | { |
1210 | StoreUndoState(); | 1203 | StoreUndoState(); |
1211 | m_floodeffects[(StandardTerrainEffects) action].FloodEffect(m_channel, fillArea, size); | 1204 | m_floodeffects[(StandardTerrainEffects)action].FloodEffect(m_channel, fillArea, size); |
1212 | 1205 | ||
1213 | //revert changes outside estate limits | 1206 | //revert changes outside estate limits |
1214 | if (!god) | 1207 | if (!god) |
@@ -1232,7 +1225,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1232 | InterfaceBakeTerrain(null); //bake terrain does not use the passed in parameter | 1225 | InterfaceBakeTerrain(null); //bake terrain does not use the passed in parameter |
1233 | } | 1226 | } |
1234 | } | 1227 | } |
1235 | 1228 | ||
1236 | protected void client_OnUnackedTerrain(IClientAPI client, int patchX, int patchY) | 1229 | protected void client_OnUnackedTerrain(IClientAPI client, int patchX, int patchY) |
1237 | { | 1230 | { |
1238 | //m_log.Debug("Terrain packet unacked, resending patch: " + patchX + " , " + patchY); | 1231 | //m_log.Debug("Terrain packet unacked, resending patch: " + patchX + " , " + patchY); |
@@ -1243,7 +1236,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1243 | 1236 | ||
1244 | private void StoreUndoState() | 1237 | private void StoreUndoState() |
1245 | { | 1238 | { |
1246 | lock (m_undo) | 1239 | lock(m_undo) |
1247 | { | 1240 | { |
1248 | if (m_undo.Count > 0) | 1241 | if (m_undo.Count > 0) |
1249 | { | 1242 | { |
@@ -1264,21 +1257,21 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1264 | 1257 | ||
1265 | private void InterfaceLoadFile(Object[] args) | 1258 | private void InterfaceLoadFile(Object[] args) |
1266 | { | 1259 | { |
1267 | LoadFromFile((string) args[0]); | 1260 | LoadFromFile((string)args[0]); |
1268 | } | 1261 | } |
1269 | 1262 | ||
1270 | private void InterfaceLoadTileFile(Object[] args) | 1263 | private void InterfaceLoadTileFile(Object[] args) |
1271 | { | 1264 | { |
1272 | LoadFromFile((string) args[0], | 1265 | LoadFromFile((string)args[0], |
1273 | (int) args[1], | 1266 | (int)args[1], |
1274 | (int) args[2], | 1267 | (int)args[2], |
1275 | (int) args[3], | 1268 | (int)args[3], |
1276 | (int) args[4]); | 1269 | (int)args[4]); |
1277 | } | 1270 | } |
1278 | 1271 | ||
1279 | private void InterfaceSaveFile(Object[] args) | 1272 | private void InterfaceSaveFile(Object[] args) |
1280 | { | 1273 | { |
1281 | SaveToFile((string) args[0]); | 1274 | SaveToFile((string)args[0]); |
1282 | } | 1275 | } |
1283 | 1276 | ||
1284 | private void InterfaceSaveTileFile(Object[] args) | 1277 | private void InterfaceSaveTileFile(Object[] args) |
@@ -1298,8 +1291,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1298 | private void InterfaceRevertTerrain(Object[] args) | 1291 | private void InterfaceRevertTerrain(Object[] args) |
1299 | { | 1292 | { |
1300 | int x, y; | 1293 | int x, y; |
1301 | for (x = 0; x < m_channel.Width; x++) | 1294 | for(x = 0; x < m_channel.Width; x++) |
1302 | for (y = 0; y < m_channel.Height; y++) | 1295 | for(y = 0; y < m_channel.Height; y++) |
1303 | m_channel[x, y] = m_revert[x, y]; | 1296 | m_channel[x, y] = m_revert[x, y]; |
1304 | 1297 | ||
1305 | } | 1298 | } |
@@ -1310,9 +1303,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1310 | 1303 | ||
1311 | if (direction.ToLower().StartsWith("y")) | 1304 | if (direction.ToLower().StartsWith("y")) |
1312 | { | 1305 | { |
1313 | for (int x = 0; x < m_channel.Width; x++) | 1306 | for(int x = 0; x < m_channel.Width; x++) |
1314 | { | 1307 | { |
1315 | for (int y = 0; y < m_channel.Height / 2; y++) | 1308 | for(int y = 0; y < m_channel.Height / 2; y++) |
1316 | { | 1309 | { |
1317 | double height = m_channel[x, y]; | 1310 | double height = m_channel[x, y]; |
1318 | double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y]; | 1311 | double flippedHeight = m_channel[x, (int)m_channel.Height - 1 - y]; |
@@ -1324,9 +1317,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1324 | } | 1317 | } |
1325 | else if (direction.ToLower().StartsWith("x")) | 1318 | else if (direction.ToLower().StartsWith("x")) |
1326 | { | 1319 | { |
1327 | for (int y = 0; y < m_channel.Height; y++) | 1320 | for(int y = 0; y < m_channel.Height; y++) |
1328 | { | 1321 | { |
1329 | for (int x = 0; x < m_channel.Width / 2; x++) | 1322 | for(int x = 0; x < m_channel.Width / 2; x++) |
1330 | { | 1323 | { |
1331 | double height = m_channel[x, y]; | 1324 | double height = m_channel[x, y]; |
1332 | double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y]; | 1325 | double flippedHeight = m_channel[(int)m_channel.Width - 1 - x, y]; |
@@ -1365,9 +1358,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1365 | int width = m_channel.Width; | 1358 | int width = m_channel.Width; |
1366 | int height = m_channel.Height; | 1359 | int height = m_channel.Height; |
1367 | 1360 | ||
1368 | for (int x = 0; x < width; x++) | 1361 | for(int x = 0; x < width; x++) |
1369 | { | 1362 | { |
1370 | for (int y = 0; y < height; y++) | 1363 | for(int y = 0; y < height; y++) |
1371 | { | 1364 | { |
1372 | double currHeight = m_channel[x, y]; | 1365 | double currHeight = m_channel[x, y]; |
1373 | if (currHeight < currMin) | 1366 | if (currHeight < currMin) |
@@ -1388,12 +1381,12 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1388 | //m_log.InfoFormat("Scale = {0}", scale); | 1381 | //m_log.InfoFormat("Scale = {0}", scale); |
1389 | 1382 | ||
1390 | // scale the heightmap accordingly | 1383 | // scale the heightmap accordingly |
1391 | for (int x = 0; x < width; x++) | 1384 | for(int x = 0; x < width; x++) |
1392 | { | 1385 | { |
1393 | for (int y = 0; y < height; y++) | 1386 | for(int y = 0; y < height; y++) |
1394 | { | 1387 | { |
1395 | double currHeight = m_channel[x, y] - currMin; | 1388 | double currHeight = m_channel[x, y] - currMin; |
1396 | m_channel[x, y] = desiredMin + (currHeight * scale); | 1389 | m_channel[x, y] = desiredMin + (currHeight * scale); |
1397 | } | 1390 | } |
1398 | } | 1391 | } |
1399 | 1392 | ||
@@ -1404,42 +1397,42 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1404 | private void InterfaceElevateTerrain(Object[] args) | 1397 | private void InterfaceElevateTerrain(Object[] args) |
1405 | { | 1398 | { |
1406 | int x, y; | 1399 | int x, y; |
1407 | for (x = 0; x < m_channel.Width; x++) | 1400 | for(x = 0; x < m_channel.Width; x++) |
1408 | for (y = 0; y < m_channel.Height; y++) | 1401 | for(y = 0; y < m_channel.Height; y++) |
1409 | m_channel[x, y] += (double) args[0]; | 1402 | m_channel[x, y] += (double)args[0]; |
1410 | } | 1403 | } |
1411 | 1404 | ||
1412 | private void InterfaceMultiplyTerrain(Object[] args) | 1405 | private void InterfaceMultiplyTerrain(Object[] args) |
1413 | { | 1406 | { |
1414 | int x, y; | 1407 | int x, y; |
1415 | for (x = 0; x < m_channel.Width; x++) | 1408 | for(x = 0; x < m_channel.Width; x++) |
1416 | for (y = 0; y < m_channel.Height; y++) | 1409 | for(y = 0; y < m_channel.Height; y++) |
1417 | m_channel[x, y] *= (double) args[0]; | 1410 | m_channel[x, y] *= (double)args[0]; |
1418 | } | 1411 | } |
1419 | 1412 | ||
1420 | private void InterfaceLowerTerrain(Object[] args) | 1413 | private void InterfaceLowerTerrain(Object[] args) |
1421 | { | 1414 | { |
1422 | int x, y; | 1415 | int x, y; |
1423 | for (x = 0; x < m_channel.Width; x++) | 1416 | for(x = 0; x < m_channel.Width; x++) |
1424 | for (y = 0; y < m_channel.Height; y++) | 1417 | for(y = 0; y < m_channel.Height; y++) |
1425 | m_channel[x, y] -= (double) args[0]; | 1418 | m_channel[x, y] -= (double)args[0]; |
1426 | } | 1419 | } |
1427 | 1420 | ||
1428 | public void InterfaceFillTerrain(Object[] args) | 1421 | public void InterfaceFillTerrain(Object[] args) |
1429 | { | 1422 | { |
1430 | int x, y; | 1423 | int x, y; |
1431 | 1424 | ||
1432 | for (x = 0; x < m_channel.Width; x++) | 1425 | for(x = 0; x < m_channel.Width; x++) |
1433 | for (y = 0; y < m_channel.Height; y++) | 1426 | for(y = 0; y < m_channel.Height; y++) |
1434 | m_channel[x, y] = (double) args[0]; | 1427 | m_channel[x, y] = (double)args[0]; |
1435 | } | 1428 | } |
1436 | 1429 | ||
1437 | private void InterfaceMinTerrain(Object[] args) | 1430 | private void InterfaceMinTerrain(Object[] args) |
1438 | { | 1431 | { |
1439 | int x, y; | 1432 | int x, y; |
1440 | for (x = 0; x < m_channel.Width; x++) | 1433 | for(x = 0; x < m_channel.Width; x++) |
1441 | { | 1434 | { |
1442 | for (y = 0; y < m_channel.Height; y++) | 1435 | for(y = 0; y < m_channel.Height; y++) |
1443 | { | 1436 | { |
1444 | m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]); | 1437 | m_channel[x, y] = Math.Max((double)args[0], m_channel[x, y]); |
1445 | } | 1438 | } |
@@ -1449,9 +1442,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1449 | private void InterfaceMaxTerrain(Object[] args) | 1442 | private void InterfaceMaxTerrain(Object[] args) |
1450 | { | 1443 | { |
1451 | int x, y; | 1444 | int x, y; |
1452 | for (x = 0; x < m_channel.Width; x++) | 1445 | for(x = 0; x < m_channel.Width; x++) |
1453 | { | 1446 | { |
1454 | for (y = 0; y < m_channel.Height; y++) | 1447 | for(y = 0; y < m_channel.Height; y++) |
1455 | { | 1448 | { |
1456 | m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]); | 1449 | m_channel[x, y] = Math.Min((double)args[0], m_channel[x, y]); |
1457 | } | 1450 | } |
@@ -1480,10 +1473,10 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1480 | double sum = 0; | 1473 | double sum = 0; |
1481 | 1474 | ||
1482 | int x; | 1475 | int x; |
1483 | for (x = 0; x < m_channel.Width; x++) | 1476 | for(x = 0; x < m_channel.Width; x++) |
1484 | { | 1477 | { |
1485 | int y; | 1478 | int y; |
1486 | for (y = 0; y < m_channel.Height; y++) | 1479 | for(y = 0; y < m_channel.Height; y++) |
1487 | { | 1480 | { |
1488 | sum += m_channel[x, y]; | 1481 | sum += m_channel[x, y]; |
1489 | if (max < m_channel[x, y]) | 1482 | if (max < m_channel[x, y]) |
@@ -1501,7 +1494,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1501 | 1494 | ||
1502 | private void InterfaceEnableExperimentalBrushes(Object[] args) | 1495 | private void InterfaceEnableExperimentalBrushes(Object[] args) |
1503 | { | 1496 | { |
1504 | if ((bool) args[0]) | 1497 | if ((bool)args[0]) |
1505 | { | 1498 | { |
1506 | m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere(); | 1499 | m_painteffects[StandardTerrainEffects.Revert] = new WeatherSphere(); |
1507 | m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere(); | 1500 | m_painteffects[StandardTerrainEffects.Flatten] = new OlsenSphere(); |
@@ -1520,7 +1513,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1520 | if (firstArg == "list") | 1513 | if (firstArg == "list") |
1521 | { | 1514 | { |
1522 | MainConsole.Instance.Output("List of loaded plugins"); | 1515 | MainConsole.Instance.Output("List of loaded plugins"); |
1523 | foreach (KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) | 1516 | foreach(KeyValuePair<string, ITerrainEffect> kvp in m_plugineffects) |
1524 | { | 1517 | { |
1525 | MainConsole.Instance.Output(kvp.Key); | 1518 | MainConsole.Instance.Output(kvp.Key); |
1526 | } | 1519 | } |
@@ -1665,46 +1658,65 @@ namespace OpenSim.Region.CoreModules.World.Terrain | |||
1665 | // Add this to our scene so scripts can call these functions | 1658 | // Add this to our scene so scripts can call these functions |
1666 | m_scene.RegisterModuleCommander(m_commander); | 1659 | m_scene.RegisterModuleCommander(m_commander); |
1667 | 1660 | ||
1668 | // Add Feature command to Scene, since Command object requires fixed-length arglists | 1661 | // Add Modify command to Scene, since Command object requires fixed-length arglists |
1669 | m_scene.AddCommand("Terrain", this, "terrain feature", | 1662 | m_scene.AddCommand("Terrain", this, "terrain modify", |
1670 | "terrain feature <type> <parameters...>", "Constructs a feature of the requested type.", FeatureCommand); | 1663 | "terrain modify <operation> <value> [<area>] [<taper>]", |
1664 | "Modifies the terrain as instructed." + | ||
1665 | "\nEach operation can be limited to an area of effect:" + | ||
1666 | "\n * -ell=x,y,rx[,ry] constrains the operation to an ellipse centred at x,y" + | ||
1667 | "\n * -rec=x,y,dx[,dy] constrains the operation to a rectangle based at x,y" + | ||
1668 | "\nEach operation can have its effect tapered based on distance from centre:" + | ||
1669 | "\n * elliptical operations taper as cones" + | ||
1670 | "\n * rectangular operations taper as pyramids" | ||
1671 | , | ||
1672 | ModifyCommand); | ||
1671 | 1673 | ||
1672 | } | 1674 | } |
1673 | 1675 | ||
1674 | public void FeatureCommand(string module, string[] cmd) | 1676 | public void ModifyCommand(string module, string[] cmd) |
1675 | { | 1677 | { |
1676 | string result; | 1678 | string result; |
1677 | if (cmd.Length > 2) | 1679 | Scene scene = SceneManager.Instance.CurrentScene; |
1680 | if ((scene != null) && (scene != m_scene)) | ||
1681 | { | ||
1682 | result = String.Empty; | ||
1683 | } | ||
1684 | else if (cmd.Length > 2) | ||
1678 | { | 1685 | { |
1679 | string featureType = cmd[2]; | 1686 | string operationType = cmd[2]; |
1687 | |||
1680 | 1688 | ||
1681 | ITerrainFeature feature; | 1689 | ITerrainModifier operation; |
1682 | if (!m_featureEffects.TryGetValue(featureType, out feature)) | 1690 | if (!m_modifyOperations.TryGetValue(operationType, out operation)) |
1683 | { | 1691 | { |
1684 | result = String.Format("Terrain Feature \"{0}\" not found.", featureType); | 1692 | result = String.Format("Terrain Modify \"{0}\" not found.", operationType); |
1685 | } | 1693 | } |
1686 | else if ((cmd.Length > 3) && (cmd[3] == "usage")) | 1694 | else if ((cmd.Length > 3) && (cmd[3] == "usage")) |
1687 | { | 1695 | { |
1688 | result = "Usage: " + feature.GetUsage(); | 1696 | result = "Usage: " + operation.GetUsage(); |
1689 | } | 1697 | } |
1690 | else | 1698 | else |
1691 | { | 1699 | { |
1692 | result = feature.CreateFeature(m_channel, cmd); | 1700 | result = operation.ModifyTerrain(m_channel, cmd); |
1693 | } | 1701 | } |
1694 | 1702 | ||
1695 | if(result == String.Empty) | 1703 | if (result == String.Empty) |
1696 | { | 1704 | { |
1697 | result = "Created Feature"; | 1705 | result = "Modified terrain"; |
1698 | m_log.DebugFormat("Created terrain feature {0}", featureType); | 1706 | m_log.DebugFormat("Performed terrain operation {0}", operationType); |
1699 | } | 1707 | } |
1700 | } | 1708 | } |
1701 | else | 1709 | else |
1702 | { | 1710 | { |
1703 | result = "Usage: <feature-name> <arg1> <arg2>..."; | 1711 | result = "Usage: <operation-name> <arg1> <arg2>..."; |
1712 | } | ||
1713 | if (result != String.Empty) | ||
1714 | { | ||
1715 | MainConsole.Instance.Output(result); | ||
1704 | } | 1716 | } |
1705 | MainConsole.Instance.Output(result); | ||
1706 | } | 1717 | } |
1707 | #endregion | 1718 | |
1719 | #endregion | ||
1708 | 1720 | ||
1709 | } | 1721 | } |
1710 | } | 1722 | } |
diff --git a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs index 637387a..e60d3ae 100644 --- a/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/DataSnapshot/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs index fd9ab3d..97dea1f 100644 --- a/OpenSim/Region/Framework/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Framework/Properties/AssemblyInfo.cs | |||
@@ -31,6 +31,6 @@ using Mono.Addins; | |||
31 | // Build Number | 31 | // Build Number |
32 | // Revision | 32 | // Revision |
33 | // | 33 | // |
34 | [assembly: AssemblyVersion("0.8.1.*")] | 34 | [assembly: AssemblyVersion("0.8.2.*")] |
35 | [assembly: AddinRoot("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: AddinRoot("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] |
36 | 36 | ||
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 31900ec..905bde2 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1653,7 +1653,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1653 | 1653 | ||
1654 | // These variables will be used to save the precise frame time using the | 1654 | // These variables will be used to save the precise frame time using the |
1655 | // Stopwatch class of Microsoft SDK; the times are recorded at the start | 1655 | // Stopwatch class of Microsoft SDK; the times are recorded at the start |
1656 | // and end of a parcticular section of code, and then used to calculate | 1656 | // and end of a particular section of code, and then used to calculate |
1657 | // the frame times, which are the sums of the sections for each given name | 1657 | // the frame times, which are the sums of the sections for each given name |
1658 | double preciseTotalFrameTime = 0.0; | 1658 | double preciseTotalFrameTime = 0.0; |
1659 | double preciseSimFrameTime = 0.0; | 1659 | double preciseSimFrameTime = 0.0; |
@@ -1698,7 +1698,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1698 | // input took | 1698 | // input took |
1699 | simFrameStopwatch.Stop(); | 1699 | simFrameStopwatch.Stop(); |
1700 | preciseSimFrameTime = | 1700 | preciseSimFrameTime = |
1701 | simFrameStopwatch.Elapsed.TotalMilliseconds; | 1701 | simFrameStopwatch.Elapsed.TotalMilliseconds; |
1702 | terrainMS = Util.EnvironmentTickCountSubtract(tmpMS); | 1702 | terrainMS = Util.EnvironmentTickCountSubtract(tmpMS); |
1703 | } | 1703 | } |
1704 | 1704 | ||
@@ -1717,7 +1717,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1717 | // Begin the stopwatch to track the time to prepare physics | 1717 | // Begin the stopwatch to track the time to prepare physics |
1718 | physicsFrameStopwatch.Start(); | 1718 | physicsFrameStopwatch.Start(); |
1719 | if (PhysicsEnabled && Frame % m_update_physics == 0) | 1719 | if (PhysicsEnabled && Frame % m_update_physics == 0) |
1720 | m_sceneGraph.UpdatePreparePhysics(); | 1720 | m_sceneGraph.UpdatePreparePhysics(); |
1721 | 1721 | ||
1722 | // Get the time it took to prepare the physics, this | 1722 | // Get the time it took to prepare the physics, this |
1723 | // would report the most precise time that physics was | 1723 | // would report the most precise time that physics was |
@@ -1738,7 +1738,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1738 | // took | 1738 | // took |
1739 | simFrameStopwatch.Stop(); | 1739 | simFrameStopwatch.Stop(); |
1740 | preciseSimFrameTime += | 1740 | preciseSimFrameTime += |
1741 | simFrameStopwatch.Elapsed.TotalMilliseconds; | 1741 | simFrameStopwatch.Elapsed.TotalMilliseconds; |
1742 | agentMS = Util.EnvironmentTickCountSubtract(tmpMS); | 1742 | agentMS = Util.EnvironmentTickCountSubtract(tmpMS); |
1743 | 1743 | ||
1744 | // Perform the main physics update. This will do the actual work of moving objects and avatars according to their | 1744 | // Perform the main physics update. This will do the actual work of moving objects and avatars according to their |
@@ -1851,7 +1851,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1851 | // Get the elapsed time for the simulation frame | 1851 | // Get the elapsed time for the simulation frame |
1852 | simFrameStopwatch.Stop(); | 1852 | simFrameStopwatch.Stop(); |
1853 | preciseSimFrameTime += | 1853 | preciseSimFrameTime += |
1854 | simFrameStopwatch.Elapsed.TotalMilliseconds; | 1854 | simFrameStopwatch.Elapsed.TotalMilliseconds; |
1855 | 1855 | ||
1856 | if (!UpdateOnTimer) | 1856 | if (!UpdateOnTimer) |
1857 | { | 1857 | { |
@@ -1872,7 +1872,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1872 | // Get the total frame time | 1872 | // Get the total frame time |
1873 | totalFrameStopwatch.Stop(); | 1873 | totalFrameStopwatch.Stop(); |
1874 | preciseTotalFrameTime = | 1874 | preciseTotalFrameTime = |
1875 | totalFrameStopwatch.Elapsed.TotalMilliseconds; | 1875 | totalFrameStopwatch.Elapsed.TotalMilliseconds; |
1876 | 1876 | ||
1877 | // Restart the stopwatch for the total time of the next frame | 1877 | // Restart the stopwatch for the total time of the next frame |
1878 | totalFrameStopwatch.Restart(); | 1878 | totalFrameStopwatch.Restart(); |
@@ -1897,7 +1897,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1897 | // Send the correct time values to the stats reporter for the | 1897 | // Send the correct time values to the stats reporter for the |
1898 | // frame times | 1898 | // frame times |
1899 | StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime, | 1899 | StatsReporter.addFrameTimeMilliseconds(preciseTotalFrameTime, |
1900 | preciseSimFrameTime, precisePhysicsFrameTime, 0.0); | 1900 | preciseSimFrameTime, precisePhysicsFrameTime, 0.0); |
1901 | 1901 | ||
1902 | // Send the correct number of frames that the physics library | 1902 | // Send the correct number of frames that the physics library |
1903 | // has processed to the stats reporter | 1903 | // has processed to the stats reporter |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0a1a226..866a43c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -2672,20 +2672,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
2672 | } | 2672 | } |
2673 | else | 2673 | else |
2674 | { | 2674 | { |
2675 | //NonPhysicalGrabMovement(pos); | 2675 | NonPhysicalGrabMovement(pos); |
2676 | } | 2676 | } |
2677 | } | 2677 | } |
2678 | else | 2678 | else |
2679 | { | 2679 | { |
2680 | //NonPhysicalGrabMovement(pos); | 2680 | NonPhysicalGrabMovement(pos); |
2681 | } | 2681 | } |
2682 | } | 2682 | } |
2683 | } | 2683 | } |
2684 | 2684 | ||
2685 | /// <summary> | ||
2686 | /// Apply possition for grabbing non-physical linksets (Ctrl+Drag) | ||
2687 | /// This MUST be blocked for linksets that contain touch scripts because the viewer triggers grab on the touch | ||
2688 | /// event (Viewer Bug?) This would allow anyone to drag a linkset with a touch script. SL behaviour is also to | ||
2689 | /// block grab on prims with touch events. | ||
2690 | /// </summary> | ||
2691 | /// <param name="pos">New Position</param> | ||
2685 | public void NonPhysicalGrabMovement(Vector3 pos) | 2692 | public void NonPhysicalGrabMovement(Vector3 pos) |
2686 | { | 2693 | { |
2687 | AbsolutePosition = pos; | 2694 | if(!IsAttachment && ScriptCount() == 0) |
2688 | m_rootPart.SendTerseUpdateToAllClients(); | 2695 | UpdateGroupPosition(pos); |
2689 | } | 2696 | } |
2690 | 2697 | ||
2691 | /// <summary> | 2698 | /// <summary> |
@@ -2781,17 +2788,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
2781 | } | 2788 | } |
2782 | else | 2789 | else |
2783 | { | 2790 | { |
2784 | //NonPhysicalSpinMovement(pos); | 2791 | NonPhysicalSpinMovement(newOrientation); |
2785 | } | 2792 | } |
2786 | } | 2793 | } |
2787 | else | 2794 | else |
2788 | { | 2795 | { |
2789 | //NonPhysicalSpinMovement(pos); | 2796 | NonPhysicalSpinMovement(newOrientation); |
2790 | } | 2797 | } |
2791 | } | 2798 | } |
2792 | } | 2799 | } |
2793 | 2800 | ||
2794 | /// <summary> | 2801 | /// <summary> |
2802 | /// Apply rotation for spinning non-physical linksets (Ctrl+Shift+Drag) | ||
2803 | /// As with dragging, scripted objects must be blocked from spinning | ||
2804 | /// </summary> | ||
2805 | /// <param name="newOrientation">New Rotation</param> | ||
2806 | private void NonPhysicalSpinMovement(Quaternion newOrientation) | ||
2807 | { | ||
2808 | if(!IsAttachment && ScriptCount() == 0) | ||
2809 | UpdateGroupRotationR(newOrientation); | ||
2810 | } | ||
2811 | |||
2812 | /// <summary> | ||
2795 | /// Set the name of a prim | 2813 | /// Set the name of a prim |
2796 | /// </summary> | 2814 | /// </summary> |
2797 | /// <param name="name"></param> | 2815 | /// <param name="name"></param> |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSerializationTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSerializationTests.cs new file mode 100644 index 0000000..927d8e8 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectSerializationTests.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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Threading; | ||
32 | using System.Xml; | ||
33 | using System.Linq; | ||
34 | using Nini.Config; | ||
35 | using NUnit.Framework; | ||
36 | using OpenMetaverse; | ||
37 | using OpenSim.Framework; | ||
38 | using OpenSim.Framework.Serialization.External; | ||
39 | using OpenSim.Framework.Communications; | ||
40 | using OpenSim.Region.Framework.Scenes; | ||
41 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
42 | using OpenSim.Services.Interfaces; | ||
43 | using OpenSim.Tests.Common; | ||
44 | |||
45 | namespace OpenSim.Region.Framework.Scenes.Tests | ||
46 | { | ||
47 | /// <summary> | ||
48 | /// Basic scene object serialization tests. | ||
49 | /// </summary> | ||
50 | [TestFixture] | ||
51 | public class SceneObjectSerializationTests : OpenSimTestCase | ||
52 | { | ||
53 | |||
54 | /// <summary> | ||
55 | /// Serialize and deserialize. | ||
56 | /// </summary> | ||
57 | [Test] | ||
58 | public void TestSerialDeserial() | ||
59 | { | ||
60 | TestHelpers.InMethod(); | ||
61 | |||
62 | Scene scene = new SceneHelpers().SetupScene(); | ||
63 | int partsToTestCount = 3; | ||
64 | |||
65 | SceneObjectGroup so | ||
66 | = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10); | ||
67 | SceneObjectPart[] parts = so.Parts; | ||
68 | so.Name = "obj1"; | ||
69 | so.Description = "xpto"; | ||
70 | |||
71 | string xml = SceneObjectSerializer.ToXml2Format(so); | ||
72 | Assert.That(!string.IsNullOrEmpty(xml), "SOG serialization resulted in empty or null string"); | ||
73 | |||
74 | XmlDocument doc = new XmlDocument(); | ||
75 | doc.LoadXml(xml); | ||
76 | XmlNodeList nodes = doc.GetElementsByTagName("SceneObjectPart"); | ||
77 | Assert.That(nodes.Count, Is.EqualTo(3), "SOG serialization resulted in wrong number of SOPs"); | ||
78 | |||
79 | SceneObjectGroup so2 = SceneObjectSerializer.FromXml2Format(xml); | ||
80 | Assert.IsNotNull(so2, "SOG deserialization resulted in null object"); | ||
81 | Assert.That(so2.Name == so.Name, "Name of deserialized object does not match original name"); | ||
82 | Assert.That(so2.Description == so.Description, "Description of deserialized object does not match original name"); | ||
83 | } | ||
84 | |||
85 | /// <summary> | ||
86 | /// This checks for a bug reported in mantis #7514 | ||
87 | /// </summary> | ||
88 | [Test] | ||
89 | public void TestNamespaceAttribute() | ||
90 | { | ||
91 | TestHelpers.InMethod(); | ||
92 | |||
93 | Scene scene = new SceneHelpers().SetupScene(); | ||
94 | UserAccount account = new UserAccount(UUID.Zero, UUID.Random(), "Test", "User", string.Empty); | ||
95 | scene.UserAccountService.StoreUserAccount(account); | ||
96 | int partsToTestCount = 1; | ||
97 | |||
98 | SceneObjectGroup so | ||
99 | = SceneHelpers.CreateSceneObject(partsToTestCount, TestHelpers.ParseTail(0x1), "obj1", 0x10); | ||
100 | SceneObjectPart[] parts = so.Parts; | ||
101 | so.Name = "obj1"; | ||
102 | so.Description = "xpto"; | ||
103 | so.OwnerID = account.PrincipalID; | ||
104 | so.RootPart.CreatorID = so.OwnerID; | ||
105 | |||
106 | string xml = SceneObjectSerializer.ToXml2Format(so); | ||
107 | Assert.That(!string.IsNullOrEmpty(xml), "SOG serialization resulted in empty or null string"); | ||
108 | |||
109 | xml = ExternalRepresentationUtils.RewriteSOP(xml, "Test Scene", "http://localhost", scene.UserAccountService, UUID.Zero); | ||
110 | //Console.WriteLine(xml); | ||
111 | |||
112 | XmlDocument doc = new XmlDocument(); | ||
113 | doc.LoadXml(xml); | ||
114 | |||
115 | XmlNodeList nodes = doc.GetElementsByTagName("SceneObjectPart"); | ||
116 | Assert.That(nodes.Count, Is.GreaterThan(0), "SOG serialization resulted in no SOPs"); | ||
117 | foreach (XmlAttribute a in nodes[0].Attributes) | ||
118 | { | ||
119 | int count = a.Name.Count(c => c == ':'); | ||
120 | Assert.That(count, Is.EqualTo(1), "Cannot have multiple ':' in attribute name in SOP"); | ||
121 | } | ||
122 | nodes = doc.GetElementsByTagName("CreatorData"); | ||
123 | Assert.That(nodes.Count, Is.GreaterThan(0), "SOG serialization resulted in no CreatorData"); | ||
124 | foreach (XmlAttribute a in nodes[0].Attributes) | ||
125 | { | ||
126 | int count = a.Name.Count(c => c == ':'); | ||
127 | Assert.That(count, Is.EqualTo(1), "Cannot have multiple ':' in attribute name in CreatorData"); | ||
128 | } | ||
129 | |||
130 | SceneObjectGroup so2 = SceneObjectSerializer.FromXml2Format(xml); | ||
131 | Assert.IsNotNull(so2, "SOG deserialization resulted in null object"); | ||
132 | Assert.AreNotEqual(so.RootPart.CreatorIdentification, so2.RootPart.CreatorIdentification, "RewriteSOP failed to transform CreatorData."); | ||
133 | Assert.That(so2.RootPart.CreatorIdentification.Contains("http://"), "RewriteSOP failed to add the homeURL to CreatorData"); | ||
134 | } | ||
135 | } | ||
136 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs index d028374..f8ad958 100644 --- a/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/OptionalModules/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | 35 | ||
36 | [assembly: Addin("OpenSim.Region.OptionalModules", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: Addin("OpenSim.Region.OptionalModules", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs index 28dc5f5..ceb3332 100644 --- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs +++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModule.cs | |||
@@ -115,6 +115,9 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup | |||
115 | 115 | ||
116 | private delegate T DefaultGetter<T>(string settingName, T defaultValue); | 116 | private delegate T DefaultGetter<T>(string settingName, T defaultValue); |
117 | private bool m_enabled; | 117 | private bool m_enabled; |
118 | private ICommandConsole m_console; | ||
119 | private List<Scene> m_Scenes = new List<Scene> (); | ||
120 | |||
118 | 121 | ||
119 | /// <summary> | 122 | /// <summary> |
120 | /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState! | 123 | /// Whether the shared module should be enabled at all. NOT the same as m_Enabled in AutoBackupModuleState! |
@@ -206,8 +209,20 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup | |||
206 | /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded. | 209 | /// Currently a no-op for AutoBackup because we have to wait for region to be fully loaded. |
207 | /// </summary> | 210 | /// </summary> |
208 | /// <param name="scene"></param> | 211 | /// <param name="scene"></param> |
209 | void IRegionModuleBase.AddRegion(Scene scene) | 212 | void IRegionModuleBase.AddRegion (Scene scene) |
210 | { | 213 | { |
214 | if (!this.m_enabled) { | ||
215 | return; | ||
216 | } | ||
217 | lock (m_Scenes) { | ||
218 | m_Scenes.Add (scene); | ||
219 | } | ||
220 | m_console = MainConsole.Instance; | ||
221 | |||
222 | m_console.Commands.AddCommand ( | ||
223 | "AutoBackup", false, "dobackup", | ||
224 | "dobackup", | ||
225 | "do backup.", DoBackup); | ||
211 | } | 226 | } |
212 | 227 | ||
213 | /// <summary> | 228 | /// <summary> |
@@ -220,7 +235,7 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup | |||
220 | { | 235 | { |
221 | return; | 236 | return; |
222 | } | 237 | } |
223 | 238 | m_Scenes.Remove (scene); | |
224 | if (this.m_states.ContainsKey(scene)) | 239 | if (this.m_states.ContainsKey(scene)) |
225 | { | 240 | { |
226 | AutoBackupModuleState abms = this.m_states[scene]; | 241 | AutoBackupModuleState abms = this.m_states[scene]; |
@@ -275,6 +290,28 @@ namespace OpenSim.Region.OptionalModules.World.AutoBackup | |||
275 | 290 | ||
276 | #endregion | 291 | #endregion |
277 | 292 | ||
293 | private void DoBackup (string module, string[] args) | ||
294 | { | ||
295 | if (args.Length != 2) { | ||
296 | MainConsole.Instance.OutputFormat ("Usage: dobackup <regionname>"); | ||
297 | return; | ||
298 | } | ||
299 | bool found = false; | ||
300 | string name = args [1]; | ||
301 | lock (m_Scenes) { | ||
302 | foreach (Scene s in m_Scenes) { | ||
303 | string test = s.Name.ToString (); | ||
304 | if (test == name) { | ||
305 | found = true; | ||
306 | DoRegionBackup (s); | ||
307 | } | ||
308 | } | ||
309 | if (!found) { | ||
310 | MainConsole.Instance.OutputFormat ("No such region {0}. Nothing to backup", name); | ||
311 | } | ||
312 | } | ||
313 | } | ||
314 | |||
278 | /// <summary> | 315 | /// <summary> |
279 | /// Set up internal state for a given scene. Fairly complex code. | 316 | /// Set up internal state for a given scene. Fairly complex code. |
280 | /// When this method returns, we've started auto-backup timers, put members in Dictionaries, and created a State object for this scene. | 317 | /// When this method returns, we've started auto-backup timers, put members in Dictionaries, and created a State object for this scene. |
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs index eba0675..7d054dd 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs | |||
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices; | |||
55 | // You can specify all values by your own or you can build default build and revision | 55 | // You can specify all values by your own or you can build default build and revision |
56 | // numbers with the '*' character (the default): | 56 | // numbers with the '*' character (the default): |
57 | 57 | ||
58 | [assembly : AssemblyVersion("0.8.1.*")] | 58 | [assembly : AssemblyVersion("0.8.2.*")] |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs index 4de5b47..4f90eee 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs index 1486ba8..c5867b2 100644 --- a/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/ConvexDecompositionDotNet/Properties/AssemblyInfo.cs | |||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices; | |||
32 | // You can specify all the values or you can default the Build and Revision Numbers | 32 | // You can specify all the values or you can default the Build and Revision Numbers |
33 | // by using the '*' as shown below: | 33 | // by using the '*' as shown below: |
34 | // [assembly: AssemblyVersion("1.0.*")] | 34 | // [assembly: AssemblyVersion("1.0.*")] |
35 | [assembly: AssemblyVersion("0.8.1.*")] | 35 | [assembly: AssemblyVersion("0.8.2.*")] |
36 | 36 | ||
diff --git a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs index 202ef20..33f60e4 100644 --- a/OpenSim/Region/Physics/Manager/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Manager/AssemblyInfo.cs | |||
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices; | |||
55 | // You can specify all values by your own or you can build default build and revision | 55 | // You can specify all values by your own or you can build default build and revision |
56 | // numbers with the '*' character (the default): | 56 | // numbers with the '*' character (the default): |
57 | 57 | ||
58 | [assembly : AssemblyVersion("0.8.1.*")] | 58 | [assembly : AssemblyVersion("0.8.2.*")] |
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index d96de4a..42231b5 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -84,7 +84,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
84 | private List<List<Vector3>> mConvexHulls = null; | 84 | private List<List<Vector3>> mConvexHulls = null; |
85 | private List<Vector3> mBoundingHull = null; | 85 | private List<Vector3> mBoundingHull = null; |
86 | 86 | ||
87 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); | 87 | // Mesh cache. Static so it can be shared across instances of this class |
88 | private static Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); | ||
88 | 89 | ||
89 | public Meshmerizer(IConfigSource config) | 90 | public Meshmerizer(IConfigSource config) |
90 | { | 91 | { |
@@ -927,8 +928,11 @@ namespace OpenSim.Region.Physics.Meshing | |||
927 | if (shouldCache) | 928 | if (shouldCache) |
928 | { | 929 | { |
929 | key = primShape.GetMeshKey(size, lod); | 930 | key = primShape.GetMeshKey(size, lod); |
930 | if (m_uniqueMeshes.TryGetValue(key, out mesh)) | 931 | lock (m_uniqueMeshes) |
931 | return mesh; | 932 | { |
933 | if (m_uniqueMeshes.TryGetValue(key, out mesh)) | ||
934 | return mesh; | ||
935 | } | ||
932 | } | 936 | } |
933 | 937 | ||
934 | if (size.X < 0.01f) size.X = 0.01f; | 938 | if (size.X < 0.01f) size.X = 0.01f; |
@@ -954,7 +958,10 @@ namespace OpenSim.Region.Physics.Meshing | |||
954 | 958 | ||
955 | if (shouldCache) | 959 | if (shouldCache) |
956 | { | 960 | { |
957 | m_uniqueMeshes.Add(key, mesh); | 961 | lock (m_uniqueMeshes) |
962 | { | ||
963 | m_uniqueMeshes.Add(key, mesh); | ||
964 | } | ||
958 | } | 965 | } |
959 | } | 966 | } |
960 | 967 | ||
diff --git a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs index 2b083fe..ec968c0 100644 --- a/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/Meshing/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs index b95f7f4..076da78 100644 --- a/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/OdePlugin/AssemblyInfo.cs | |||
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices; | |||
55 | // You can specify all values by your own or you can build default build and revision | 55 | // You can specify all values by your own or you can build default build and revision |
56 | // numbers with the '*' character (the default): | 56 | // numbers with the '*' character (the default): |
57 | 57 | ||
58 | [assembly : AssemblyVersion("0.8.1.*")] | 58 | [assembly : AssemblyVersion("0.8.2.*")] |
diff --git a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs index 125d38a..fc1ffba 100644 --- a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs +++ b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs | |||
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices; | |||
55 | // You can specify all values by your own or you can build default build and revision | 55 | // You can specify all values by your own or you can build default build and revision |
56 | // numbers with the '*' character (the default): | 56 | // numbers with the '*' character (the default): |
57 | 57 | ||
58 | [assembly : AssemblyVersion("0.8.1.*")] | 58 | [assembly : AssemblyVersion("0.8.2.*")] |
diff --git a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs index e8b29f9..11b89d2 100644 --- a/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/RegionCombinerModule/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | [assembly: Addin("OpenSim.RegionModules.RegionCombinerModule", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: Addin("OpenSim.RegionModules.RegionCombinerModule", OpenSim.VersionInfo.VersionNumber)] |
36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 40b7c35..089a5a8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -28,6 +28,8 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Drawing; | ||
32 | using System.Drawing.Imaging; | ||
31 | using System.Runtime.Remoting.Lifetime; | 33 | using System.Runtime.Remoting.Lifetime; |
32 | using System.Text; | 34 | using System.Text; |
33 | using System.Threading; | 35 | using System.Threading; |
@@ -35,7 +37,9 @@ using System.Text.RegularExpressions; | |||
35 | using Nini.Config; | 37 | using Nini.Config; |
36 | using log4net; | 38 | using log4net; |
37 | using OpenMetaverse; | 39 | using OpenMetaverse; |
40 | using OpenMetaverse.Assets; | ||
38 | using OpenMetaverse.Packets; | 41 | using OpenMetaverse.Packets; |
42 | using OpenMetaverse.Rendering; | ||
39 | using OpenSim; | 43 | using OpenSim; |
40 | using OpenSim.Framework; | 44 | using OpenSim.Framework; |
41 | 45 | ||
@@ -182,6 +186,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
182 | protected bool m_restrictEmail = false; | 186 | protected bool m_restrictEmail = false; |
183 | protected ISoundModule m_SoundModule = null; | 187 | protected ISoundModule m_SoundModule = null; |
184 | 188 | ||
189 | protected float m_avatarHeightCorrection = 0.2f; | ||
190 | protected bool m_useSimpleBoxesInGetBoundingBox = false; | ||
191 | protected bool m_addStatsInGetBoundingBox = false; | ||
192 | |||
193 | //LSL Avatar Bounding Box (lABB), lower (1) and upper (2), | ||
194 | //standing (Std), Groundsitting (Grs), Sitting (Sit), | ||
195 | //along X, Y and Z axes, constants (0) and coefficients (1) | ||
196 | protected float m_lABB1StdX0 = -0.275f; | ||
197 | protected float m_lABB2StdX0 = 0.275f; | ||
198 | protected float m_lABB1StdY0 = -0.35f; | ||
199 | protected float m_lABB2StdY0 = 0.35f; | ||
200 | protected float m_lABB1StdZ0 = -0.1f; | ||
201 | protected float m_lABB1StdZ1 = -0.5f; | ||
202 | protected float m_lABB2StdZ0 = 0.1f; | ||
203 | protected float m_lABB2StdZ1 = 0.5f; | ||
204 | protected float m_lABB1GrsX0 = -0.3875f; | ||
205 | protected float m_lABB2GrsX0 = 0.3875f; | ||
206 | protected float m_lABB1GrsY0 = -0.5f; | ||
207 | protected float m_lABB2GrsY0 = 0.5f; | ||
208 | protected float m_lABB1GrsZ0 = -0.05f; | ||
209 | protected float m_lABB1GrsZ1 = -0.375f; | ||
210 | protected float m_lABB2GrsZ0 = 0.5f; | ||
211 | protected float m_lABB2GrsZ1 = 0.0f; | ||
212 | protected float m_lABB1SitX0 = -0.5875f; | ||
213 | protected float m_lABB2SitX0 = 0.1875f; | ||
214 | protected float m_lABB1SitY0 = -0.35f; | ||
215 | protected float m_lABB2SitY0 = 0.35f; | ||
216 | protected float m_lABB1SitZ0 = -0.35f; | ||
217 | protected float m_lABB1SitZ1 = -0.375f; | ||
218 | protected float m_lABB2SitZ0 = -0.25f; | ||
219 | protected float m_lABB2SitZ1 = 0.25f; | ||
220 | |||
221 | protected float m_primSafetyCoeffX = 2.414214f; | ||
222 | protected float m_primSafetyCoeffY = 2.414214f; | ||
223 | protected float m_primSafetyCoeffZ = 1.618034f; | ||
224 | protected bool m_useCastRayV3 = false; | ||
225 | protected float m_floatToleranceInCastRay = 0.000001f; | ||
226 | protected float m_floatTolerance2InCastRay = 0.0001f; | ||
227 | protected DetailLevel m_primLodInCastRay = DetailLevel.Medium; | ||
228 | protected DetailLevel m_sculptLodInCastRay = DetailLevel.Medium; | ||
229 | protected DetailLevel m_meshLodInCastRay = DetailLevel.Highest; | ||
230 | protected DetailLevel m_avatarLodInCastRay = DetailLevel.Medium; | ||
231 | protected int m_maxHitsInCastRay = 16; | ||
232 | protected int m_maxHitsPerPrimInCastRay = 16; | ||
233 | protected int m_maxHitsPerObjectInCastRay = 16; | ||
234 | protected bool m_detectExitsInCastRay = false; | ||
235 | protected bool m_filterPartsInCastRay = false; | ||
236 | protected bool m_doAttachmentsInCastRay = false; | ||
237 | |||
185 | //An array of HTTP/1.1 headers that are not allowed to be used | 238 | //An array of HTTP/1.1 headers that are not allowed to be used |
186 | //as custom headers by llHTTPRequest. | 239 | //as custom headers by llHTTPRequest. |
187 | private string[] HttpStandardHeaders = | 240 | private string[] HttpStandardHeaders = |
@@ -257,6 +310,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
257 | if (lslConfig != null) | 310 | if (lslConfig != null) |
258 | { | 311 | { |
259 | m_restrictEmail = lslConfig.GetBoolean("RestrictEmail", m_restrictEmail); | 312 | m_restrictEmail = lslConfig.GetBoolean("RestrictEmail", m_restrictEmail); |
313 | m_avatarHeightCorrection = lslConfig.GetFloat("AvatarHeightCorrection", m_avatarHeightCorrection); | ||
314 | m_useSimpleBoxesInGetBoundingBox = lslConfig.GetBoolean("UseSimpleBoxesInGetBoundingBox", m_useSimpleBoxesInGetBoundingBox); | ||
315 | m_addStatsInGetBoundingBox = lslConfig.GetBoolean("AddStatsInGetBoundingBox", m_addStatsInGetBoundingBox); | ||
316 | m_lABB1StdX0 = lslConfig.GetFloat("LowerAvatarBoundingBoxStandingXconst", m_lABB1StdX0); | ||
317 | m_lABB2StdX0 = lslConfig.GetFloat("UpperAvatarBoundingBoxStandingXconst", m_lABB2StdX0); | ||
318 | m_lABB1StdY0 = lslConfig.GetFloat("LowerAvatarBoundingBoxStandingYconst", m_lABB1StdY0); | ||
319 | m_lABB2StdY0 = lslConfig.GetFloat("UpperAvatarBoundingBoxStandingYconst", m_lABB2StdY0); | ||
320 | m_lABB1StdZ0 = lslConfig.GetFloat("LowerAvatarBoundingBoxStandingZconst", m_lABB1StdZ0); | ||
321 | m_lABB1StdZ1 = lslConfig.GetFloat("LowerAvatarBoundingBoxStandingZcoeff", m_lABB1StdZ1); | ||
322 | m_lABB2StdZ0 = lslConfig.GetFloat("UpperAvatarBoundingBoxStandingZconst", m_lABB2StdZ0); | ||
323 | m_lABB2StdZ1 = lslConfig.GetFloat("UpperAvatarBoundingBoxStandingZcoeff", m_lABB2StdZ1); | ||
324 | m_lABB1GrsX0 = lslConfig.GetFloat("LowerAvatarBoundingBoxGroundsittingXconst", m_lABB1GrsX0); | ||
325 | m_lABB2GrsX0 = lslConfig.GetFloat("UpperAvatarBoundingBoxGroundsittingXconst", m_lABB2GrsX0); | ||
326 | m_lABB1GrsY0 = lslConfig.GetFloat("LowerAvatarBoundingBoxGroundsittingYconst", m_lABB1GrsY0); | ||
327 | m_lABB2GrsY0 = lslConfig.GetFloat("UpperAvatarBoundingBoxGroundsittingYconst", m_lABB2GrsY0); | ||
328 | m_lABB1GrsZ0 = lslConfig.GetFloat("LowerAvatarBoundingBoxGroundsittingZconst", m_lABB1GrsZ0); | ||
329 | m_lABB1GrsZ1 = lslConfig.GetFloat("LowerAvatarBoundingBoxGroundsittingZcoeff", m_lABB1GrsZ1); | ||
330 | m_lABB2GrsZ0 = lslConfig.GetFloat("UpperAvatarBoundingBoxGroundsittingZconst", m_lABB2GrsZ0); | ||
331 | m_lABB2GrsZ1 = lslConfig.GetFloat("UpperAvatarBoundingBoxGroundsittingZcoeff", m_lABB2GrsZ1); | ||
332 | m_lABB1SitX0 = lslConfig.GetFloat("LowerAvatarBoundingBoxSittingXconst", m_lABB1SitX0); | ||
333 | m_lABB2SitX0 = lslConfig.GetFloat("UpperAvatarBoundingBoxSittingXconst", m_lABB2SitX0); | ||
334 | m_lABB1SitY0 = lslConfig.GetFloat("LowerAvatarBoundingBoxSittingYconst", m_lABB1SitY0); | ||
335 | m_lABB2SitY0 = lslConfig.GetFloat("UpperAvatarBoundingBoxSittingYconst", m_lABB2SitY0); | ||
336 | m_lABB1SitZ0 = lslConfig.GetFloat("LowerAvatarBoundingBoxSittingZconst", m_lABB1SitZ0); | ||
337 | m_lABB1SitZ1 = lslConfig.GetFloat("LowerAvatarBoundingBoxSittingZcoeff", m_lABB1SitZ1); | ||
338 | m_lABB2SitZ0 = lslConfig.GetFloat("UpperAvatarBoundingBoxSittingZconst", m_lABB2SitZ0); | ||
339 | m_lABB2SitZ1 = lslConfig.GetFloat("UpperAvatarBoundingBoxSittingZcoeff", m_lABB2SitZ1); | ||
340 | m_primSafetyCoeffX = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientX", m_primSafetyCoeffX); | ||
341 | m_primSafetyCoeffY = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientY", m_primSafetyCoeffY); | ||
342 | m_primSafetyCoeffZ = lslConfig.GetFloat("PrimBoundingBoxSafetyCoefficientZ", m_primSafetyCoeffZ); | ||
343 | m_useCastRayV3 = lslConfig.GetBoolean("UseLlCastRayV3", m_useCastRayV3); | ||
344 | m_floatToleranceInCastRay = lslConfig.GetFloat("FloatToleranceInLlCastRay", m_floatToleranceInCastRay); | ||
345 | m_floatTolerance2InCastRay = lslConfig.GetFloat("FloatTolerance2InLlCastRay", m_floatTolerance2InCastRay); | ||
346 | m_primLodInCastRay = (DetailLevel)lslConfig.GetInt("PrimDetailLevelInLlCastRay", (int)m_primLodInCastRay); | ||
347 | m_sculptLodInCastRay = (DetailLevel)lslConfig.GetInt("SculptDetailLevelInLlCastRay", (int)m_sculptLodInCastRay); | ||
348 | m_meshLodInCastRay = (DetailLevel)lslConfig.GetInt("MeshDetailLevelInLlCastRay", (int)m_meshLodInCastRay); | ||
349 | m_avatarLodInCastRay = (DetailLevel)lslConfig.GetInt("AvatarDetailLevelInLlCastRay", (int)m_avatarLodInCastRay); | ||
350 | m_maxHitsInCastRay = lslConfig.GetInt("MaxHitsInLlCastRay", m_maxHitsInCastRay); | ||
351 | m_maxHitsPerPrimInCastRay = lslConfig.GetInt("MaxHitsPerPrimInLlCastRay", m_maxHitsPerPrimInCastRay); | ||
352 | m_maxHitsPerObjectInCastRay = lslConfig.GetInt("MaxHitsPerObjectInLlCastRay", m_maxHitsPerObjectInCastRay); | ||
353 | m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay); | ||
354 | m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay); | ||
355 | m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay); | ||
260 | } | 356 | } |
261 | 357 | ||
262 | IConfig smtpConfig = seConfigSource.Configs["SMTP"]; | 358 | IConfig smtpConfig = seConfigSource.Configs["SMTP"]; |
@@ -7725,13 +7821,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7725 | { | 7821 | { |
7726 | profilecut.y = 1f; | 7822 | profilecut.y = 1f; |
7727 | } | 7823 | } |
7728 | if (profilecut.y - profilecut.x < 0.05f) | 7824 | if (profilecut.y - profilecut.x < 0.02f) |
7729 | { | 7825 | { |
7730 | profilecut.x = profilecut.y - 0.05f; | 7826 | profilecut.x = profilecut.y - 0.02f; |
7731 | if (profilecut.x < 0.0f) | 7827 | if (profilecut.x < 0.0f) |
7732 | { | 7828 | { |
7733 | profilecut.x = 0.0f; | 7829 | profilecut.x = 0.0f; |
7734 | profilecut.y = 0.05f; | 7830 | profilecut.y = 0.02f; |
7735 | } | 7831 | } |
7736 | } | 7832 | } |
7737 | shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x); | 7833 | shapeBlock.ProfileBegin = (ushort)(50000 * profilecut.x); |
@@ -9584,80 +9680,441 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9584 | } | 9680 | } |
9585 | 9681 | ||
9586 | /// <summary> | 9682 | /// <summary> |
9587 | /// A partial implementation. | 9683 | /// Full implementation of llGetBoundingBox according to SL 2015-04-15. |
9684 | /// http://wiki.secondlife.com/wiki/LlGetBoundingBox | ||
9588 | /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetBoundingBox | 9685 | /// http://lslwiki.net/lslwiki/wakka.php?wakka=llGetBoundingBox |
9589 | /// So far only valid for standing/flying/ground sitting avatars and single prim objects. | 9686 | /// Returns local bounding box of avatar without attachments |
9590 | /// If the object has multiple prims and/or a sitting avatar then the bounding | 9687 | /// if target is non-seated avatar or prim/mesh in avatar attachment. |
9591 | /// box is for the root prim only. | 9688 | /// Returns local bounding box of object including seated avatars |
9689 | /// if target is seated avatar or prim/mesh in object. | ||
9690 | /// Uses meshing of prims for high accuracy | ||
9691 | /// or less accurate box models for speed. | ||
9592 | /// </summary> | 9692 | /// </summary> |
9593 | public LSL_List llGetBoundingBox(string obj) | 9693 | public LSL_List llGetBoundingBox(string obj) |
9594 | { | 9694 | { |
9595 | m_host.AddScriptLPS(1); | 9695 | m_host.AddScriptLPS(1); |
9696 | |||
9697 | // Get target avatar if non-seated avatar or attachment, or prim and object | ||
9596 | UUID objID = UUID.Zero; | 9698 | UUID objID = UUID.Zero; |
9699 | UUID.TryParse(obj, out objID); | ||
9700 | ScenePresence agent = World.GetScenePresence(objID); | ||
9701 | if (agent != null) | ||
9702 | { | ||
9703 | if (agent.ParentPart != null) | ||
9704 | { | ||
9705 | objID = agent.ParentPart.UUID; | ||
9706 | agent = null; | ||
9707 | } | ||
9708 | } | ||
9709 | SceneObjectGroup group = null; | ||
9710 | SceneObjectPart target = World.GetSceneObjectPart(objID); | ||
9711 | if (target != null) | ||
9712 | { | ||
9713 | group = target.ParentGroup; | ||
9714 | if (group.IsAttachment) { | ||
9715 | objID = group.AttachedAvatar; | ||
9716 | agent = World.GetScenePresence(objID); | ||
9717 | group = null; | ||
9718 | target = null; | ||
9719 | } | ||
9720 | } | ||
9721 | |||
9722 | // Initialize but break if no target | ||
9597 | LSL_List result = new LSL_List(); | 9723 | LSL_List result = new LSL_List(); |
9598 | if (!UUID.TryParse(obj, out objID)) | 9724 | int groupCount = 0; |
9725 | int partCount = 0; | ||
9726 | int vertexCount = 0; | ||
9727 | if (target == null && agent == null) | ||
9599 | { | 9728 | { |
9600 | result.Add(new LSL_Vector()); | 9729 | result.Add(new LSL_Vector()); |
9601 | result.Add(new LSL_Vector()); | 9730 | result.Add(new LSL_Vector()); |
9731 | if (m_addStatsInGetBoundingBox) | ||
9732 | result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); | ||
9602 | return result; | 9733 | return result; |
9603 | } | 9734 | } |
9604 | ScenePresence presence = World.GetScenePresence(objID); | 9735 | Vector3 minPosition = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); |
9605 | if (presence != null) | 9736 | Vector3 maxPosition = new Vector3(float.MinValue, float.MinValue, float.MinValue); |
9737 | |||
9738 | // Try to get a mesher | ||
9739 | IRendering primMesher = null; | ||
9740 | List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); | ||
9741 | if (renderers.Count > 0) | ||
9742 | primMesher = RenderingLoader.LoadRenderer(renderers[0]); | ||
9743 | |||
9744 | // Get bounding box of just avatar, seated or not | ||
9745 | if (agent != null) | ||
9746 | { | ||
9747 | bool hasParent = false; | ||
9748 | Vector3 lower; | ||
9749 | Vector3 upper; | ||
9750 | BoundingBoxOfScenePresence(agent, out lower, out upper); | ||
9751 | Vector3 offset = Vector3.Zero; | ||
9752 | |||
9753 | // Since local bounding box unrotated and untilted, keep it simple | ||
9754 | AddBoundingBoxOfSimpleBox(lower, upper, offset, agent.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9755 | partCount++; | ||
9756 | groupCount++; | ||
9757 | |||
9758 | // Return lower and upper bounding box corners | ||
9759 | result.Add(new LSL_Vector(minPosition)); | ||
9760 | result.Add(new LSL_Vector(maxPosition)); | ||
9761 | if (m_addStatsInGetBoundingBox) | ||
9762 | result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); | ||
9763 | return result; | ||
9764 | } | ||
9765 | // Get bounding box of object including seated avatars | ||
9766 | else if (group != null) | ||
9606 | { | 9767 | { |
9607 | if (presence.ParentID == 0) // not sat on an object | 9768 | // Merge bounding boxes of all parts (prims and mesh) |
9769 | foreach (SceneObjectPart part in group.Parts) | ||
9608 | { | 9770 | { |
9609 | LSL_Vector lower; | 9771 | bool hasParent = (!part.IsRoot); |
9610 | LSL_Vector upper; | 9772 | // When requested or if no mesher, keep it simple |
9611 | if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID | 9773 | if (m_useSimpleBoxesInGetBoundingBox || primMesher == null) |
9612 | == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) | ||
9613 | { | 9774 | { |
9614 | // This is for ground sitting avatars | 9775 | AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount); |
9615 | float height = presence.Appearance.AvatarHeight / 2.66666667f; | ||
9616 | lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); | ||
9617 | upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); | ||
9618 | } | 9776 | } |
9777 | // Do the full mounty | ||
9619 | else | 9778 | else |
9620 | { | 9779 | { |
9621 | // This is for standing/flying avatars | 9780 | Primitive omvPrim = part.Shape.ToOmvPrimitive(part.OffsetPosition, part.RotationOffset); |
9622 | float height = presence.Appearance.AvatarHeight / 2.0f; | 9781 | byte[] sculptAsset = null; |
9623 | lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); | 9782 | if (omvPrim.Sculpt != null) |
9624 | upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); | 9783 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); |
9784 | |||
9785 | // When part is mesh | ||
9786 | // Quirk: Only imports as incompletely populated faceted mesh object, so needs an own handler. | ||
9787 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) | ||
9788 | { | ||
9789 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); | ||
9790 | FacetedMesh mesh = null; | ||
9791 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out mesh); | ||
9792 | meshAsset = null; | ||
9793 | if (mesh != null) | ||
9794 | { | ||
9795 | AddBoundingBoxOfFacetedMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9796 | mesh = null; | ||
9797 | } | ||
9798 | } | ||
9799 | |||
9800 | // When part is sculpt | ||
9801 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. | ||
9802 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) | ||
9803 | { | ||
9804 | IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); | ||
9805 | if (imgDecoder != null) | ||
9806 | { | ||
9807 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); | ||
9808 | if (sculpt != null) | ||
9809 | { | ||
9810 | SimpleMesh mesh = primMesher.GenerateSimpleSculptMesh(omvPrim, (Bitmap)sculpt, DetailLevel.Medium); | ||
9811 | sculpt.Dispose(); | ||
9812 | if (mesh != null) | ||
9813 | { | ||
9814 | AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9815 | mesh = null; | ||
9816 | } | ||
9817 | } | ||
9818 | } | ||
9819 | } | ||
9820 | |||
9821 | // When part is prim | ||
9822 | else if (omvPrim.Sculpt == null) | ||
9823 | { | ||
9824 | SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium); | ||
9825 | if (mesh != null) | ||
9826 | { | ||
9827 | AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9828 | mesh = null; | ||
9829 | } | ||
9830 | } | ||
9831 | |||
9832 | // When all else fails, try fallback to simple box | ||
9833 | else | ||
9834 | { | ||
9835 | AddBoundingBoxOfSimpleBox(part.Scale * -0.5f, part.Scale * 0.5f, part.OffsetPosition, part.RotationOffset, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9836 | } | ||
9625 | } | 9837 | } |
9626 | result.Add(lower); | 9838 | partCount++; |
9627 | result.Add(upper); | ||
9628 | return result; | ||
9629 | } | 9839 | } |
9840 | } | ||
9841 | |||
9842 | // Merge bounding boxes of seated avatars | ||
9843 | foreach (ScenePresence sp in group.GetSittingAvatars()) | ||
9844 | { | ||
9845 | Vector3 lower; | ||
9846 | Vector3 upper; | ||
9847 | BoundingBoxOfScenePresence(sp, out lower, out upper); | ||
9848 | Vector3 offset = sp.OffsetPosition; | ||
9849 | |||
9850 | bool hasParent = true; | ||
9851 | // When requested or if no mesher, keep it simple | ||
9852 | if (m_useSimpleBoxesInGetBoundingBox || primMesher == null) | ||
9853 | { | ||
9854 | AddBoundingBoxOfSimpleBox(lower, upper, offset, sp.Rotation, hasParent, ref minPosition, ref maxPosition, ref vertexCount); | ||
9855 | } | ||
9856 | // Do the full mounty | ||
9630 | else | 9857 | else |
9631 | { | 9858 | { |
9632 | // sitting on an object so we need the bounding box of that | 9859 | // Prim shapes don't do center offsets, so add it here. |
9633 | // which should include the avatar so set the UUID to the | 9860 | offset = offset + (lower + upper) * 0.5f * sp.Rotation; |
9634 | // UUID of the object the avatar is sat on and allow it to fall through | 9861 | Primitive omvPrim = MakeOpenMetaversePrim(upper - lower, offset, sp.Rotation, ScriptBaseClass.PRIM_TYPE_SPHERE); |
9635 | // to processing an object | 9862 | SimpleMesh mesh = primMesher.GenerateSimpleMesh(omvPrim, DetailLevel.Medium); |
9636 | SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID); | 9863 | AddBoundingBoxOfSimpleMesh(mesh, omvPrim, hasParent, ref minPosition, ref maxPosition, ref vertexCount); |
9637 | objID = p.UUID; | 9864 | mesh = null; |
9638 | } | 9865 | } |
9866 | partCount++; | ||
9867 | } | ||
9868 | |||
9869 | groupCount++; | ||
9870 | |||
9871 | // Return lower and upper bounding box corners | ||
9872 | result.Add(new LSL_Vector(minPosition)); | ||
9873 | result.Add(new LSL_Vector(maxPosition)); | ||
9874 | if (m_addStatsInGetBoundingBox) | ||
9875 | result.Add(new LSL_Vector((float)groupCount, (float)partCount, (float)vertexCount)); | ||
9876 | |||
9877 | primMesher = null; | ||
9878 | return result; | ||
9879 | } | ||
9880 | |||
9881 | /// <summary> | ||
9882 | /// Helper to calculate bounding box of an avatar. | ||
9883 | /// </summary> | ||
9884 | private void BoundingBoxOfScenePresence(ScenePresence sp, out Vector3 lower, out Vector3 upper) | ||
9885 | { | ||
9886 | // Adjust from OS model | ||
9887 | // avatar height = visual height - 0.2, bounding box height = visual height | ||
9888 | // to SL model | ||
9889 | // avatar height = visual height, bounding box height = visual height + 0.2 | ||
9890 | float height = sp.Appearance.AvatarHeight + m_avatarHeightCorrection; | ||
9891 | |||
9892 | // According to avatar bounding box in SL 2015-04-18: | ||
9893 | // standing = <-0.275,-0.35,-0.1-0.5*h> : <0.275,0.35,0.1+0.5*h> | ||
9894 | // groundsitting = <-0.3875,-0.5,-0.05-0.375*h> : <0.3875,0.5,0.5> | ||
9895 | // sitting = <-0.5875,-0.35,-0.35-0.375*h> : <0.1875,0.35,-0.25+0.25*h> | ||
9896 | |||
9897 | // When avatar is sitting | ||
9898 | if (sp.ParentPart != null) | ||
9899 | { | ||
9900 | lower = new Vector3(m_lABB1SitX0, m_lABB1SitY0, m_lABB1SitZ0 + m_lABB1SitZ1 * height); | ||
9901 | upper = new Vector3(m_lABB2SitX0, m_lABB2SitY0, m_lABB2SitZ0 + m_lABB2SitZ1 * height); | ||
9639 | } | 9902 | } |
9640 | SceneObjectPart part = World.GetSceneObjectPart(objID); | 9903 | // When avatar is groundsitting |
9641 | // Currently only works for single prims without a sitting avatar | 9904 | else if (sp.Animator.Animations.ImplicitDefaultAnimation.AnimID == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) |
9642 | if (part != null) | ||
9643 | { | 9905 | { |
9644 | Vector3 halfSize = part.Scale / 2.0f; | 9906 | lower = new Vector3(m_lABB1GrsX0, m_lABB1GrsY0, m_lABB1GrsZ0 + m_lABB1GrsZ1 * height); |
9645 | LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; | 9907 | upper = new Vector3(m_lABB2GrsX0, m_lABB2GrsY0, m_lABB2GrsZ0 + m_lABB2GrsZ1 * height); |
9646 | LSL_Vector upper = new LSL_Vector(halfSize); | ||
9647 | result.Add(lower); | ||
9648 | result.Add(upper); | ||
9649 | return result; | ||
9650 | } | 9908 | } |
9909 | // When avatar is standing or flying | ||
9910 | else | ||
9911 | { | ||
9912 | lower = new Vector3(m_lABB1StdX0, m_lABB1StdY0, m_lABB1StdZ0 + m_lABB1StdZ1 * height); | ||
9913 | upper = new Vector3(m_lABB2StdX0, m_lABB2StdY0, m_lABB2StdZ0 + m_lABB2StdZ1 * height); | ||
9914 | } | ||
9915 | } | ||
9651 | 9916 | ||
9652 | // Not found so return empty values | 9917 | /// <summary> |
9653 | result.Add(new LSL_Vector()); | 9918 | /// Helper to approximate a part with a simple box. |
9654 | result.Add(new LSL_Vector()); | 9919 | /// </summary> |
9655 | return result; | 9920 | private void AddBoundingBoxOfSimpleBox(Vector3 corner1, Vector3 corner2, Vector3 offset, Quaternion rotation, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count) |
9921 | { | ||
9922 | // Parse the 8 box corners | ||
9923 | for (int i = 0; i < 8; i++) | ||
9924 | { | ||
9925 | // Calculate each box corner | ||
9926 | Vector3 position = corner1; | ||
9927 | if ((i & 1) != 0) | ||
9928 | position.X = corner2.X; | ||
9929 | if ((i & 2) != 0) | ||
9930 | position.Y = corner2.Y; | ||
9931 | if ((i & 4) != 0) | ||
9932 | position.Z = corner2.Z; | ||
9933 | // Rotate part unless part is root | ||
9934 | if (hasParent) | ||
9935 | position = position * rotation; | ||
9936 | position = position + offset; | ||
9937 | // Adjust lower and upper bounding box corners if needed | ||
9938 | lower = Vector3.Min(lower, position); | ||
9939 | upper = Vector3.Max(upper, position); | ||
9940 | count++; | ||
9941 | } | ||
9656 | } | 9942 | } |
9657 | 9943 | ||
9944 | /// <summary> | ||
9945 | /// Helper to parse a meshed prim and needed especially | ||
9946 | /// for accuracy with tortured prims and sculpts. | ||
9947 | /// </summary> | ||
9948 | private void AddBoundingBoxOfSimpleMesh(SimpleMesh mesh, Primitive prim, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count) | ||
9949 | { | ||
9950 | // Quirk: A meshed box contains 10 instead of the 8 necessary vertices. | ||
9951 | if (mesh != null) | ||
9952 | { | ||
9953 | // Parse each vertex in mesh | ||
9954 | foreach (Vertex vertex in mesh.Vertices) | ||
9955 | { | ||
9956 | Vector3 position = vertex.Position; | ||
9957 | position = position * prim.Scale; | ||
9958 | // Rotate part unless part is root | ||
9959 | if (hasParent) | ||
9960 | position = position * prim.Rotation; | ||
9961 | position = position + prim.Position; | ||
9962 | // Adjust lower and upper bounding box corners if needed | ||
9963 | lower = Vector3.Min(lower, position); | ||
9964 | upper = Vector3.Max(upper, position); | ||
9965 | count++; | ||
9966 | } | ||
9967 | } | ||
9968 | } | ||
9969 | |||
9970 | /// <summary> | ||
9971 | /// Helper to parse mesh because no method exists | ||
9972 | /// to parse mesh assets to SimpleMesh. | ||
9973 | /// </summary> | ||
9974 | private void AddBoundingBoxOfFacetedMesh(FacetedMesh mesh, Primitive prim, bool hasParent, ref Vector3 lower, ref Vector3 upper, ref int count) | ||
9975 | { | ||
9976 | if (mesh != null) | ||
9977 | { | ||
9978 | // Parse each face in mesh | ||
9979 | // since vertex array isn't populated. | ||
9980 | // This parses each unique vertex 3-6 times. | ||
9981 | foreach (Face face in mesh.Faces) | ||
9982 | { | ||
9983 | // Parse each vertex in face | ||
9984 | foreach (Vertex vertex in face.Vertices) | ||
9985 | { | ||
9986 | Vector3 position = vertex.Position; | ||
9987 | position = position * prim.Scale; | ||
9988 | // Rotate part unless part is root | ||
9989 | if (hasParent) | ||
9990 | position = position * prim.Rotation; | ||
9991 | position = position + prim.Position; | ||
9992 | // Adjust lower and upper bounding box corners if needed | ||
9993 | lower = Vector3.Min(lower, position); | ||
9994 | upper = Vector3.Max(upper, position); | ||
9995 | count++; | ||
9996 | } | ||
9997 | } | ||
9998 | } | ||
9999 | } | ||
10000 | |||
10001 | /// <summary> | ||
10002 | /// Helper to make up an OpenMetaverse prim | ||
10003 | /// needed to create mesh from parts. | ||
10004 | /// </summary> | ||
10005 | private Primitive MakeOpenMetaversePrim(Vector3 scale, Vector3 position, Quaternion rotation, int primType) | ||
10006 | { | ||
10007 | // Initialize and set common parameters | ||
10008 | Primitive prim = new OpenMetaverse.Primitive(); | ||
10009 | prim.Scale = scale; | ||
10010 | prim.Position = position; | ||
10011 | prim.Rotation = rotation; | ||
10012 | prim.PrimData.PathShearX = 0.0f; | ||
10013 | prim.PrimData.PathShearY = 0.0f; | ||
10014 | prim.PrimData.PathBegin = 0.0f; | ||
10015 | prim.PrimData.PathEnd = 1.0f; | ||
10016 | prim.PrimData.PathScaleX = 1.0f; | ||
10017 | prim.PrimData.PathScaleY = 1.0f; | ||
10018 | prim.PrimData.PathTaperX = 0.0f; | ||
10019 | prim.PrimData.PathTaperY = 0.0f; | ||
10020 | prim.PrimData.PathTwistBegin = 0.0f; | ||
10021 | prim.PrimData.PathTwist = 0.0f; | ||
10022 | prim.PrimData.ProfileBegin = 0.0f; | ||
10023 | prim.PrimData.ProfileEnd = 1.0f; | ||
10024 | prim.PrimData.ProfileHollow = 0.0f; | ||
10025 | prim.PrimData.ProfileCurve = (ProfileCurve)1; | ||
10026 | prim.PrimData.ProfileHole = (HoleType)0; | ||
10027 | prim.PrimData.PathCurve = (PathCurve)16; | ||
10028 | prim.PrimData.PathRadiusOffset = 0.0f; | ||
10029 | prim.PrimData.PathRevolutions = 1.0f; | ||
10030 | prim.PrimData.PathSkew = 0.0f; | ||
10031 | prim.PrimData.PCode = OpenMetaverse.PCode.Prim; | ||
10032 | prim.PrimData.State = (byte)0; | ||
10033 | |||
10034 | // Set type specific parameters | ||
10035 | switch (primType) | ||
10036 | { | ||
10037 | // Set specific parameters for box | ||
10038 | case ScriptBaseClass.PRIM_TYPE_BOX: | ||
10039 | prim.PrimData.PathScaleY = 1.0f; | ||
10040 | prim.PrimData.ProfileCurve = (ProfileCurve)1; | ||
10041 | prim.PrimData.PathCurve = (PathCurve)16; | ||
10042 | break; | ||
10043 | // Set specific parameters for cylinder | ||
10044 | case ScriptBaseClass.PRIM_TYPE_CYLINDER: | ||
10045 | prim.PrimData.PathScaleY = 1.0f; | ||
10046 | prim.PrimData.ProfileCurve = (ProfileCurve)0; | ||
10047 | prim.PrimData.PathCurve = (PathCurve)16; | ||
10048 | break; | ||
10049 | // Set specific parameters for prism | ||
10050 | case ScriptBaseClass.PRIM_TYPE_PRISM: | ||
10051 | prim.PrimData.PathScaleY = 1.0f; | ||
10052 | prim.PrimData.ProfileCurve = (ProfileCurve)3; | ||
10053 | prim.PrimData.PathCurve = (PathCurve)16; | ||
10054 | break; | ||
10055 | // Set specific parameters for sphere | ||
10056 | case ScriptBaseClass.PRIM_TYPE_SPHERE: | ||
10057 | prim.PrimData.PathScaleY = 1.0f; | ||
10058 | prim.PrimData.ProfileCurve = (ProfileCurve)5; | ||
10059 | prim.PrimData.PathCurve = (PathCurve)32; | ||
10060 | break; | ||
10061 | // Set specific parameters for torus | ||
10062 | case ScriptBaseClass.PRIM_TYPE_TORUS: | ||
10063 | prim.PrimData.PathScaleY = 0.5f; | ||
10064 | prim.PrimData.ProfileCurve = (ProfileCurve)0; | ||
10065 | prim.PrimData.PathCurve = (PathCurve)32; | ||
10066 | break; | ||
10067 | // Set specific parameters for tube | ||
10068 | case ScriptBaseClass.PRIM_TYPE_TUBE: | ||
10069 | prim.PrimData.PathScaleY = 0.5f; | ||
10070 | prim.PrimData.ProfileCurve = (ProfileCurve)1; | ||
10071 | prim.PrimData.PathCurve = (PathCurve)32; | ||
10072 | break; | ||
10073 | // Set specific parameters for ring | ||
10074 | case ScriptBaseClass.PRIM_TYPE_RING: | ||
10075 | prim.PrimData.PathScaleY = 0.5f; | ||
10076 | prim.PrimData.ProfileCurve = (ProfileCurve)3; | ||
10077 | prim.PrimData.PathCurve = (PathCurve)32; | ||
10078 | break; | ||
10079 | // Set specific parameters for sculpt | ||
10080 | case ScriptBaseClass.PRIM_TYPE_SCULPT: | ||
10081 | prim.PrimData.PathScaleY = 1.0f; | ||
10082 | prim.PrimData.ProfileCurve = (ProfileCurve)5; | ||
10083 | prim.PrimData.PathCurve = (PathCurve)32; | ||
10084 | break; | ||
10085 | // Default to specific parameters for box | ||
10086 | default: | ||
10087 | prim.PrimData.PathScaleY = 1.0f; | ||
10088 | prim.PrimData.ProfileCurve = (ProfileCurve)1; | ||
10089 | prim.PrimData.PathCurve = (PathCurve)16; | ||
10090 | break; | ||
10091 | } | ||
10092 | |||
10093 | return prim; | ||
10094 | } | ||
10095 | |||
10096 | /// <summary> | ||
10097 | /// Implementation of llGetGeometricCenter according to SL 2015-04-30. | ||
10098 | /// http://wiki.secondlife.com/wiki/LlGetGeometricCenter | ||
10099 | /// Returns the average position offset of all linked parts, | ||
10100 | /// including the root prim and seated avatars, | ||
10101 | /// relative to the root prim in local coordinates. | ||
10102 | /// </summary> | ||
9658 | public LSL_Vector llGetGeometricCenter() | 10103 | public LSL_Vector llGetGeometricCenter() |
9659 | { | 10104 | { |
9660 | return new LSL_Vector(m_host.GetGeometricCenter()); | 10105 | // Subtract whatever position the root prim has to make it zero |
10106 | Vector3 offset = m_host.ParentGroup.RootPart.OffsetPosition * -1.0f; | ||
10107 | |||
10108 | // Add all prim/part position offsets | ||
10109 | foreach (SceneObjectPart part in m_host.ParentGroup.Parts) | ||
10110 | offset = offset + part.OffsetPosition; | ||
10111 | // Add all avatar/scene presence position offsets | ||
10112 | foreach (ScenePresence sp in m_host.ParentGroup.GetSittingAvatars()) | ||
10113 | offset = offset + sp.OffsetPosition; | ||
10114 | |||
10115 | // Calculate and return the average offset | ||
10116 | offset = offset / (float)(m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount()); | ||
10117 | return new LSL_Vector(offset); | ||
9661 | } | 10118 | } |
9662 | 10119 | ||
9663 | public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) | 10120 | public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) |
@@ -12600,6 +13057,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12600 | case ScriptBaseClass.OBJECT_TEMP_ON_REZ: | 13057 | case ScriptBaseClass.OBJECT_TEMP_ON_REZ: |
12601 | ret.Add(new LSL_Integer(0)); | 13058 | ret.Add(new LSL_Integer(0)); |
12602 | break; | 13059 | break; |
13060 | case ScriptBaseClass.OBJECT_RENDER_WEIGHT: | ||
13061 | ret.Add(new LSL_Integer(-1)); | ||
13062 | break; | ||
13063 | case ScriptBaseClass.OBJECT_HOVER_HEIGHT: | ||
13064 | ret.Add(new LSL_Float(0)); | ||
13065 | break; | ||
13066 | case ScriptBaseClass.OBJECT_BODY_SHAPE_TYPE: | ||
13067 | LSL_Float shapeType; | ||
13068 | if (av.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] != 0) | ||
13069 | shapeType = new LSL_Float(1); | ||
13070 | else | ||
13071 | shapeType = new LSL_Float(0); | ||
13072 | ret.Add(shapeType); | ||
13073 | break; | ||
13074 | case ScriptBaseClass.OBJECT_LAST_OWNER_ID: | ||
13075 | ret.Add(new LSL_Key(ScriptBaseClass.NULL_KEY)); | ||
13076 | break; | ||
12603 | default: | 13077 | default: |
12604 | // Invalid or unhandled constant. | 13078 | // Invalid or unhandled constant. |
12605 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); | 13079 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); |
@@ -12764,6 +13238,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
12764 | case ScriptBaseClass.OBJECT_TEMP_ON_REZ: | 13238 | case ScriptBaseClass.OBJECT_TEMP_ON_REZ: |
12765 | ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0)); | 13239 | ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0)); |
12766 | break; | 13240 | break; |
13241 | case ScriptBaseClass.OBJECT_RENDER_WEIGHT: | ||
13242 | ret.Add(new LSL_Integer(0)); | ||
13243 | break; | ||
13244 | case ScriptBaseClass.OBJECT_HOVER_HEIGHT: | ||
13245 | ret.Add(new LSL_Float(0)); | ||
13246 | break; | ||
13247 | case ScriptBaseClass.OBJECT_BODY_SHAPE_TYPE: | ||
13248 | ret.Add(new LSL_Float(-1)); | ||
13249 | break; | ||
13250 | case ScriptBaseClass.OBJECT_LAST_OWNER_ID: | ||
13251 | ret.Add(new LSL_Key(obj.ParentGroup.LastOwnerID.ToString())); | ||
13252 | break; | ||
12767 | default: | 13253 | default: |
12768 | // Invalid or unhandled constant. | 13254 | // Invalid or unhandled constant. |
12769 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); | 13255 | ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); |
@@ -13335,6 +13821,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13335 | 13821 | ||
13336 | public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) | 13822 | public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) |
13337 | { | 13823 | { |
13824 | // Use llCastRay V3 if configured | ||
13825 | if (m_useCastRayV3) | ||
13826 | return llCastRayV3(start, end, options); | ||
13827 | |||
13338 | LSL_List list = new LSL_List(); | 13828 | LSL_List list = new LSL_List(); |
13339 | 13829 | ||
13340 | m_host.AddScriptLPS(1); | 13830 | m_host.AddScriptLPS(1); |
@@ -13524,6 +14014,732 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
13524 | return list; | 14014 | return list; |
13525 | } | 14015 | } |
13526 | 14016 | ||
14017 | /// <summary> | ||
14018 | /// Implementation of llCastRay similar to SL 2015-04-21. | ||
14019 | /// http://wiki.secondlife.com/wiki/LlCastRay | ||
14020 | /// Uses pure geometry, bounding shapes, meshing and no physics | ||
14021 | /// for prims, sculpts, meshes, avatars and terrain. | ||
14022 | /// Implements all flags, reject types and data flags. | ||
14023 | /// Can handle both objects/groups and prims/parts, by config. | ||
14024 | /// May sometimes be inaccurate owing to calculation precision, | ||
14025 | /// meshing detail level and a bug in libopenmetaverse PrimMesher. | ||
14026 | /// </summary> | ||
14027 | public LSL_List llCastRayV3(LSL_Vector start, LSL_Vector end, LSL_List options) | ||
14028 | { | ||
14029 | // Initialize | ||
14030 | m_host.AddScriptLPS(1); | ||
14031 | List<RayHit> rayHits = new List<RayHit>(); | ||
14032 | LSL_List result = new LSL_List(); | ||
14033 | float tol = m_floatToleranceInCastRay; | ||
14034 | Vector3 pos1Ray = start; | ||
14035 | Vector3 pos2Ray = end; | ||
14036 | |||
14037 | // Get input options | ||
14038 | int rejectTypes = 0; | ||
14039 | int dataFlags = 0; | ||
14040 | int maxHits = 1; | ||
14041 | bool detectPhantom = false; | ||
14042 | for (int i = 0; i < options.Length; i += 2) | ||
14043 | { | ||
14044 | if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) | ||
14045 | rejectTypes = options.GetLSLIntegerItem(i + 1); | ||
14046 | else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) | ||
14047 | dataFlags = options.GetLSLIntegerItem(i + 1); | ||
14048 | else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) | ||
14049 | maxHits = options.GetLSLIntegerItem(i + 1); | ||
14050 | else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) | ||
14051 | detectPhantom = (options.GetLSLIntegerItem(i + 1) != 0); | ||
14052 | } | ||
14053 | if (maxHits > m_maxHitsInCastRay) | ||
14054 | maxHits = m_maxHitsInCastRay; | ||
14055 | bool rejectAgents = ((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != 0); | ||
14056 | bool rejectPhysical = ((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) != 0); | ||
14057 | bool rejectNonphysical = ((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) != 0); | ||
14058 | bool rejectLand = ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) != 0); | ||
14059 | bool getNormal = ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) != 0); | ||
14060 | bool getRootKey = ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) != 0); | ||
14061 | bool getLinkNum = ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) != 0); | ||
14062 | |||
14063 | // Calculate some basic parameters | ||
14064 | Vector3 vecRay = pos2Ray - pos1Ray; | ||
14065 | float rayLength = vecRay.Length(); | ||
14066 | |||
14067 | // Try to get a mesher and return failure if none, degenerate ray, or max 0 hits | ||
14068 | IRendering primMesher = null; | ||
14069 | List<string> renderers = RenderingLoader.ListRenderers(Util.ExecutingDirectory()); | ||
14070 | if (renderers.Count < 1 || rayLength < tol || m_maxHitsInCastRay < 1) | ||
14071 | { | ||
14072 | result.Add(new LSL_Integer(ScriptBaseClass.RCERR_UNKNOWN)); | ||
14073 | return result; | ||
14074 | } | ||
14075 | primMesher = RenderingLoader.LoadRenderer(renderers[0]); | ||
14076 | |||
14077 | // Iterate over all objects/groups and prims/parts in region | ||
14078 | World.ForEachSOG( | ||
14079 | delegate(SceneObjectGroup group) | ||
14080 | { | ||
14081 | // Check group filters unless part filters are configured | ||
14082 | bool isPhysical = (group.RootPart != null && group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical); | ||
14083 | bool isNonphysical = !isPhysical; | ||
14084 | bool isPhantom = group.IsPhantom || group.IsVolumeDetect; | ||
14085 | bool isAttachment = group.IsAttachment; | ||
14086 | bool doGroup = true; | ||
14087 | if (isPhysical && rejectPhysical) | ||
14088 | doGroup = false; | ||
14089 | if (isNonphysical && rejectNonphysical) | ||
14090 | doGroup = false; | ||
14091 | if (isPhantom && detectPhantom) | ||
14092 | doGroup = true; | ||
14093 | if (m_filterPartsInCastRay) | ||
14094 | doGroup = true; | ||
14095 | if (isAttachment && !m_doAttachmentsInCastRay) | ||
14096 | doGroup = false; | ||
14097 | // Parse object/group if passed filters | ||
14098 | if (doGroup) | ||
14099 | { | ||
14100 | // Iterate over all prims/parts in object/group | ||
14101 | foreach(SceneObjectPart part in group.Parts) | ||
14102 | { | ||
14103 | // Check part filters if configured | ||
14104 | if (m_filterPartsInCastRay) | ||
14105 | { | ||
14106 | isPhysical = (part.PhysActor != null && part.PhysActor.IsPhysical); | ||
14107 | isNonphysical = !isPhysical; | ||
14108 | isPhantom = ((part.Flags & PrimFlags.Phantom) != 0) || (part.VolumeDetectActive); | ||
14109 | bool doPart = true; | ||
14110 | if (isPhysical && rejectPhysical) | ||
14111 | doPart = false; | ||
14112 | if (isNonphysical && rejectNonphysical) | ||
14113 | doPart = false; | ||
14114 | if (isPhantom && detectPhantom) | ||
14115 | doPart = true; | ||
14116 | if (!doPart) | ||
14117 | continue; | ||
14118 | } | ||
14119 | |||
14120 | // Parse prim/part and project ray if passed filters | ||
14121 | Vector3 scalePart = part.Scale; | ||
14122 | Vector3 posPart = part.GetWorldPosition(); | ||
14123 | Quaternion rotPart = part.GetWorldRotation(); | ||
14124 | Quaternion rotPartInv = Quaternion.Inverse(rotPart); | ||
14125 | Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart; | ||
14126 | Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart; | ||
14127 | |||
14128 | // Filter parts by shape bounding boxes | ||
14129 | Vector3 shapeBoxMax = new Vector3(0.5f, 0.5f, 0.5f); | ||
14130 | if (!part.Shape.SculptEntry) | ||
14131 | shapeBoxMax = shapeBoxMax * (new Vector3(m_primSafetyCoeffX, m_primSafetyCoeffY, m_primSafetyCoeffZ)); | ||
14132 | shapeBoxMax = shapeBoxMax + (new Vector3(tol, tol, tol)); | ||
14133 | if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax)) | ||
14134 | { | ||
14135 | // Prepare data needed to check for ray hits | ||
14136 | RayTrans rayTrans = new RayTrans(); | ||
14137 | rayTrans.PartId = part.UUID; | ||
14138 | rayTrans.GroupId = part.ParentGroup.UUID; | ||
14139 | rayTrans.Link = group.PrimCount > 1 ? part.LinkNum : 0; | ||
14140 | rayTrans.ScalePart = scalePart; | ||
14141 | rayTrans.PositionPart = posPart; | ||
14142 | rayTrans.RotationPart = rotPart; | ||
14143 | rayTrans.ShapeNeedsEnds = true; | ||
14144 | rayTrans.Position1Ray = pos1Ray; | ||
14145 | rayTrans.Position1RayProj = pos1RayProj; | ||
14146 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; | ||
14147 | |||
14148 | // Make an OMV prim to be able to mesh part | ||
14149 | Primitive omvPrim = part.Shape.ToOmvPrimitive(posPart, rotPart); | ||
14150 | byte[] sculptAsset = null; | ||
14151 | if (omvPrim.Sculpt != null) | ||
14152 | sculptAsset = World.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString()); | ||
14153 | FacetedMesh mesh = null; | ||
14154 | |||
14155 | // When part is mesh, get mesh and check for hits | ||
14156 | if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type == SculptType.Mesh && sculptAsset != null) | ||
14157 | { | ||
14158 | AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset); | ||
14159 | FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, m_meshLodInCastRay, out mesh); | ||
14160 | meshAsset = null; | ||
14161 | } | ||
14162 | |||
14163 | // When part is sculpt, create mesh and check for hits | ||
14164 | // Quirk: Generated sculpt mesh is about 2.8% smaller in X and Y than visual sculpt. | ||
14165 | else if (omvPrim.Sculpt != null && omvPrim.Sculpt.Type != SculptType.Mesh && sculptAsset != null) | ||
14166 | { | ||
14167 | IJ2KDecoder imgDecoder = World.RequestModuleInterface<IJ2KDecoder>(); | ||
14168 | if (imgDecoder != null) | ||
14169 | { | ||
14170 | Image sculpt = imgDecoder.DecodeToImage(sculptAsset); | ||
14171 | if (sculpt != null) | ||
14172 | { | ||
14173 | mesh = primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, m_sculptLodInCastRay); | ||
14174 | sculpt.Dispose(); | ||
14175 | } | ||
14176 | } | ||
14177 | } | ||
14178 | |||
14179 | // When part is prim, create mesh and check for hits | ||
14180 | else if (omvPrim.Sculpt == null) | ||
14181 | { | ||
14182 | if ( | ||
14183 | omvPrim.PrimData.PathBegin == 0.0 && omvPrim.PrimData.PathEnd == 1.0 && | ||
14184 | omvPrim.PrimData.PathTaperX == 0.0 && omvPrim.PrimData.PathTaperY == 0.0 && | ||
14185 | omvPrim.PrimData.PathSkew == 0.0 && | ||
14186 | omvPrim.PrimData.PathTwist - omvPrim.PrimData.PathTwistBegin == 0.0 | ||
14187 | ) | ||
14188 | rayTrans.ShapeNeedsEnds = false; | ||
14189 | mesh = primMesher.GenerateFacetedMesh(omvPrim, m_primLodInCastRay); | ||
14190 | } | ||
14191 | |||
14192 | // Check mesh for ray hits | ||
14193 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | ||
14194 | mesh = null; | ||
14195 | } | ||
14196 | } | ||
14197 | } | ||
14198 | } | ||
14199 | ); | ||
14200 | |||
14201 | // Check avatar filter | ||
14202 | if (!rejectAgents) | ||
14203 | { | ||
14204 | // Iterate over all avatars in region | ||
14205 | World.ForEachRootScenePresence( | ||
14206 | delegate (ScenePresence sp) | ||
14207 | { | ||
14208 | // Get bounding box | ||
14209 | Vector3 lower; | ||
14210 | Vector3 upper; | ||
14211 | BoundingBoxOfScenePresence(sp, out lower, out upper); | ||
14212 | // Parse avatar | ||
14213 | Vector3 scalePart = upper - lower; | ||
14214 | Vector3 posPart = sp.AbsolutePosition; | ||
14215 | Quaternion rotPart = sp.GetWorldRotation(); | ||
14216 | Quaternion rotPartInv = Quaternion.Inverse(rotPart); | ||
14217 | posPart = posPart + (lower + upper) * 0.5f * rotPart; | ||
14218 | // Project ray | ||
14219 | Vector3 pos1RayProj = ((pos1Ray - posPart) * rotPartInv) / scalePart; | ||
14220 | Vector3 pos2RayProj = ((pos2Ray - posPart) * rotPartInv) / scalePart; | ||
14221 | |||
14222 | // Filter avatars by shape bounding boxes | ||
14223 | Vector3 shapeBoxMax = new Vector3(0.5f + tol, 0.5f + tol, 0.5f + tol); | ||
14224 | if (RayIntersectsShapeBox(pos1RayProj, pos2RayProj, shapeBoxMax)) | ||
14225 | { | ||
14226 | // Prepare data needed to check for ray hits | ||
14227 | RayTrans rayTrans = new RayTrans(); | ||
14228 | rayTrans.PartId = sp.UUID; | ||
14229 | rayTrans.GroupId = sp.ParentPart != null ? sp.ParentPart.ParentGroup.UUID : sp.UUID; | ||
14230 | rayTrans.Link = sp.ParentPart != null ? UUID2LinkNumber(sp.ParentPart, sp.UUID) : 0; | ||
14231 | rayTrans.ScalePart = scalePart; | ||
14232 | rayTrans.PositionPart = posPart; | ||
14233 | rayTrans.RotationPart = rotPart; | ||
14234 | rayTrans.ShapeNeedsEnds = false; | ||
14235 | rayTrans.Position1Ray = pos1Ray; | ||
14236 | rayTrans.Position1RayProj = pos1RayProj; | ||
14237 | rayTrans.VectorRayProj = pos2RayProj - pos1RayProj; | ||
14238 | |||
14239 | // Make OMV prim, create and check mesh | ||
14240 | PrimitiveBaseShape prim = PrimitiveBaseShape.CreateSphere(); | ||
14241 | prim.Scale = scalePart; | ||
14242 | Primitive omvPrim = prim.ToOmvPrimitive(posPart, rotPart); | ||
14243 | FacetedMesh mesh = primMesher.GenerateFacetedMesh(omvPrim, m_meshLodInCastRay); | ||
14244 | AddRayInFacetedMesh(mesh, rayTrans, ref rayHits); | ||
14245 | mesh = null; | ||
14246 | } | ||
14247 | } | ||
14248 | ); | ||
14249 | } | ||
14250 | |||
14251 | // Check terrain filter | ||
14252 | if (!rejectLand) | ||
14253 | { | ||
14254 | // Parse terrain | ||
14255 | |||
14256 | // Mesh terrain and check bounding box | ||
14257 | Vector3 lower; | ||
14258 | Vector3 upper; | ||
14259 | List<Tri> triangles = TrisFromHeightmapUnderRay(pos1Ray, pos2Ray, out lower, out upper); | ||
14260 | lower.Z -= tol; | ||
14261 | upper.Z += tol; | ||
14262 | if ((pos1Ray.Z >= lower.Z || pos2Ray.Z >= lower.Z) && (pos1Ray.Z <= upper.Z || pos2Ray.Z <= upper.Z)) | ||
14263 | { | ||
14264 | // Prepare data needed to check for ray hits | ||
14265 | RayTrans rayTrans = new RayTrans(); | ||
14266 | rayTrans.PartId = UUID.Zero; | ||
14267 | rayTrans.GroupId = UUID.Zero; | ||
14268 | rayTrans.Link = 0; | ||
14269 | rayTrans.ScalePart = new Vector3 (1.0f, 1.0f, 1.0f); | ||
14270 | rayTrans.PositionPart = Vector3.Zero; | ||
14271 | rayTrans.RotationPart = Quaternion.Identity; | ||
14272 | rayTrans.ShapeNeedsEnds = true; | ||
14273 | rayTrans.Position1Ray = pos1Ray; | ||
14274 | rayTrans.Position1RayProj = pos1Ray; | ||
14275 | rayTrans.VectorRayProj = vecRay; | ||
14276 | |||
14277 | // Check mesh | ||
14278 | AddRayInTris(triangles, rayTrans, ref rayHits); | ||
14279 | triangles = null; | ||
14280 | } | ||
14281 | } | ||
14282 | |||
14283 | // Sort hits by ascending distance | ||
14284 | rayHits.Sort((s1, s2) => s1.Distance.CompareTo(s2.Distance)); | ||
14285 | |||
14286 | // Check excess hits per part and group | ||
14287 | for (int t = 0; t < 2; t++) | ||
14288 | { | ||
14289 | int maxHitsPerType = 0; | ||
14290 | UUID id = UUID.Zero; | ||
14291 | if (t == 0) | ||
14292 | maxHitsPerType = m_maxHitsPerPrimInCastRay; | ||
14293 | else | ||
14294 | maxHitsPerType = m_maxHitsPerObjectInCastRay; | ||
14295 | |||
14296 | // Handle excess hits only when needed | ||
14297 | if (maxHitsPerType < m_maxHitsInCastRay) | ||
14298 | { | ||
14299 | // Find excess hits | ||
14300 | Hashtable hits = new Hashtable(); | ||
14301 | for (int i = rayHits.Count - 1; i >= 0; i--) | ||
14302 | { | ||
14303 | if (t == 0) | ||
14304 | id = rayHits[i].PartId; | ||
14305 | else | ||
14306 | id = rayHits[i].GroupId; | ||
14307 | if (hits.ContainsKey(id)) | ||
14308 | hits[id] = (int)hits[id] + 1; | ||
14309 | else | ||
14310 | hits[id] = 1; | ||
14311 | } | ||
14312 | |||
14313 | // Remove excess hits | ||
14314 | for (int i = rayHits.Count - 1; i >= 0; i--) | ||
14315 | { | ||
14316 | if (t == 0) | ||
14317 | id = rayHits[i].PartId; | ||
14318 | else | ||
14319 | id = rayHits[i].GroupId; | ||
14320 | int hit = (int)hits[id]; | ||
14321 | if (hit > m_maxHitsPerPrimInCastRay) | ||
14322 | { | ||
14323 | rayHits.RemoveAt(i); | ||
14324 | hit--; | ||
14325 | hits[id] = hit; | ||
14326 | } | ||
14327 | } | ||
14328 | } | ||
14329 | } | ||
14330 | |||
14331 | // Parse hits into result list according to data flags | ||
14332 | int hitCount = rayHits.Count; | ||
14333 | if (hitCount > maxHits) | ||
14334 | hitCount = maxHits; | ||
14335 | for (int i = 0; i < hitCount; i++) | ||
14336 | { | ||
14337 | RayHit rayHit = rayHits[i]; | ||
14338 | if (getRootKey) | ||
14339 | result.Add(new LSL_Key(rayHit.GroupId.ToString())); | ||
14340 | else | ||
14341 | result.Add(new LSL_Key(rayHit.PartId.ToString())); | ||
14342 | result.Add(new LSL_Vector(rayHit.Position)); | ||
14343 | if (getLinkNum) | ||
14344 | result.Add(new LSL_Integer(rayHit.Link)); | ||
14345 | if (getNormal) | ||
14346 | result.Add(new LSL_Vector(rayHit.Normal)); | ||
14347 | } | ||
14348 | result.Add(new LSL_Integer(hitCount)); | ||
14349 | return result; | ||
14350 | } | ||
14351 | |||
14352 | /// <summary> | ||
14353 | /// Struct for transmitting parameters required for finding llCastRay ray hits. | ||
14354 | /// </summary> | ||
14355 | public struct RayTrans | ||
14356 | { | ||
14357 | public UUID PartId; | ||
14358 | public UUID GroupId; | ||
14359 | public int Link; | ||
14360 | public Vector3 ScalePart; | ||
14361 | public Vector3 PositionPart; | ||
14362 | public Quaternion RotationPart; | ||
14363 | public bool ShapeNeedsEnds; | ||
14364 | public Vector3 Position1Ray; | ||
14365 | public Vector3 Position1RayProj; | ||
14366 | public Vector3 VectorRayProj; | ||
14367 | } | ||
14368 | |||
14369 | /// <summary> | ||
14370 | /// Struct for llCastRay ray hits. | ||
14371 | /// </summary> | ||
14372 | public struct RayHit | ||
14373 | { | ||
14374 | public UUID PartId; | ||
14375 | public UUID GroupId; | ||
14376 | public int Link; | ||
14377 | public Vector3 Position; | ||
14378 | public Vector3 Normal; | ||
14379 | public float Distance; | ||
14380 | } | ||
14381 | |||
14382 | /// <summary> | ||
14383 | /// Helper to check if a ray intersects a shape bounding box. | ||
14384 | /// </summary> | ||
14385 | private bool RayIntersectsShapeBox(Vector3 pos1RayProj, Vector3 pos2RayProj, Vector3 shapeBoxMax) | ||
14386 | { | ||
14387 | // Skip if ray can't intersect bounding box; | ||
14388 | Vector3 rayBoxProjMin = Vector3.Min(pos1RayProj, pos2RayProj); | ||
14389 | Vector3 rayBoxProjMax = Vector3.Max(pos1RayProj, pos2RayProj); | ||
14390 | if ( | ||
14391 | rayBoxProjMin.X > shapeBoxMax.X || rayBoxProjMin.Y > shapeBoxMax.Y || rayBoxProjMin.Z > shapeBoxMax.Z || | ||
14392 | rayBoxProjMax.X < -shapeBoxMax.X || rayBoxProjMax.Y < -shapeBoxMax.Y || rayBoxProjMax.Z < -shapeBoxMax.Z | ||
14393 | ) | ||
14394 | return false; | ||
14395 | |||
14396 | // Check if ray intersect any bounding box side | ||
14397 | int sign = 0; | ||
14398 | float dist = 0.0f; | ||
14399 | Vector3 posProj = Vector3.Zero; | ||
14400 | Vector3 vecRayProj = pos2RayProj - pos1RayProj; | ||
14401 | |||
14402 | // Check both X sides unless ray is parallell to them | ||
14403 | if (Math.Abs(vecRayProj.X) > m_floatToleranceInCastRay) | ||
14404 | { | ||
14405 | for (sign = -1; sign <= 1; sign += 2) | ||
14406 | { | ||
14407 | dist = ((float)sign * shapeBoxMax.X - pos1RayProj.X) / vecRayProj.X; | ||
14408 | posProj = pos1RayProj + vecRayProj * dist; | ||
14409 | if (Math.Abs(posProj.Y) <= shapeBoxMax.Y && Math.Abs(posProj.Z) <= shapeBoxMax.Z) | ||
14410 | return true; | ||
14411 | } | ||
14412 | } | ||
14413 | |||
14414 | // Check both Y sides unless ray is parallell to them | ||
14415 | if (Math.Abs(vecRayProj.Y) > m_floatToleranceInCastRay) | ||
14416 | { | ||
14417 | for (sign = -1; sign <= 1; sign += 2) | ||
14418 | { | ||
14419 | dist = ((float)sign * shapeBoxMax.Y - pos1RayProj.Y) / vecRayProj.Y; | ||
14420 | posProj = pos1RayProj + vecRayProj * dist; | ||
14421 | if (Math.Abs(posProj.X) <= shapeBoxMax.X && Math.Abs(posProj.Z) <= shapeBoxMax.Z) | ||
14422 | return true; | ||
14423 | } | ||
14424 | } | ||
14425 | |||
14426 | // Check both Z sides unless ray is parallell to them | ||
14427 | if (Math.Abs(vecRayProj.Z) > m_floatToleranceInCastRay) | ||
14428 | { | ||
14429 | for (sign = -1; sign <= 1; sign += 2) | ||
14430 | { | ||
14431 | dist = ((float)sign * shapeBoxMax.Z - pos1RayProj.Z) / vecRayProj.Z; | ||
14432 | posProj = pos1RayProj + vecRayProj * dist; | ||
14433 | if (Math.Abs(posProj.X) <= shapeBoxMax.X && Math.Abs(posProj.Y) <= shapeBoxMax.Y) | ||
14434 | return true; | ||
14435 | } | ||
14436 | } | ||
14437 | |||
14438 | // No hits on bounding box so return false | ||
14439 | return false; | ||
14440 | } | ||
14441 | |||
14442 | /// <summary> | ||
14443 | /// Helper to parse FacetedMesh for ray hits. | ||
14444 | /// </summary> | ||
14445 | private void AddRayInFacetedMesh(FacetedMesh mesh, RayTrans rayTrans, ref List<RayHit> rayHits) | ||
14446 | { | ||
14447 | if (mesh != null) | ||
14448 | { | ||
14449 | foreach (Face face in mesh.Faces) | ||
14450 | { | ||
14451 | for (int i = 0; i < face.Indices.Count; i += 3) | ||
14452 | { | ||
14453 | Tri triangle = new Tri(); | ||
14454 | triangle.p1 = face.Vertices[face.Indices[i]].Position; | ||
14455 | triangle.p2 = face.Vertices[face.Indices[i + 1]].Position; | ||
14456 | triangle.p3 = face.Vertices[face.Indices[i + 2]].Position; | ||
14457 | AddRayInTri(triangle, rayTrans, ref rayHits); | ||
14458 | } | ||
14459 | } | ||
14460 | } | ||
14461 | } | ||
14462 | |||
14463 | /// <summary> | ||
14464 | /// Helper to parse Tri (triangle) List for ray hits. | ||
14465 | /// </summary> | ||
14466 | private void AddRayInTris(List<Tri> triangles, RayTrans rayTrans, ref List<RayHit> rayHits) | ||
14467 | { | ||
14468 | foreach (Tri triangle in triangles) | ||
14469 | { | ||
14470 | AddRayInTri(triangle, rayTrans, ref rayHits); | ||
14471 | } | ||
14472 | } | ||
14473 | |||
14474 | /// <summary> | ||
14475 | /// Helper to add ray hit in a Tri (triangle). | ||
14476 | /// </summary> | ||
14477 | private void AddRayInTri(Tri triProj, RayTrans rayTrans, ref List<RayHit> rayHits) | ||
14478 | { | ||
14479 | // Check for hit in triangle | ||
14480 | Vector3 posHitProj; | ||
14481 | Vector3 normalProj; | ||
14482 | if (HitRayInTri(triProj, rayTrans.Position1RayProj, rayTrans.VectorRayProj, out posHitProj, out normalProj)) | ||
14483 | { | ||
14484 | // Hack to circumvent ghost face bug in PrimMesher by removing hits in (ghost) face plane through shape center | ||
14485 | if (Math.Abs(Vector3.Dot(posHitProj, normalProj)) < m_floatToleranceInCastRay && !rayTrans.ShapeNeedsEnds) | ||
14486 | return; | ||
14487 | |||
14488 | // Transform hit and normal to region coordinate system | ||
14489 | Vector3 posHit = rayTrans.PositionPart + (posHitProj * rayTrans.ScalePart) * rayTrans.RotationPart; | ||
14490 | Vector3 normal = Vector3.Normalize((normalProj * rayTrans.ScalePart) * rayTrans.RotationPart); | ||
14491 | |||
14492 | // Remove duplicate hits at triangle intersections | ||
14493 | float distance = Vector3.Distance(rayTrans.Position1Ray, posHit); | ||
14494 | for (int i = rayHits.Count - 1; i >= 0; i--) | ||
14495 | { | ||
14496 | if (rayHits[i].PartId != rayTrans.PartId) | ||
14497 | break; | ||
14498 | if (Math.Abs(rayHits[i].Distance - distance) < m_floatTolerance2InCastRay) | ||
14499 | return; | ||
14500 | } | ||
14501 | |||
14502 | // Build result data set | ||
14503 | RayHit rayHit = new RayHit(); | ||
14504 | rayHit.PartId = rayTrans.PartId; | ||
14505 | rayHit.GroupId = rayTrans.GroupId; | ||
14506 | rayHit.Link = rayTrans.Link; | ||
14507 | rayHit.Position = posHit; | ||
14508 | rayHit.Normal = normal; | ||
14509 | rayHit.Distance = distance; | ||
14510 | rayHits.Add(rayHit); | ||
14511 | } | ||
14512 | } | ||
14513 | |||
14514 | /// <summary> | ||
14515 | /// Helper to find ray hit in triangle | ||
14516 | /// </summary> | ||
14517 | bool HitRayInTri(Tri triProj, Vector3 pos1RayProj, Vector3 vecRayProj, out Vector3 posHitProj, out Vector3 normalProj) | ||
14518 | { | ||
14519 | float tol = m_floatToleranceInCastRay; | ||
14520 | posHitProj = Vector3.Zero; | ||
14521 | |||
14522 | // Calculate triangle edge vectors | ||
14523 | Vector3 vec1Proj = triProj.p2 - triProj.p1; | ||
14524 | Vector3 vec2Proj = triProj.p3 - triProj.p2; | ||
14525 | Vector3 vec3Proj = triProj.p1 - triProj.p3; | ||
14526 | |||
14527 | // Calculate triangle normal | ||
14528 | normalProj = Vector3.Cross(vec1Proj, vec2Proj); | ||
14529 | |||
14530 | // Skip if degenerate triangle or ray parallell with triangle plane | ||
14531 | float divisor = Vector3.Dot(vecRayProj, normalProj); | ||
14532 | if (Math.Abs(divisor) < tol) | ||
14533 | return false; | ||
14534 | |||
14535 | // Skip if exit and not configured to detect | ||
14536 | if (divisor > tol && !m_detectExitsInCastRay) | ||
14537 | return false; | ||
14538 | |||
14539 | // Skip if outside ray ends | ||
14540 | float distanceProj = Vector3.Dot(triProj.p1 - pos1RayProj, normalProj) / divisor; | ||
14541 | if (distanceProj < -tol || distanceProj > 1 + tol) | ||
14542 | return false; | ||
14543 | |||
14544 | // Calculate hit position in triangle | ||
14545 | posHitProj = pos1RayProj + vecRayProj * distanceProj; | ||
14546 | |||
14547 | // Skip if outside triangle bounding box | ||
14548 | Vector3 triProjMin = Vector3.Min(Vector3.Min(triProj.p1, triProj.p2), triProj.p3); | ||
14549 | Vector3 triProjMax = Vector3.Max(Vector3.Max(triProj.p1, triProj.p2), triProj.p3); | ||
14550 | if ( | ||
14551 | posHitProj.X < triProjMin.X - tol || posHitProj.Y < triProjMin.Y - tol || posHitProj.Z < triProjMin.Z - tol || | ||
14552 | posHitProj.X > triProjMax.X + tol || posHitProj.Y > triProjMax.Y + tol || posHitProj.Z > triProjMax.Z + tol | ||
14553 | ) | ||
14554 | return false; | ||
14555 | |||
14556 | // Skip if outside triangle | ||
14557 | if ( | ||
14558 | Vector3.Dot(Vector3.Cross(vec1Proj, normalProj), posHitProj - triProj.p1) > tol || | ||
14559 | Vector3.Dot(Vector3.Cross(vec2Proj, normalProj), posHitProj - triProj.p2) > tol || | ||
14560 | Vector3.Dot(Vector3.Cross(vec3Proj, normalProj), posHitProj - triProj.p3) > tol | ||
14561 | ) | ||
14562 | return false; | ||
14563 | |||
14564 | // Return hit | ||
14565 | return true; | ||
14566 | } | ||
14567 | |||
14568 | /// <summary> | ||
14569 | /// Helper to parse selected parts of HeightMap into a Tri (triangle) List and calculate bounding box. | ||
14570 | /// </summary> | ||
14571 | private List<Tri> TrisFromHeightmapUnderRay(Vector3 posStart, Vector3 posEnd, out Vector3 lower, out Vector3 upper) | ||
14572 | { | ||
14573 | // Get bounding X-Y rectangle of terrain under ray | ||
14574 | lower = Vector3.Min(posStart, posEnd); | ||
14575 | upper = Vector3.Max(posStart, posEnd); | ||
14576 | lower.X = (float)Math.Floor(lower.X); | ||
14577 | lower.Y = (float)Math.Floor(lower.Y); | ||
14578 | float zLower = float.MaxValue; | ||
14579 | upper.X = (float)Math.Ceiling(upper.X); | ||
14580 | upper.Y = (float)Math.Ceiling(upper.Y); | ||
14581 | float zUpper = float.MinValue; | ||
14582 | |||
14583 | // Initialize Tri (triangle) List | ||
14584 | List<Tri> triangles = new List<Tri>(); | ||
14585 | |||
14586 | // Set parsing lane direction to major ray X-Y axis | ||
14587 | Vector3 vec = posEnd - posStart; | ||
14588 | float xAbs = Math.Abs(vec.X); | ||
14589 | float yAbs = Math.Abs(vec.Y); | ||
14590 | bool bigX = true; | ||
14591 | if (yAbs > xAbs) | ||
14592 | { | ||
14593 | bigX = false; | ||
14594 | vec = vec / yAbs; | ||
14595 | } | ||
14596 | else if (xAbs > yAbs || xAbs > 0.0f) | ||
14597 | vec = vec / xAbs; | ||
14598 | else | ||
14599 | vec = new Vector3(1.0f, 1.0f, 0.0f); | ||
14600 | |||
14601 | // Simplify by start parsing in lower end of lane | ||
14602 | if ((bigX && vec.X < 0.0f) || (!bigX && vec.Y < 0.0f)) | ||
14603 | { | ||
14604 | Vector3 posTemp = posStart; | ||
14605 | posStart = posEnd; | ||
14606 | posEnd = posTemp; | ||
14607 | vec = vec * -1.0f; | ||
14608 | } | ||
14609 | |||
14610 | // First 1x1 rectangle under ray | ||
14611 | float xFloorOld = 0.0f; | ||
14612 | float yFloorOld = 0.0f; | ||
14613 | Vector3 pos = posStart; | ||
14614 | float xFloor = (float)Math.Floor(pos.X); | ||
14615 | float yFloor = (float)Math.Floor(pos.Y); | ||
14616 | AddTrisFromHeightmap(xFloor, yFloor, ref triangles, ref zLower, ref zUpper); | ||
14617 | |||
14618 | // Parse every remaining 1x1 rectangle under ray | ||
14619 | while (pos != posEnd) | ||
14620 | { | ||
14621 | // Next 1x1 rectangle under ray | ||
14622 | xFloorOld = xFloor; | ||
14623 | yFloorOld = yFloor; | ||
14624 | pos = pos + vec; | ||
14625 | |||
14626 | // Clip position to 1x1 rectangle border | ||
14627 | xFloor = (float)Math.Floor(pos.X); | ||
14628 | yFloor = (float)Math.Floor(pos.Y); | ||
14629 | if (bigX && pos.X > xFloor) | ||
14630 | { | ||
14631 | pos.Y -= vec.Y * (pos.X - xFloor); | ||
14632 | pos.X = xFloor; | ||
14633 | } | ||
14634 | else if (!bigX && pos.Y > yFloor) | ||
14635 | { | ||
14636 | pos.X -= vec.X * (pos.Y - yFloor); | ||
14637 | pos.Y = yFloor; | ||
14638 | } | ||
14639 | |||
14640 | // Last 1x1 rectangle under ray | ||
14641 | if ((bigX && pos.X >= posEnd.X) || (!bigX && pos.Y >= posEnd.Y)) | ||
14642 | { | ||
14643 | pos = posEnd; | ||
14644 | xFloor = (float)Math.Floor(pos.X); | ||
14645 | yFloor = (float)Math.Floor(pos.Y); | ||
14646 | } | ||
14647 | |||
14648 | // Add new 1x1 rectangle in lane | ||
14649 | if ((bigX && xFloor != xFloorOld) || (!bigX && yFloor != yFloorOld)) | ||
14650 | AddTrisFromHeightmap(xFloor, yFloor, ref triangles, ref zLower, ref zUpper); | ||
14651 | // Add last 1x1 rectangle in old lane at lane shift | ||
14652 | if (bigX && yFloor != yFloorOld) | ||
14653 | AddTrisFromHeightmap(xFloor, yFloorOld, ref triangles, ref zLower, ref zUpper); | ||
14654 | if (!bigX && xFloor != xFloorOld) | ||
14655 | AddTrisFromHeightmap(xFloorOld, yFloor, ref triangles, ref zLower, ref zUpper); | ||
14656 | } | ||
14657 | |||
14658 | // Finalize bounding box Z | ||
14659 | lower.Z = zLower; | ||
14660 | upper.Z = zUpper; | ||
14661 | |||
14662 | // Done and returning Tri (triangle)List | ||
14663 | return triangles; | ||
14664 | } | ||
14665 | |||
14666 | /// <summary> | ||
14667 | /// Helper to add HeightMap squares into Tri (triangle) List and adjust bounding box. | ||
14668 | /// </summary> | ||
14669 | private void AddTrisFromHeightmap(float xPos, float yPos, ref List<Tri> triangles, ref float zLower, ref float zUpper) | ||
14670 | { | ||
14671 | int xInt = (int)xPos; | ||
14672 | int yInt = (int)yPos; | ||
14673 | |||
14674 | // Corner 1 of 1x1 rectangle | ||
14675 | int x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1); | ||
14676 | int y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1); | ||
14677 | Vector3 pos1 = new Vector3(x, y, (float)World.Heightmap[x, y]); | ||
14678 | // Adjust bounding box | ||
14679 | zLower = Math.Min(zLower, pos1.Z); | ||
14680 | zUpper = Math.Max(zUpper, pos1.Z); | ||
14681 | |||
14682 | // Corner 2 of 1x1 rectangle | ||
14683 | x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1); | ||
14684 | y = Util.Clamp<int>(yInt+1, 0, World.Heightmap.Height - 1); | ||
14685 | Vector3 pos2 = new Vector3(x, y, (float)World.Heightmap[x, y]); | ||
14686 | // Adjust bounding box | ||
14687 | zLower = Math.Min(zLower, pos2.Z); | ||
14688 | zUpper = Math.Max(zUpper, pos2.Z); | ||
14689 | |||
14690 | // Corner 3 of 1x1 rectangle | ||
14691 | x = Util.Clamp<int>(xInt, 0, World.Heightmap.Width - 1); | ||
14692 | y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); | ||
14693 | Vector3 pos3 = new Vector3(x, y, (float)World.Heightmap[x, y]); | ||
14694 | // Adjust bounding box | ||
14695 | zLower = Math.Min(zLower, pos3.Z); | ||
14696 | zUpper = Math.Max(zUpper, pos3.Z); | ||
14697 | |||
14698 | // Corner 4 of 1x1 rectangle | ||
14699 | x = Util.Clamp<int>(xInt+1, 0, World.Heightmap.Width - 1); | ||
14700 | y = Util.Clamp<int>(yInt, 0, World.Heightmap.Height - 1); | ||
14701 | Vector3 pos4 = new Vector3(x, y, (float)World.Heightmap[x, y]); | ||
14702 | // Adjust bounding box | ||
14703 | zLower = Math.Min(zLower, pos4.Z); | ||
14704 | zUpper = Math.Max(zUpper, pos4.Z); | ||
14705 | |||
14706 | // Add triangle 1 | ||
14707 | Tri triangle1 = new Tri(); | ||
14708 | triangle1.p1 = pos1; | ||
14709 | triangle1.p2 = pos2; | ||
14710 | triangle1.p3 = pos3; | ||
14711 | triangles.Add(triangle1); | ||
14712 | |||
14713 | // Add triangle 2 | ||
14714 | Tri triangle2 = new Tri(); | ||
14715 | triangle2.p1 = pos3; | ||
14716 | triangle2.p2 = pos4; | ||
14717 | triangle2.p3 = pos1; | ||
14718 | triangles.Add(triangle2); | ||
14719 | } | ||
14720 | |||
14721 | /// <summary> | ||
14722 | /// Helper to get link number for a UUID. | ||
14723 | /// </summary> | ||
14724 | private int UUID2LinkNumber(SceneObjectPart part, UUID id) | ||
14725 | { | ||
14726 | SceneObjectGroup group = part.ParentGroup; | ||
14727 | if (group != null) | ||
14728 | { | ||
14729 | // Parse every link for UUID | ||
14730 | int linkCount = group.PrimCount + group.GetSittingAvatarsCount(); | ||
14731 | for (int link = linkCount; link > 0; link--) | ||
14732 | { | ||
14733 | ISceneEntity entity = GetLinkEntity(part, link); | ||
14734 | // Return link number if UUID match | ||
14735 | if (entity != null && entity.UUID == id) | ||
14736 | return link; | ||
14737 | } | ||
14738 | } | ||
14739 | // Return link number 0 if no links or UUID matches | ||
14740 | return 0; | ||
14741 | } | ||
14742 | |||
13527 | public LSL_Integer llManageEstateAccess(int action, string avatar) | 14743 | public LSL_Integer llManageEstateAccess(int action, string avatar) |
13528 | { | 14744 | { |
13529 | m_host.AddScriptLPS(1); | 14745 | m_host.AddScriptLPS(1); |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs index d02c91c..4708473 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index a96cd16..e37d3af 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | |||
@@ -596,6 +596,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase | |||
596 | public const int OBJECT_PHYSICS = 21; | 596 | public const int OBJECT_PHYSICS = 21; |
597 | public const int OBJECT_PHANTOM = 22; | 597 | public const int OBJECT_PHANTOM = 22; |
598 | public const int OBJECT_TEMP_ON_REZ = 23; | 598 | public const int OBJECT_TEMP_ON_REZ = 23; |
599 | public const int OBJECT_RENDER_WEIGHT = 24; | ||
600 | public const int OBJECT_HOVER_HEIGHT = 25; | ||
601 | public const int OBJECT_BODY_SHAPE_TYPE = 26; | ||
602 | public const int OBJECT_LAST_OWNER_ID = 27; | ||
599 | 603 | ||
600 | // Pathfinding types | 604 | // Pathfinding types |
601 | public const int OPT_OTHER = -1; | 605 | public const int OPT_OTHER = -1; |
diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs index 31acd44..4df09ef 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs index af7ee26..3eaaed0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs index 03612ef..0094af6 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/Properties/AssemblyInfo.cs | |||
@@ -30,7 +30,7 @@ using Mono.Addins; | |||
30 | // Build Number | 30 | // Build Number |
31 | // Revision | 31 | // Revision |
32 | // | 32 | // |
33 | [assembly: AssemblyVersion("0.8.1.*")] | 33 | [assembly: AssemblyVersion("0.8.2.*")] |
34 | 34 | ||
35 | [assembly: Addin("OpenSim.Region.ScriptEngine.XEngine", OpenSim.VersionInfo.VersionNumber)] | 35 | [assembly: Addin("OpenSim.Region.ScriptEngine.XEngine", OpenSim.VersionInfo.VersionNumber)] |
36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] | 36 | [assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)] |
diff --git a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs index 58fa66f..9fac53e 100644 --- a/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs +++ b/OpenSim/Region/UserStatistics/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Server/Base/Properties/AssemblyInfo.cs b/OpenSim/Server/Base/Properties/AssemblyInfo.cs index 0d583f0..e819a2b 100644 --- a/OpenSim/Server/Base/Properties/AssemblyInfo.cs +++ b/OpenSim/Server/Base/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index d7d1306..1f2c54d 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs | |||
@@ -82,7 +82,9 @@ namespace OpenSim.Server.Base | |||
82 | argvConfig.AddSwitch("Startup", "logconfig", "g"); | 82 | argvConfig.AddSwitch("Startup", "logconfig", "g"); |
83 | 83 | ||
84 | // Automagically create the ini file name | 84 | // Automagically create the ini file name |
85 | string fileName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location); | 85 | string fileName = ""; |
86 | if (Assembly.GetEntryAssembly() != null) | ||
87 | fileName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location); | ||
86 | string iniFile = fileName + ".ini"; | 88 | string iniFile = fileName + ".ini"; |
87 | string logConfig = null; | 89 | string logConfig = null; |
88 | 90 | ||
@@ -158,7 +160,11 @@ namespace OpenSim.Server.Base | |||
158 | MainConsole.Instance = new RemoteConsole(prompt); | 160 | MainConsole.Instance = new RemoteConsole(prompt); |
159 | ((RemoteConsole)MainConsole.Instance).ReadConfig(Config); | 161 | ((RemoteConsole)MainConsole.Instance).ReadConfig(Config); |
160 | } | 162 | } |
161 | else | 163 | else if (consoleType == "mock") |
164 | { | ||
165 | MainConsole.Instance = new MockConsole(); | ||
166 | } | ||
167 | else if (consoleType == "local") | ||
162 | { | 168 | { |
163 | MainConsole.Instance = new LocalConsole(prompt, startupConfig); | 169 | MainConsole.Instance = new LocalConsole(prompt, startupConfig); |
164 | } | 170 | } |
diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index 0288fa6..cf0762b 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs | |||
@@ -41,7 +41,9 @@ using OpenSim.Server.Handlers.Base; | |||
41 | using log4net; | 41 | using log4net; |
42 | using OpenMetaverse; | 42 | using OpenMetaverse; |
43 | 43 | ||
44 | namespace OpenSim.Server.Handlers.Asset | 44 | using System.Threading; |
45 | |||
46 | namespace OpenSim.Server.Handlers.Inventory | ||
45 | { | 47 | { |
46 | public class XInventoryInConnector : ServiceConnector | 48 | public class XInventoryInConnector : ServiceConnector |
47 | { | 49 | { |
@@ -123,6 +125,8 @@ namespace OpenSim.Server.Handlers.Asset | |||
123 | return HandleGetFolderForType(request); | 125 | return HandleGetFolderForType(request); |
124 | case "GETFOLDERCONTENT": | 126 | case "GETFOLDERCONTENT": |
125 | return HandleGetFolderContent(request); | 127 | return HandleGetFolderContent(request); |
128 | case "GETMULTIPLEFOLDERSCONTENT": | ||
129 | return HandleGetMultipleFoldersContent(request); | ||
126 | case "GETFOLDERITEMS": | 130 | case "GETFOLDERITEMS": |
127 | return HandleGetFolderItems(request); | 131 | return HandleGetFolderItems(request); |
128 | case "ADDFOLDER": | 132 | case "ADDFOLDER": |
@@ -145,6 +149,8 @@ namespace OpenSim.Server.Handlers.Asset | |||
145 | return HandleDeleteItems(request); | 149 | return HandleDeleteItems(request); |
146 | case "GETITEM": | 150 | case "GETITEM": |
147 | return HandleGetItem(request); | 151 | return HandleGetItem(request); |
152 | case "GETMULTIPLEITEMS": | ||
153 | return HandleGetMultipleItems(request); | ||
148 | case "GETFOLDER": | 154 | case "GETFOLDER": |
149 | return HandleGetFolder(request); | 155 | return HandleGetFolder(request); |
150 | case "GETACTIVEGESTURES": | 156 | case "GETACTIVEGESTURES": |
@@ -284,6 +290,8 @@ namespace OpenSim.Server.Handlers.Asset | |||
284 | InventoryCollection icoll = m_InventoryService.GetFolderContent(principal, folderID); | 290 | InventoryCollection icoll = m_InventoryService.GetFolderContent(principal, folderID); |
285 | if (icoll != null) | 291 | if (icoll != null) |
286 | { | 292 | { |
293 | result["FID"] = icoll.FolderID.ToString(); | ||
294 | result["VERSION"] = icoll.Version.ToString(); | ||
287 | Dictionary<string, object> folders = new Dictionary<string, object>(); | 295 | Dictionary<string, object> folders = new Dictionary<string, object>(); |
288 | int i = 0; | 296 | int i = 0; |
289 | if (icoll.Folders != null) | 297 | if (icoll.Folders != null) |
@@ -314,7 +322,71 @@ namespace OpenSim.Server.Handlers.Asset | |||
314 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | 322 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); |
315 | } | 323 | } |
316 | 324 | ||
317 | byte[] HandleGetFolderItems(Dictionary<string,object> request) | 325 | byte[] HandleGetMultipleFoldersContent(Dictionary<string, object> request) |
326 | { | ||
327 | Dictionary<string, object> resultSet = new Dictionary<string, object>(); | ||
328 | UUID principal = UUID.Zero; | ||
329 | UUID.TryParse(request["PRINCIPAL"].ToString(), out principal); | ||
330 | string folderIDstr = request["FOLDERS"].ToString(); | ||
331 | int count = 0; | ||
332 | Int32.TryParse(request["COUNT"].ToString(), out count); | ||
333 | |||
334 | UUID[] fids = new UUID[count]; | ||
335 | string[] uuids = folderIDstr.Split(','); | ||
336 | int i = 0; | ||
337 | foreach (string id in uuids) | ||
338 | { | ||
339 | UUID fid = UUID.Zero; | ||
340 | if (UUID.TryParse(id, out fid)) | ||
341 | fids[i] = fid; | ||
342 | i += 1; | ||
343 | } | ||
344 | |||
345 | count = 0; | ||
346 | InventoryCollection[] icollList = m_InventoryService.GetMultipleFoldersContent(principal, fids); | ||
347 | if (icollList != null && icollList.Length > 0) | ||
348 | { | ||
349 | foreach (InventoryCollection icoll in icollList) | ||
350 | { | ||
351 | Dictionary<string, object> result = new Dictionary<string, object>(); | ||
352 | result["FID"] = icoll.FolderID.ToString(); | ||
353 | result["VERSION"] = icoll.Version.ToString(); | ||
354 | result["OWNER"] = icoll.OwnerID.ToString(); | ||
355 | Dictionary<string, object> folders = new Dictionary<string, object>(); | ||
356 | i = 0; | ||
357 | if (icoll.Folders != null) | ||
358 | { | ||
359 | foreach (InventoryFolderBase f in icoll.Folders) | ||
360 | { | ||
361 | folders["folder_" + i.ToString()] = EncodeFolder(f); | ||
362 | i++; | ||
363 | } | ||
364 | result["FOLDERS"] = folders; | ||
365 | } | ||
366 | i = 0; | ||
367 | if (icoll.Items != null) | ||
368 | { | ||
369 | Dictionary<string, object> items = new Dictionary<string, object>(); | ||
370 | foreach (InventoryItemBase it in icoll.Items) | ||
371 | { | ||
372 | items["item_" + i.ToString()] = EncodeItem(it); | ||
373 | i++; | ||
374 | } | ||
375 | result["ITEMS"] = items; | ||
376 | } | ||
377 | |||
378 | resultSet["F_" + fids[count++]] = result; | ||
379 | //m_log.DebugFormat("[XXX]: Sending {0} {1}", fids[count-1], icoll.FolderID); | ||
380 | } | ||
381 | } | ||
382 | |||
383 | string xmlString = ServerUtils.BuildXmlResponse(resultSet); | ||
384 | |||
385 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
386 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
387 | } | ||
388 | |||
389 | byte[] HandleGetFolderItems(Dictionary<string, object> request) | ||
318 | { | 390 | { |
319 | Dictionary<string,object> result = new Dictionary<string,object>(); | 391 | Dictionary<string,object> result = new Dictionary<string,object>(); |
320 | UUID principal = UUID.Zero; | 392 | UUID principal = UUID.Zero; |
@@ -506,6 +578,40 @@ namespace OpenSim.Server.Handlers.Asset | |||
506 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | 578 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); |
507 | } | 579 | } |
508 | 580 | ||
581 | byte[] HandleGetMultipleItems(Dictionary<string, object> request) | ||
582 | { | ||
583 | Dictionary<string, object> resultSet = new Dictionary<string, object>(); | ||
584 | UUID principal = UUID.Zero; | ||
585 | UUID.TryParse(request["PRINCIPAL"].ToString(), out principal); | ||
586 | string itemIDstr = request["ITEMS"].ToString(); | ||
587 | int count = 0; | ||
588 | Int32.TryParse(request["COUNT"].ToString(), out count); | ||
589 | |||
590 | UUID[] fids = new UUID[count]; | ||
591 | string[] uuids = itemIDstr.Split(','); | ||
592 | int i = 0; | ||
593 | foreach (string id in uuids) | ||
594 | { | ||
595 | UUID fid = UUID.Zero; | ||
596 | if (UUID.TryParse(id, out fid)) | ||
597 | fids[i] = fid; | ||
598 | i += 1; | ||
599 | } | ||
600 | |||
601 | InventoryItemBase[] itemsList = m_InventoryService.GetMultipleItems(principal, fids); | ||
602 | if (itemsList != null && itemsList.Length > 0) | ||
603 | { | ||
604 | count = 0; | ||
605 | foreach (InventoryItemBase item in itemsList) | ||
606 | resultSet["item_" + count++] = (item == null) ? (object)"NULL" : EncodeItem(item); | ||
607 | } | ||
608 | |||
609 | string xmlString = ServerUtils.BuildXmlResponse(resultSet); | ||
610 | |||
611 | //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString); | ||
612 | return Util.UTF8NoBomEncoding.GetBytes(xmlString); | ||
613 | } | ||
614 | |||
509 | byte[] HandleGetFolder(Dictionary<string,object> request) | 615 | byte[] HandleGetFolder(Dictionary<string,object> request) |
510 | { | 616 | { |
511 | Dictionary<string, object> result = new Dictionary<string, object>(); | 617 | Dictionary<string, object> result = new Dictionary<string, object>(); |
diff --git a/OpenSim/Server/Handlers/Properties/AssemblyInfo.cs b/OpenSim/Server/Handlers/Properties/AssemblyInfo.cs index 04fe41a..780e454 100644 --- a/OpenSim/Server/Handlers/Properties/AssemblyInfo.cs +++ b/OpenSim/Server/Handlers/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs index a77d78e..21eb790 100644 --- a/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs +++ b/OpenSim/Server/Handlers/UserAccounts/UserAccountServerPostHandler.cs | |||
@@ -257,8 +257,7 @@ namespace OpenSim.Server.Handlers.UserAccounts | |||
257 | 257 | ||
258 | byte[] CreateUser(Dictionary<string, object> request) | 258 | byte[] CreateUser(Dictionary<string, object> request) |
259 | { | 259 | { |
260 | if (! | 260 | if (! request.ContainsKey("FirstName") |
261 | request.ContainsKey("FirstName") | ||
262 | && request.ContainsKey("LastName") | 261 | && request.ContainsKey("LastName") |
263 | && request.ContainsKey("Password")) | 262 | && request.ContainsKey("Password")) |
264 | return FailureResult(); | 263 | return FailureResult(); |
diff --git a/OpenSim/Services/AssetService/Properties/AssemblyInfo.cs b/OpenSim/Services/AssetService/Properties/AssemblyInfo.cs index 96391aa..9717319 100644 --- a/OpenSim/Services/AssetService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/AssetService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs b/OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs index 46fc1d5..8c63adc 100644 --- a/OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/AuthenticationService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs b/OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs index e04ea3f..ce91b56 100644 --- a/OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/AuthorizationService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs b/OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs index cf419ff..1778863 100644 --- a/OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/AvatarService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/Base/Properties/AssemblyInfo.cs b/OpenSim/Services/Base/Properties/AssemblyInfo.cs index 328e011..a3fb11b 100644 --- a/OpenSim/Services/Base/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/Base/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs b/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs index 37f9374..6412bcd 100644 --- a/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs +++ b/OpenSim/Services/Connectors/Estate/EstateDataConnector.cs | |||
@@ -40,7 +40,7 @@ using OpenSim.Services.Connectors; | |||
40 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
41 | using OpenSim.Server.Base; | 41 | using OpenSim.Server.Base; |
42 | 42 | ||
43 | namespace OpenSim.Service.Connectors | 43 | namespace OpenSim.Services.Connectors |
44 | { | 44 | { |
45 | public class EstateDataRemoteConnector : BaseServiceConnector, IEstateDataService | 45 | public class EstateDataRemoteConnector : BaseServiceConnector, IEstateDataService |
46 | { | 46 | { |
diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs index 574de89..db3c857 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryServicesConnector.cs | |||
@@ -205,7 +205,7 @@ namespace OpenSim.Services.Connectors | |||
205 | InventoryCollection inventory = new InventoryCollection(); | 205 | InventoryCollection inventory = new InventoryCollection(); |
206 | inventory.Folders = new List<InventoryFolderBase>(); | 206 | inventory.Folders = new List<InventoryFolderBase>(); |
207 | inventory.Items = new List<InventoryItemBase>(); | 207 | inventory.Items = new List<InventoryItemBase>(); |
208 | inventory.UserID = principalID; | 208 | inventory.OwnerID = principalID; |
209 | 209 | ||
210 | try | 210 | try |
211 | { | 211 | { |
@@ -235,6 +235,87 @@ namespace OpenSim.Services.Connectors | |||
235 | 235 | ||
236 | return inventory; | 236 | return inventory; |
237 | } | 237 | } |
238 | |||
239 | public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs) | ||
240 | { | ||
241 | InventoryCollection[] inventoryArr = new InventoryCollection[folderIDs.Length]; | ||
242 | //m_log.DebugFormat("[XXX]: In GetMultipleFoldersContent {0}", folderIDs.Length); | ||
243 | try | ||
244 | { | ||
245 | Dictionary<string, object> resultSet = MakeRequest("GETMULTIPLEFOLDERSCONTENT", | ||
246 | new Dictionary<string, object> { | ||
247 | { "PRINCIPAL", principalID.ToString() }, | ||
248 | { "FOLDERS", String.Join(",", folderIDs) }, | ||
249 | { "COUNT", folderIDs.Length.ToString() } | ||
250 | }); | ||
251 | |||
252 | if (!CheckReturn(resultSet)) | ||
253 | return null; | ||
254 | |||
255 | int i = 0; | ||
256 | foreach (KeyValuePair<string, object> kvp in resultSet) | ||
257 | { | ||
258 | InventoryCollection inventory = new InventoryCollection(); | ||
259 | if (kvp.Key.StartsWith("F_")) | ||
260 | { | ||
261 | UUID fid = UUID.Zero; | ||
262 | if (UUID.TryParse(kvp.Key.Substring(2), out fid) && fid == folderIDs[i]) | ||
263 | { | ||
264 | inventory.Folders = new List<InventoryFolderBase>(); | ||
265 | inventory.Items = new List<InventoryItemBase>(); | ||
266 | |||
267 | Dictionary<string, object> ret = (Dictionary<string, object>)kvp.Value; | ||
268 | |||
269 | if (ret.ContainsKey("FID")) | ||
270 | { | ||
271 | if (!UUID.TryParse(ret["FID"].ToString(), out inventory.FolderID)) | ||
272 | m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Could not parse folder id {0}", ret["FID"].ToString()); | ||
273 | } | ||
274 | else | ||
275 | m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: FID key not present in response"); | ||
276 | |||
277 | inventory.Version = -1; | ||
278 | if (ret.ContainsKey("VERSION")) | ||
279 | Int32.TryParse(ret["VERSION"].ToString(), out inventory.Version); | ||
280 | if (ret.ContainsKey("OWNER")) | ||
281 | UUID.TryParse(ret["OWNER"].ToString(), out inventory.OwnerID); | ||
282 | |||
283 | //m_log.DebugFormat("[XXX]: Received {0} ({1}) {2} {3}", inventory.FolderID, fid, inventory.Version, inventory.OwnerID); | ||
284 | |||
285 | Dictionary<string, object> folders = | ||
286 | (Dictionary<string, object>)ret["FOLDERS"]; | ||
287 | Dictionary<string, object> items = | ||
288 | (Dictionary<string, object>)ret["ITEMS"]; | ||
289 | |||
290 | foreach (Object o in folders.Values) // getting the values directly, we don't care about the keys folder_i | ||
291 | { | ||
292 | inventory.Folders.Add(BuildFolder((Dictionary<string, object>)o)); | ||
293 | } | ||
294 | foreach (Object o in items.Values) // getting the values directly, we don't care about the keys item_i | ||
295 | { | ||
296 | inventory.Items.Add(BuildItem((Dictionary<string, object>)o)); | ||
297 | } | ||
298 | |||
299 | inventoryArr[i] = inventory; | ||
300 | } | ||
301 | else | ||
302 | { | ||
303 | m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Folder id does not match. Expected {0} got {1}", | ||
304 | folderIDs[i], fid); | ||
305 | m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: {0} {1}", String.Join(",", folderIDs), String.Join(",", resultSet.Keys)); | ||
306 | } | ||
307 | |||
308 | i += 1; | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | catch (Exception e) | ||
313 | { | ||
314 | m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleFoldersContent: {0}", e.Message); | ||
315 | } | ||
316 | |||
317 | return inventoryArr; | ||
318 | } | ||
238 | 319 | ||
239 | public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) | 320 | public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) |
240 | { | 321 | { |
@@ -325,9 +406,13 @@ namespace OpenSim.Services.Connectors | |||
325 | 406 | ||
326 | public bool AddItem(InventoryItemBase item) | 407 | public bool AddItem(InventoryItemBase item) |
327 | { | 408 | { |
409 | if (item.Description == null) | ||
410 | item.Description = String.Empty; | ||
328 | if (item.CreatorData == null) | 411 | if (item.CreatorData == null) |
329 | item.CreatorData = String.Empty; | 412 | item.CreatorData = String.Empty; |
330 | Dictionary<string,object> ret = MakeRequest("ADDITEM", | 413 | if (item.CreatorId == null) |
414 | item.CreatorId = String.Empty; | ||
415 | Dictionary<string, object> ret = MakeRequest("ADDITEM", | ||
331 | new Dictionary<string,object> { | 416 | new Dictionary<string,object> { |
332 | { "AssetID", item.AssetID.ToString() }, | 417 | { "AssetID", item.AssetID.ToString() }, |
333 | { "AssetType", item.AssetType.ToString() }, | 418 | { "AssetType", item.AssetType.ToString() }, |
@@ -446,6 +531,42 @@ namespace OpenSim.Services.Connectors | |||
446 | return null; | 531 | return null; |
447 | } | 532 | } |
448 | 533 | ||
534 | public virtual InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs) | ||
535 | { | ||
536 | InventoryItemBase[] itemArr = new InventoryItemBase[itemIDs.Length]; | ||
537 | try | ||
538 | { | ||
539 | Dictionary<string, object> resultSet = MakeRequest("GETMULTIPLEITEMS", | ||
540 | new Dictionary<string, object> { | ||
541 | { "PRINCIPAL", principalID.ToString() }, | ||
542 | { "ITEMS", String.Join(",", itemIDs) }, | ||
543 | { "COUNT", itemIDs.Length.ToString() } | ||
544 | }); | ||
545 | |||
546 | if (!CheckReturn(resultSet)) | ||
547 | return null; | ||
548 | |||
549 | int i = 0; | ||
550 | foreach (KeyValuePair<string, object> kvp in resultSet) | ||
551 | { | ||
552 | InventoryCollection inventory = new InventoryCollection(); | ||
553 | if (kvp.Key.StartsWith("item_")) | ||
554 | { | ||
555 | if (kvp.Value is Dictionary<string, object>) | ||
556 | itemArr[i++] = BuildItem((Dictionary<string, object>)kvp.Value); | ||
557 | else | ||
558 | itemArr[i++] = null; | ||
559 | } | ||
560 | } | ||
561 | } | ||
562 | catch (Exception e) | ||
563 | { | ||
564 | m_log.WarnFormat("[XINVENTORY SERVICES CONNECTOR]: Exception in GetMultipleItems: {0}", e.Message); | ||
565 | } | ||
566 | |||
567 | return itemArr; | ||
568 | } | ||
569 | |||
449 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) | 570 | public InventoryFolderBase GetFolder(InventoryFolderBase folder) |
450 | { | 571 | { |
451 | try | 572 | try |
diff --git a/OpenSim/Services/Connectors/Properties/AssemblyInfo.cs b/OpenSim/Services/Connectors/Properties/AssemblyInfo.cs index bb78cfd..2af2ec1 100644 --- a/OpenSim/Services/Connectors/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/Connectors/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs index 9ded1c4..fdeea18 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs | |||
@@ -301,6 +301,21 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
301 | return null; | 301 | return null; |
302 | } | 302 | } |
303 | 303 | ||
304 | public InventoryItemBase[] GetMultipleItems(UUID principalID, UUID[] itemIDs) | ||
305 | { | ||
306 | InventoryItemBase[] result = new InventoryItemBase[itemIDs.Length]; | ||
307 | int i = 0; | ||
308 | InventoryItemBase item = new InventoryItemBase(); | ||
309 | item.Owner = principalID; | ||
310 | foreach (UUID id in itemIDs) | ||
311 | { | ||
312 | item.ID = id; | ||
313 | result[i++] = GetItem(item); | ||
314 | } | ||
315 | |||
316 | return result; | ||
317 | } | ||
318 | |||
304 | /// <summary> | 319 | /// <summary> |
305 | /// Get a folder, given by its UUID | 320 | /// Get a folder, given by its UUID |
306 | /// </summary> | 321 | /// </summary> |
@@ -340,7 +355,7 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
340 | public InventoryCollection GetFolderContent(UUID userID, UUID folderID) | 355 | public InventoryCollection GetFolderContent(UUID userID, UUID folderID) |
341 | { | 356 | { |
342 | InventoryCollection inventory = new InventoryCollection(); | 357 | InventoryCollection inventory = new InventoryCollection(); |
343 | inventory.UserID = userID; | 358 | inventory.OwnerID = userID; |
344 | 359 | ||
345 | NameValueCollection requestArgs = new NameValueCollection | 360 | NameValueCollection requestArgs = new NameValueCollection |
346 | { | 361 | { |
@@ -371,6 +386,18 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
371 | return inventory; | 386 | return inventory; |
372 | } | 387 | } |
373 | 388 | ||
389 | public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs) | ||
390 | { | ||
391 | InventoryCollection[] invColl = new InventoryCollection[folderIDs.Length]; | ||
392 | int i = 0; | ||
393 | foreach (UUID fid in folderIDs) | ||
394 | { | ||
395 | invColl[i++] = GetFolderContent(principalID, fid); | ||
396 | } | ||
397 | |||
398 | return invColl; | ||
399 | } | ||
400 | |||
374 | /// <summary> | 401 | /// <summary> |
375 | /// Gets the items inside a folder | 402 | /// Gets the items inside a folder |
376 | /// </summary> | 403 | /// </summary> |
@@ -380,7 +407,7 @@ namespace OpenSim.Services.Connectors.SimianGrid | |||
380 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) | 407 | public List<InventoryItemBase> GetFolderItems(UUID userID, UUID folderID) |
381 | { | 408 | { |
382 | InventoryCollection inventory = new InventoryCollection(); | 409 | InventoryCollection inventory = new InventoryCollection(); |
383 | inventory.UserID = userID; | 410 | inventory.OwnerID = userID; |
384 | 411 | ||
385 | NameValueCollection requestArgs = new NameValueCollection | 412 | NameValueCollection requestArgs = new NameValueCollection |
386 | { | 413 | { |
diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs index 3f61d9a..560e6c4 100644 --- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs +++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServicesConnector.cs | |||
@@ -215,9 +215,39 @@ namespace OpenSim.Services.Connectors | |||
215 | sendData[kvp.Key] = kvp.Value.ToString(); | 215 | sendData[kvp.Key] = kvp.Value.ToString(); |
216 | } | 216 | } |
217 | 217 | ||
218 | return SendAndGetBoolReply(sendData); | 218 | if (SendAndGetReply(sendData) != null) |
219 | return true; | ||
220 | else | ||
221 | return false; | ||
219 | } | 222 | } |
220 | 223 | ||
224 | /// <summary> | ||
225 | /// Create user remotely. Note this this is not part of the IUserAccountsService | ||
226 | /// </summary> | ||
227 | /// <param name="first"></param> | ||
228 | /// <param name="last"></param> | ||
229 | /// <param name="password"></param> | ||
230 | /// <param name="email"></param> | ||
231 | /// <param name="scopeID"></param> | ||
232 | /// <returns></returns> | ||
233 | public virtual UserAccount CreateUser(string first, string last, string password, string email, UUID scopeID) | ||
234 | { | ||
235 | Dictionary<string, object> sendData = new Dictionary<string, object>(); | ||
236 | //sendData["SCOPEID"] = scopeID.ToString(); | ||
237 | sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); | ||
238 | sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); | ||
239 | sendData["METHOD"] = "createuser"; | ||
240 | |||
241 | sendData["FirstName"] = first; | ||
242 | sendData["LastName"] = last; | ||
243 | sendData["Password"] = password; | ||
244 | if (!string.IsNullOrEmpty(email)) | ||
245 | sendData["Email"] = first; | ||
246 | sendData["ScopeID"] = scopeID.ToString(); | ||
247 | |||
248 | return SendAndGetReply(sendData); | ||
249 | } | ||
250 | |||
221 | private UserAccount SendAndGetReply(Dictionary<string, object> sendData) | 251 | private UserAccount SendAndGetReply(Dictionary<string, object> sendData) |
222 | { | 252 | { |
223 | string reply = string.Empty; | 253 | string reply = string.Empty; |
@@ -260,7 +290,7 @@ namespace OpenSim.Services.Connectors | |||
260 | { | 290 | { |
261 | string reqString = ServerUtils.BuildQueryString(sendData); | 291 | string reqString = ServerUtils.BuildQueryString(sendData); |
262 | string uri = m_ServerURI + "/accounts"; | 292 | string uri = m_ServerURI + "/accounts"; |
263 | // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); | 293 | //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: queryString = {0}", reqString); |
264 | try | 294 | try |
265 | { | 295 | { |
266 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", | 296 | string reply = SynchronousRestFormsRequester.MakeRequest("POST", |
@@ -269,6 +299,7 @@ namespace OpenSim.Services.Connectors | |||
269 | m_Auth); | 299 | m_Auth); |
270 | if (reply != string.Empty) | 300 | if (reply != string.Empty) |
271 | { | 301 | { |
302 | //m_log.DebugFormat("[ACCOUNTS CONNECTOR]: reply = {0}", reply); | ||
272 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); | 303 | Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); |
273 | 304 | ||
274 | if (replyData.ContainsKey("result")) | 305 | if (replyData.ContainsKey("result")) |
diff --git a/OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs b/OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs index 3a50af3..ca16f08 100644 --- a/OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/FreeswitchService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/Friends/Properties/AssemblyInfo.cs b/OpenSim/Services/Friends/Properties/AssemblyInfo.cs index d47e877..f258f94 100644 --- a/OpenSim/Services/Friends/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/Friends/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/GridService/Properties/AssemblyInfo.cs b/OpenSim/Services/GridService/Properties/AssemblyInfo.cs index 6703b3c..ebe3c44 100644 --- a/OpenSim/Services/GridService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/GridService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/HypergridService/HGAssetService.cs b/OpenSim/Services/HypergridService/HGAssetService.cs index b57f8d8..a829932 100644 --- a/OpenSim/Services/HypergridService/HGAssetService.cs +++ b/OpenSim/Services/HypergridService/HGAssetService.cs | |||
@@ -163,7 +163,7 @@ namespace OpenSim.Services.HypergridService | |||
163 | protected byte[] AdjustIdentifiers(byte[] data) | 163 | protected byte[] AdjustIdentifiers(byte[] data) |
164 | { | 164 | { |
165 | string xml = Utils.BytesToString(data); | 165 | string xml = Utils.BytesToString(data); |
166 | return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, m_HomeURL, m_Cache, UUID.Zero)); | 166 | return Utils.StringToBytes(ExternalRepresentationUtils.RewriteSOP(xml, "HGAssetService", m_HomeURL, m_Cache, UUID.Zero)); |
167 | } | 167 | } |
168 | 168 | ||
169 | } | 169 | } |
diff --git a/OpenSim/Services/HypergridService/HGInstantMessageService.cs b/OpenSim/Services/HypergridService/HGInstantMessageService.cs index 9b7b278..32ca09a 100644 --- a/OpenSim/Services/HypergridService/HGInstantMessageService.cs +++ b/OpenSim/Services/HypergridService/HGInstantMessageService.cs | |||
@@ -101,7 +101,14 @@ namespace OpenSim.Services.HypergridService | |||
101 | Object[] args = new Object[] { config }; | 101 | Object[] args = new Object[] { config }; |
102 | m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args); | 102 | m_GridService = ServerUtils.LoadPlugin<IGridService>(gridService, args); |
103 | m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args); | 103 | m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(presenceService, args); |
104 | m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(userAgentService, args); | 104 | try |
105 | { | ||
106 | m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(userAgentService, args); | ||
107 | } | ||
108 | catch | ||
109 | { | ||
110 | m_log.WarnFormat("[HG IM SERVICE]: Unable to create User Agent Service. Missing config var in [HGInstantMessageService]?"); | ||
111 | } | ||
105 | 112 | ||
106 | m_RegionCache = new ExpiringCache<UUID, GridRegion>(); | 113 | m_RegionCache = new ExpiringCache<UUID, GridRegion>(); |
107 | 114 | ||
diff --git a/OpenSim/Services/HypergridService/HGInventoryService.cs b/OpenSim/Services/HypergridService/HGInventoryService.cs index 2c63240..5f245e4 100644 --- a/OpenSim/Services/HypergridService/HGInventoryService.cs +++ b/OpenSim/Services/HypergridService/HGInventoryService.cs | |||
@@ -153,7 +153,14 @@ namespace OpenSim.Services.HypergridService | |||
153 | //public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) | 153 | //public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) |
154 | //{ | 154 | //{ |
155 | //} | 155 | //} |
156 | 156 | ||
157 | // NOGO | ||
158 | // | ||
159 | public override InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderID) | ||
160 | { | ||
161 | return new InventoryCollection[0]; | ||
162 | } | ||
163 | |||
157 | //public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) | 164 | //public List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) |
158 | //{ | 165 | //{ |
159 | //} | 166 | //} |
diff --git a/OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs b/OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs index 5294a50..a565729 100644 --- a/OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/HypergridService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/Interfaces/IInventoryService.cs b/OpenSim/Services/Interfaces/IInventoryService.cs index 2805356..1e8652c 100644 --- a/OpenSim/Services/Interfaces/IInventoryService.cs +++ b/OpenSim/Services/Interfaces/IInventoryService.cs | |||
@@ -76,6 +76,14 @@ namespace OpenSim.Services.Interfaces | |||
76 | /// <param name="folderID"></param> | 76 | /// <param name="folderID"></param> |
77 | /// <returns>Inventory content. null if the request failed.</returns> | 77 | /// <returns>Inventory content. null if the request failed.</returns> |
78 | InventoryCollection GetFolderContent(UUID userID, UUID folderID); | 78 | InventoryCollection GetFolderContent(UUID userID, UUID folderID); |
79 | |||
80 | /// <summary> | ||
81 | /// Gets everything (folders and items) inside a folder | ||
82 | /// </summary> | ||
83 | /// <param name="userId"></param> | ||
84 | /// <param name="folderIDs"></param> | ||
85 | /// <returns>Inventory content.</returns> | ||
86 | InventoryCollection[] GetMultipleFoldersContent(UUID userID, UUID[] folderIDs); | ||
79 | 87 | ||
80 | /// <summary> | 88 | /// <summary> |
81 | /// Gets the items inside a folder | 89 | /// Gets the items inside a folder |
@@ -156,6 +164,13 @@ namespace OpenSim.Services.Interfaces | |||
156 | InventoryItemBase GetItem(InventoryItemBase item); | 164 | InventoryItemBase GetItem(InventoryItemBase item); |
157 | 165 | ||
158 | /// <summary> | 166 | /// <summary> |
167 | /// Get multiple items, given by their UUIDs | ||
168 | /// </summary> | ||
169 | /// <param name="item"></param> | ||
170 | /// <returns>null if no item was found, otherwise the found item</returns> | ||
171 | InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] ids); | ||
172 | |||
173 | /// <summary> | ||
159 | /// Get a folder, given by its UUID | 174 | /// Get a folder, given by its UUID |
160 | /// </summary> | 175 | /// </summary> |
161 | /// <param name="folder"></param> | 176 | /// <param name="folder"></param> |
diff --git a/OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs b/OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs index b4fd068..a2f6c4f 100644 --- a/OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/Interfaces/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs b/OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs index 094e515..6a1187c 100644 --- a/OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/InventoryService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 362ff8f..64f727c 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs | |||
@@ -261,7 +261,7 @@ namespace OpenSim.Services.InventoryService | |||
261 | 261 | ||
262 | private InventoryFolderBase GetSystemFolderForType(InventoryFolderBase rootFolder, AssetType type) | 262 | private InventoryFolderBase GetSystemFolderForType(InventoryFolderBase rootFolder, AssetType type) |
263 | { | 263 | { |
264 | // m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0} for user {1}", type, principalID); | 264 | //m_log.DebugFormat("[XINVENTORY SERVICE]: Getting folder type {0}", type); |
265 | 265 | ||
266 | if (type == AssetType.RootFolder) | 266 | if (type == AssetType.RootFolder) |
267 | return rootFolder; | 267 | return rootFolder; |
@@ -272,13 +272,13 @@ namespace OpenSim.Services.InventoryService | |||
272 | 272 | ||
273 | if (folders.Length == 0) | 273 | if (folders.Length == 0) |
274 | { | 274 | { |
275 | // m_log.WarnFormat("[XINVENTORY SERVICE]: Found no folder for type {0} for user {1}", type, principalID); | 275 | //m_log.WarnFormat("[XINVENTORY SERVICE]: Found no folder for type {0} ", type); |
276 | return null; | 276 | return null; |
277 | } | 277 | } |
278 | 278 | ||
279 | // m_log.DebugFormat( | 279 | //m_log.DebugFormat( |
280 | // "[XINVENTORY SERVICE]: Found folder {0} {1} for type {2} for user {3}", | 280 | // "[XINVENTORY SERVICE]: Found folder {0} {1} for type {2}", |
281 | // folders[0].folderName, folders[0].folderID, type, principalID); | 281 | // folders[0].folderName, folders[0].folderID, type); |
282 | 282 | ||
283 | return ConvertToOpenSim(folders[0]); | 283 | return ConvertToOpenSim(folders[0]); |
284 | } | 284 | } |
@@ -291,7 +291,7 @@ namespace OpenSim.Services.InventoryService | |||
291 | // | 291 | // |
292 | //m_log.DebugFormat("[XINVENTORY SERVICE]: Fetch contents for folder {0}", folderID.ToString()); | 292 | //m_log.DebugFormat("[XINVENTORY SERVICE]: Fetch contents for folder {0}", folderID.ToString()); |
293 | InventoryCollection inventory = new InventoryCollection(); | 293 | InventoryCollection inventory = new InventoryCollection(); |
294 | inventory.UserID = principalID; | 294 | inventory.OwnerID = principalID; |
295 | inventory.Folders = new List<InventoryFolderBase>(); | 295 | inventory.Folders = new List<InventoryFolderBase>(); |
296 | inventory.Items = new List<InventoryItemBase>(); | 296 | inventory.Items = new List<InventoryItemBase>(); |
297 | 297 | ||
@@ -315,8 +315,27 @@ namespace OpenSim.Services.InventoryService | |||
315 | inventory.Items.Add(ConvertToOpenSim(i)); | 315 | inventory.Items.Add(ConvertToOpenSim(i)); |
316 | } | 316 | } |
317 | 317 | ||
318 | InventoryFolderBase f = new InventoryFolderBase(folderID, principalID); | ||
319 | f = GetFolder(f); | ||
320 | if (f != null) | ||
321 | { | ||
322 | inventory.Version = f.Version; | ||
323 | inventory.OwnerID = f.Owner; | ||
324 | } | ||
325 | inventory.FolderID = folderID; | ||
326 | |||
318 | return inventory; | 327 | return inventory; |
319 | } | 328 | } |
329 | |||
330 | public virtual InventoryCollection[] GetMultipleFoldersContent(UUID principalID, UUID[] folderIDs) | ||
331 | { | ||
332 | InventoryCollection[] multiple = new InventoryCollection[folderIDs.Length]; | ||
333 | int i = 0; | ||
334 | foreach (UUID fid in folderIDs) | ||
335 | multiple[i++] = GetFolderContent(principalID, fid); | ||
336 | |||
337 | return multiple; | ||
338 | } | ||
320 | 339 | ||
321 | public virtual List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) | 340 | public virtual List<InventoryItemBase> GetFolderItems(UUID principalID, UUID folderID) |
322 | { | 341 | { |
@@ -591,6 +610,21 @@ namespace OpenSim.Services.InventoryService | |||
591 | return ConvertToOpenSim(items[0]); | 610 | return ConvertToOpenSim(items[0]); |
592 | } | 611 | } |
593 | 612 | ||
613 | public virtual InventoryItemBase[] GetMultipleItems(UUID userID, UUID[] ids) | ||
614 | { | ||
615 | InventoryItemBase[] items = new InventoryItemBase[ids.Length]; | ||
616 | int i = 0; | ||
617 | InventoryItemBase item = new InventoryItemBase(); | ||
618 | item.Owner = userID; | ||
619 | foreach (UUID id in ids) | ||
620 | { | ||
621 | item.ID = id; | ||
622 | items[i++] = GetItem(item); | ||
623 | } | ||
624 | |||
625 | return items; | ||
626 | } | ||
627 | |||
594 | public virtual InventoryFolderBase GetFolder(InventoryFolderBase folder) | 628 | public virtual InventoryFolderBase GetFolder(InventoryFolderBase folder) |
595 | { | 629 | { |
596 | XInventoryFolder[] folders = m_Database.GetFolders( | 630 | XInventoryFolder[] folders = m_Database.GetFolders( |
diff --git a/OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs b/OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs index ea03b56..4dc492a 100644 --- a/OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/LLLoginService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs b/OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs index 14dc990..e5f1bf9 100644 --- a/OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/MapImageService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs b/OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs index ae122e4..9ef0ff3 100644 --- a/OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/PresenceService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs b/OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs index 9d031d0..33933a0 100644 --- a/OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs +++ b/OpenSim/Services/UserAccountService/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Tests/Clients/Grid/GridClient.cs b/OpenSim/Tests/Clients/Grid/GridClient.cs deleted file mode 100644 index fed7a16..0000000 --- a/OpenSim/Tests/Clients/Grid/GridClient.cs +++ /dev/null | |||
@@ -1,205 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenMetaverse; | ||
34 | using log4net; | ||
35 | using log4net.Appender; | ||
36 | using log4net.Layout; | ||
37 | |||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Services.Interfaces; | ||
40 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
41 | using OpenSim.Services.Connectors; | ||
42 | |||
43 | namespace OpenSim.Tests.Clients.GridClient | ||
44 | { | ||
45 | public class GridClient | ||
46 | { | ||
47 | // private static readonly ILog m_log = | ||
48 | // LogManager.GetLogger( | ||
49 | // MethodBase.GetCurrentMethod().DeclaringType); | ||
50 | |||
51 | public static void Main(string[] args) | ||
52 | { | ||
53 | ConsoleAppender consoleAppender = new ConsoleAppender(); | ||
54 | consoleAppender.Layout = | ||
55 | new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"); | ||
56 | log4net.Config.BasicConfigurator.Configure(consoleAppender); | ||
57 | |||
58 | string serverURI = "http://127.0.0.1:8001"; | ||
59 | GridServicesConnector m_Connector = new GridServicesConnector(serverURI); | ||
60 | |||
61 | GridRegion r1 = CreateRegion("Test Region 1", 1000, 1000); | ||
62 | GridRegion r2 = CreateRegion("Test Region 2", 1001, 1000); | ||
63 | GridRegion r3 = CreateRegion("Test Region 3", 1005, 1000); | ||
64 | |||
65 | Console.WriteLine("[GRID CLIENT]: *** Registering region 1"); | ||
66 | string msg = m_Connector.RegisterRegion(UUID.Zero, r1); | ||
67 | if (msg == String.Empty) | ||
68 | Console.WriteLine("[GRID CLIENT]: Successfully registered region 1"); | ||
69 | else | ||
70 | Console.WriteLine("[GRID CLIENT]: region 1 failed to register"); | ||
71 | |||
72 | Console.WriteLine("[GRID CLIENT]: *** Registering region 2"); | ||
73 | msg = m_Connector.RegisterRegion(UUID.Zero, r2); | ||
74 | if (msg == String.Empty) | ||
75 | Console.WriteLine("[GRID CLIENT]: Successfully registered region 2"); | ||
76 | else | ||
77 | Console.WriteLine("[GRID CLIENT]: region 2 failed to register"); | ||
78 | |||
79 | Console.WriteLine("[GRID CLIENT]: *** Registering region 3"); | ||
80 | msg = m_Connector.RegisterRegion(UUID.Zero, r3); | ||
81 | if (msg == String.Empty) | ||
82 | Console.WriteLine("[GRID CLIENT]: Successfully registered region 3"); | ||
83 | else | ||
84 | Console.WriteLine("[GRID CLIENT]: region 3 failed to register"); | ||
85 | |||
86 | |||
87 | bool success; | ||
88 | Console.WriteLine("[GRID CLIENT]: *** Deregistering region 3"); | ||
89 | success = m_Connector.DeregisterRegion(r3.RegionID); | ||
90 | if (success) | ||
91 | Console.WriteLine("[GRID CLIENT]: Successfully deregistered region 3"); | ||
92 | else | ||
93 | Console.WriteLine("[GRID CLIENT]: region 3 failed to deregister"); | ||
94 | Console.WriteLine("[GRID CLIENT]: *** Registering region 3 again"); | ||
95 | msg = m_Connector.RegisterRegion(UUID.Zero, r3); | ||
96 | if (msg == String.Empty) | ||
97 | Console.WriteLine("[GRID CLIENT]: Successfully registered region 3"); | ||
98 | else | ||
99 | Console.WriteLine("[GRID CLIENT]: region 3 failed to register"); | ||
100 | |||
101 | Console.WriteLine("[GRID CLIENT]: *** GetNeighbours of region 1"); | ||
102 | List<GridRegion> regions = m_Connector.GetNeighbours(UUID.Zero, r1.RegionID); | ||
103 | if (regions == null) | ||
104 | Console.WriteLine("[GRID CLIENT]: GetNeighbours of region 1 failed"); | ||
105 | else if (regions.Count > 0) | ||
106 | { | ||
107 | if (regions.Count != 1) | ||
108 | Console.WriteLine("[GRID CLIENT]: GetNeighbours of region 1 returned more neighbours than expected: " + regions.Count); | ||
109 | else | ||
110 | Console.WriteLine("[GRID CLIENT]: GetNeighbours of region 1 returned the right neighbour " + regions[0].RegionName); | ||
111 | } | ||
112 | else | ||
113 | Console.WriteLine("[GRID CLIENT]: GetNeighbours of region 1 returned 0 neighbours"); | ||
114 | |||
115 | |||
116 | Console.WriteLine("[GRID CLIENT]: *** GetRegionByUUID of region 2 (this should succeed)"); | ||
117 | GridRegion region = m_Connector.GetRegionByUUID(UUID.Zero, r2.RegionID); | ||
118 | if (region == null) | ||
119 | Console.WriteLine("[GRID CLIENT]: GetRegionByUUID returned null"); | ||
120 | else | ||
121 | Console.WriteLine("[GRID CLIENT]: GetRegionByUUID returned region " + region.RegionName); | ||
122 | |||
123 | Console.WriteLine("[GRID CLIENT]: *** GetRegionByUUID of non-existent region (this should fail)"); | ||
124 | region = m_Connector.GetRegionByUUID(UUID.Zero, UUID.Random()); | ||
125 | if (region == null) | ||
126 | Console.WriteLine("[GRID CLIENT]: GetRegionByUUID returned null"); | ||
127 | else | ||
128 | Console.WriteLine("[GRID CLIENT]: GetRegionByUUID returned region " + region.RegionName); | ||
129 | |||
130 | Console.WriteLine("[GRID CLIENT]: *** GetRegionByName of region 3 (this should succeed)"); | ||
131 | region = m_Connector.GetRegionByName(UUID.Zero, r3.RegionName); | ||
132 | if (region == null) | ||
133 | Console.WriteLine("[GRID CLIENT]: GetRegionByName returned null"); | ||
134 | else | ||
135 | Console.WriteLine("[GRID CLIENT]: GetRegionByName returned region " + region.RegionName); | ||
136 | |||
137 | Console.WriteLine("[GRID CLIENT]: *** GetRegionByName of non-existent region (this should fail)"); | ||
138 | region = m_Connector.GetRegionByName(UUID.Zero, "Foo"); | ||
139 | if (region == null) | ||
140 | Console.WriteLine("[GRID CLIENT]: GetRegionByName returned null"); | ||
141 | else | ||
142 | Console.WriteLine("[GRID CLIENT]: GetRegionByName returned region " + region.RegionName); | ||
143 | |||
144 | Console.WriteLine("[GRID CLIENT]: *** GetRegionsByName (this should return 3 regions)"); | ||
145 | regions = m_Connector.GetRegionsByName(UUID.Zero, "Test", 10); | ||
146 | if (regions == null) | ||
147 | Console.WriteLine("[GRID CLIENT]: GetRegionsByName returned null"); | ||
148 | else | ||
149 | Console.WriteLine("[GRID CLIENT]: GetRegionsByName returned " + regions.Count + " regions"); | ||
150 | |||
151 | Console.WriteLine("[GRID CLIENT]: *** GetRegionRange (this should return 2 regions)"); | ||
152 | regions = m_Connector.GetRegionRange(UUID.Zero, | ||
153 | (int)Util.RegionToWorldLoc(900), (int)Util.RegionToWorldLoc(1002), | ||
154 | (int)Util.RegionToWorldLoc(900), (int)Util.RegionToWorldLoc(1002) ); | ||
155 | if (regions == null) | ||
156 | Console.WriteLine("[GRID CLIENT]: GetRegionRange returned null"); | ||
157 | else | ||
158 | Console.WriteLine("[GRID CLIENT]: GetRegionRange returned " + regions.Count + " regions"); | ||
159 | Console.WriteLine("[GRID CLIENT]: *** GetRegionRange (this should return 0 regions)"); | ||
160 | regions = m_Connector.GetRegionRange(UUID.Zero, | ||
161 | (int)Util.RegionToWorldLoc(900), (int)Util.RegionToWorldLoc(950), | ||
162 | (int)Util.RegionToWorldLoc(900), (int)Util.RegionToWorldLoc(950) ); | ||
163 | if (regions == null) | ||
164 | Console.WriteLine("[GRID CLIENT]: GetRegionRange returned null"); | ||
165 | else | ||
166 | Console.WriteLine("[GRID CLIENT]: GetRegionRange returned " + regions.Count + " regions"); | ||
167 | |||
168 | Console.Write("Proceed to deregister? Press enter..."); | ||
169 | Console.ReadLine(); | ||
170 | |||
171 | // Deregister them all | ||
172 | Console.WriteLine("[GRID CLIENT]: *** Deregistering region 1"); | ||
173 | success = m_Connector.DeregisterRegion(r1.RegionID); | ||
174 | if (success) | ||
175 | Console.WriteLine("[GRID CLIENT]: Successfully deregistered region 1"); | ||
176 | else | ||
177 | Console.WriteLine("[GRID CLIENT]: region 1 failed to deregister"); | ||
178 | Console.WriteLine("[GRID CLIENT]: *** Deregistering region 2"); | ||
179 | success = m_Connector.DeregisterRegion(r2.RegionID); | ||
180 | if (success) | ||
181 | Console.WriteLine("[GRID CLIENT]: Successfully deregistered region 2"); | ||
182 | else | ||
183 | Console.WriteLine("[GRID CLIENT]: region 2 failed to deregister"); | ||
184 | Console.WriteLine("[GRID CLIENT]: *** Deregistering region 3"); | ||
185 | success = m_Connector.DeregisterRegion(r3.RegionID); | ||
186 | if (success) | ||
187 | Console.WriteLine("[GRID CLIENT]: Successfully deregistered region 3"); | ||
188 | else | ||
189 | Console.WriteLine("[GRID CLIENT]: region 3 failed to deregister"); | ||
190 | |||
191 | } | ||
192 | |||
193 | private static GridRegion CreateRegion(string name, uint xcell, uint ycell) | ||
194 | { | ||
195 | GridRegion region = new GridRegion(xcell, ycell); | ||
196 | region.RegionName = name; | ||
197 | region.RegionID = UUID.Random(); | ||
198 | region.ExternalHostName = "127.0.0.1"; | ||
199 | region.HttpPort = 9000; | ||
200 | region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 9000); | ||
201 | |||
202 | return region; | ||
203 | } | ||
204 | } | ||
205 | } | ||
diff --git a/OpenSim/Tests/Clients/Presence/OpenSim.Server.ini b/OpenSim/Tests/Clients/Presence/OpenSim.Server.ini deleted file mode 100644 index 8610c78..0000000 --- a/OpenSim/Tests/Clients/Presence/OpenSim.Server.ini +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | ; * Run a ROBUST server shell like this, from bin: | ||
2 | ; * $ OpenSim.Server.exe -inifile ../OpenSim/Tests/Clients/Presence/OpenSim.Server.ini | ||
3 | ; * | ||
4 | ; * Then run this client like this, from bin: | ||
5 | ; * $ OpenSim.Tests.Clients.PresenceClient.exe | ||
6 | ; * | ||
7 | ; * | ||
8 | |||
9 | [Startup] | ||
10 | ServiceConnectors = "OpenSim.Server.Handlers.dll:PresenceServiceConnector" | ||
11 | |||
12 | ; * This is common for all services, it's the network setup for the entire | ||
13 | ; * server instance | ||
14 | ; * | ||
15 | [Network] | ||
16 | port = 8003 | ||
17 | |||
18 | ; * The following are for the remote console | ||
19 | ; * They have no effect for the local or basic console types | ||
20 | ; * Leave commented to diable logins to the console | ||
21 | ;ConsoleUser = Test | ||
22 | ;ConsolePass = secret | ||
23 | |||
24 | ; * As an example, the below configuration precisely mimicks the legacy | ||
25 | ; * asset server. It is read by the asset IN connector (defined above) | ||
26 | ; * and it then loads the OUT connector (a local database module). That, | ||
27 | ; * in turn, reads the asset loader and database connection information | ||
28 | ; * | ||
29 | [PresenceService] | ||
30 | LocalServiceModule = "OpenSim.Services.PresenceService.dll:PresenceService" | ||
31 | StorageProvider = "OpenSim.Data.MySQL.dll" | ||
32 | ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;Old Guids=true;" | ||
33 | |||
diff --git a/OpenSim/Tests/Clients/Presence/PresenceClient.cs b/OpenSim/Tests/Clients/Presence/PresenceClient.cs deleted file mode 100644 index fd3905a..0000000 --- a/OpenSim/Tests/Clients/Presence/PresenceClient.cs +++ /dev/null | |||
@@ -1,115 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenMetaverse; | ||
34 | using log4net; | ||
35 | using log4net.Appender; | ||
36 | using log4net.Layout; | ||
37 | |||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Services.Interfaces; | ||
40 | using OpenSim.Services.Connectors; | ||
41 | |||
42 | namespace OpenSim.Tests.Clients.PresenceClient | ||
43 | { | ||
44 | public class PresenceClient | ||
45 | { | ||
46 | private static readonly ILog m_log = | ||
47 | LogManager.GetLogger( | ||
48 | MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | public static void Main(string[] args) | ||
51 | { | ||
52 | ConsoleAppender consoleAppender = new ConsoleAppender(); | ||
53 | consoleAppender.Layout = | ||
54 | new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"); | ||
55 | log4net.Config.BasicConfigurator.Configure(consoleAppender); | ||
56 | |||
57 | string serverURI = "http://127.0.0.1:8003"; | ||
58 | PresenceServicesConnector m_Connector = new PresenceServicesConnector(serverURI); | ||
59 | |||
60 | UUID user1 = UUID.Random(); | ||
61 | UUID session1 = UUID.Random(); | ||
62 | UUID region1 = UUID.Random(); | ||
63 | |||
64 | bool success = m_Connector.LoginAgent(user1.ToString(), session1, UUID.Zero); | ||
65 | if (success) | ||
66 | m_log.InfoFormat("[PRESENCE CLIENT]: Successfully logged in user {0} with session {1}", user1, session1); | ||
67 | else | ||
68 | m_log.InfoFormat("[PRESENCE CLIENT]: failed to login user {0}", user1); | ||
69 | |||
70 | System.Console.WriteLine("\n"); | ||
71 | |||
72 | PresenceInfo pinfo = m_Connector.GetAgent(session1); | ||
73 | if (pinfo == null) | ||
74 | m_log.InfoFormat("[PRESENCE CLIENT]: Unable to retrieve presence for {0}", user1); | ||
75 | else | ||
76 | m_log.InfoFormat("[PRESENCE CLIENT]: Presence retrieved correctly: userID={0}; regionID={1}", | ||
77 | pinfo.UserID, pinfo.RegionID); | ||
78 | |||
79 | System.Console.WriteLine("\n"); | ||
80 | success = m_Connector.ReportAgent(session1, region1); | ||
81 | if (success) | ||
82 | m_log.InfoFormat("[PRESENCE CLIENT]: Successfully reported session {0} in region {1}", user1, region1); | ||
83 | else | ||
84 | m_log.InfoFormat("[PRESENCE CLIENT]: failed to report session {0}", session1); | ||
85 | pinfo = m_Connector.GetAgent(session1); | ||
86 | if (pinfo == null) | ||
87 | m_log.InfoFormat("[PRESENCE CLIENT]: Unable to retrieve presence for {0} for second time", user1); | ||
88 | else | ||
89 | m_log.InfoFormat("[PRESENCE CLIENT]: Presence retrieved correctly: userID={0}; regionID={2}", | ||
90 | pinfo.UserID, pinfo.RegionID); | ||
91 | |||
92 | System.Console.WriteLine("\n"); | ||
93 | success = m_Connector.LogoutAgent(session1); | ||
94 | if (success) | ||
95 | m_log.InfoFormat("[PRESENCE CLIENT]: Successfully logged out user {0}", user1); | ||
96 | else | ||
97 | m_log.InfoFormat("[PRESENCE CLIENT]: failed to logout user {0}", user1); | ||
98 | pinfo = m_Connector.GetAgent(session1); | ||
99 | if (pinfo == null) | ||
100 | m_log.InfoFormat("[PRESENCE CLIENT]: Unable to retrieve presence for {0} for fourth time", user1); | ||
101 | else | ||
102 | m_log.InfoFormat("[PRESENCE CLIENT]: Presence retrieved correctly: userID={0}; regionID={1}", | ||
103 | pinfo.UserID, pinfo.RegionID); | ||
104 | |||
105 | System.Console.WriteLine("\n"); | ||
106 | success = m_Connector.ReportAgent(session1, UUID.Random()); | ||
107 | if (success) | ||
108 | m_log.InfoFormat("[PRESENCE CLIENT]: Report agent succeeded, but this is wrong"); | ||
109 | else | ||
110 | m_log.InfoFormat("[PRESENCE CLIENT]: failed to report agent, as it should because user is not logged in"); | ||
111 | |||
112 | } | ||
113 | |||
114 | } | ||
115 | } | ||
diff --git a/OpenSim/Tests/Clients/UserAccounts/OpenSim.Server.ini b/OpenSim/Tests/Clients/UserAccounts/OpenSim.Server.ini deleted file mode 100644 index 453e17e..0000000 --- a/OpenSim/Tests/Clients/UserAccounts/OpenSim.Server.ini +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | ; * Run a ROBUST server shell like this, from bin: | ||
2 | ; * $ OpenSim.Server.exe -inifile ../OpenSim/Tests/Clients/Presence/OpenSim.Server.ini | ||
3 | ; * | ||
4 | ; * Then run this client like this, from bin: | ||
5 | ; * $ OpenSim.Tests.Clients.UserAccountClient.exe | ||
6 | ; * | ||
7 | ; * | ||
8 | |||
9 | [Startup] | ||
10 | ServiceConnectors = "OpenSim.Server.Handlers.dll:UserAccountServiceConnector" | ||
11 | |||
12 | ; * This is common for all services, it's the network setup for the entire | ||
13 | ; * server instance | ||
14 | ; * | ||
15 | [Network] | ||
16 | port = 8003 | ||
17 | |||
18 | ; * The following are for the remote console | ||
19 | ; * They have no effect for the local or basic console types | ||
20 | ; * Leave commented to diable logins to the console | ||
21 | ;ConsoleUser = Test | ||
22 | ;ConsolePass = secret | ||
23 | |||
24 | ; * As an example, the below configuration precisely mimicks the legacy | ||
25 | ; * asset server. It is read by the asset IN connector (defined above) | ||
26 | ; * and it then loads the OUT connector (a local database module). That, | ||
27 | ; * in turn, reads the asset loader and database connection information | ||
28 | ; * | ||
29 | [UserAccountService] | ||
30 | LocalServiceModule = "OpenSim.Services.UserAccountService.dll:UserAccountService" | ||
31 | StorageProvider = "OpenSim.Data.MySQL.dll" | ||
32 | ConnectionString = "Data Source=localhost;Database=opensim;User ID=opensim;Password=opensim123;Old Guids=true;" | ||
33 | |||
diff --git a/OpenSim/Tests/Clients/UserAccounts/UserAccountsClient.cs b/OpenSim/Tests/Clients/UserAccounts/UserAccountsClient.cs deleted file mode 100644 index 1e0a35b..0000000 --- a/OpenSim/Tests/Clients/UserAccounts/UserAccountsClient.cs +++ /dev/null | |||
@@ -1,144 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenMetaverse; | ||
34 | using log4net; | ||
35 | using log4net.Appender; | ||
36 | using log4net.Layout; | ||
37 | |||
38 | using OpenSim.Framework; | ||
39 | using OpenSim.Services.Interfaces; | ||
40 | using OpenSim.Services.Connectors; | ||
41 | |||
42 | namespace OpenSim.Tests.Clients.PresenceClient | ||
43 | { | ||
44 | public class UserAccountsClient | ||
45 | { | ||
46 | private static readonly ILog m_log = | ||
47 | LogManager.GetLogger( | ||
48 | MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | public static void Main(string[] args) | ||
51 | { | ||
52 | ConsoleAppender consoleAppender = new ConsoleAppender(); | ||
53 | consoleAppender.Layout = | ||
54 | new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"); | ||
55 | log4net.Config.BasicConfigurator.Configure(consoleAppender); | ||
56 | |||
57 | string serverURI = "http://127.0.0.1:8003"; | ||
58 | UserAccountServicesConnector m_Connector = new UserAccountServicesConnector(serverURI); | ||
59 | |||
60 | UUID user1 = UUID.Random(); | ||
61 | string first = "Completely"; | ||
62 | string last = "Clueless"; | ||
63 | string email = "foo@bar.com"; | ||
64 | |||
65 | //UserAccount account = new UserAccount(user1); | ||
66 | //account.ScopeID = UUID.Zero; | ||
67 | //account.FirstName = first; | ||
68 | //account.LastName = last; | ||
69 | //account.Email = email; | ||
70 | //account.ServiceURLs = new Dictionary<string, object>(); | ||
71 | //account.ServiceURLs.Add("InventoryServerURI", "http://cnn.com"); | ||
72 | //account.ServiceURLs.Add("AssetServerURI", "http://cnn.com"); | ||
73 | |||
74 | //bool success = m_Connector.StoreUserAccount(account); | ||
75 | //if (success) | ||
76 | // m_log.InfoFormat("[USER CLIENT]: Successfully created account for user {0} {1}", account.FirstName, account.LastName); | ||
77 | //else | ||
78 | // m_log.InfoFormat("[USER CLIENT]: failed to create user {0} {1}", account.FirstName, account.LastName); | ||
79 | |||
80 | //System.Console.WriteLine("\n"); | ||
81 | |||
82 | //account = m_Connector.GetUserAccount(UUID.Zero, user1); | ||
83 | //if (account == null) | ||
84 | // m_log.InfoFormat("[USER CLIENT]: Unable to retrieve accouny by UUID for {0}", user1); | ||
85 | //else | ||
86 | //{ | ||
87 | // m_log.InfoFormat("[USER CLIENT]: Account retrieved correctly: userID={0}; FirstName={1}; LastName={2}; Email={3}", | ||
88 | // account.PrincipalID, account.FirstName, account.LastName, account.Email); | ||
89 | // foreach (KeyValuePair<string, object> kvp in account.ServiceURLs) | ||
90 | // m_log.DebugFormat("\t {0} -> {1}", kvp.Key, kvp.Value); | ||
91 | //} | ||
92 | |||
93 | //System.Console.WriteLine("\n"); | ||
94 | |||
95 | UserAccount account = m_Connector.GetUserAccount(UUID.Zero, first, last); | ||
96 | if (account == null) | ||
97 | m_log.InfoFormat("[USER CLIENT]: Unable to retrieve accouny by name "); | ||
98 | else | ||
99 | { | ||
100 | m_log.InfoFormat("[USER CLIENT]: Account retrieved correctly: userID={0}; FirstName={1}; LastName={2}; Email={3}", | ||
101 | account.PrincipalID, account.FirstName, account.LastName, account.Email); | ||
102 | foreach (KeyValuePair<string, object> kvp in account.ServiceURLs) | ||
103 | m_log.DebugFormat("\t {0} -> {1}", kvp.Key, kvp.Value); | ||
104 | } | ||
105 | |||
106 | System.Console.WriteLine("\n"); | ||
107 | account = m_Connector.GetUserAccount(UUID.Zero, email); | ||
108 | if (account == null) | ||
109 | m_log.InfoFormat("[USER CLIENT]: Unable to retrieve accouny by email"); | ||
110 | else | ||
111 | { | ||
112 | m_log.InfoFormat("[USER CLIENT]: Account retrieved correctly: userID={0}; FirstName={1}; LastName={2}; Email={3}", | ||
113 | account.PrincipalID, account.FirstName, account.LastName, account.Email); | ||
114 | foreach (KeyValuePair<string, object> kvp in account.ServiceURLs) | ||
115 | m_log.DebugFormat("\t {0} -> {1}", kvp.Key, kvp.Value); | ||
116 | } | ||
117 | |||
118 | System.Console.WriteLine("\n"); | ||
119 | account = m_Connector.GetUserAccount(UUID.Zero, user1); | ||
120 | if (account == null) | ||
121 | m_log.InfoFormat("[USER CLIENT]: Unable to retrieve accouny by UUID for {0}", user1); | ||
122 | else | ||
123 | { | ||
124 | m_log.InfoFormat("[USER CLIENT]: Account retrieved correctly: userID={0}; FirstName={1}; LastName={2}; Email={3}", | ||
125 | account.PrincipalID, account.FirstName, account.LastName, account.Email); | ||
126 | foreach (KeyValuePair<string, object> kvp in account.ServiceURLs) | ||
127 | m_log.DebugFormat("\t {0} -> {1}", kvp.Key, kvp.Value); | ||
128 | } | ||
129 | |||
130 | System.Console.WriteLine("\n"); | ||
131 | account = m_Connector.GetUserAccount(UUID.Zero, "DoesNot", "Exist"); | ||
132 | if (account == null) | ||
133 | m_log.InfoFormat("[USER CLIENT]: Unable to retrieve account 'DoesNot Exist'"); | ||
134 | else | ||
135 | { | ||
136 | m_log.InfoFormat("[USER CLIENT]: Account 'DoesNot Exist' retrieved correctly. REALLY??? userID={0}; FirstName={1}; LastName={2}; Email={3}", | ||
137 | account.PrincipalID, account.FirstName, account.LastName, account.Email); | ||
138 | foreach (KeyValuePair<string, object> kvp in account.ServiceURLs) | ||
139 | m_log.DebugFormat("\t {0} -> {1}", kvp.Key, kvp.Value); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | } | ||
144 | } | ||
diff --git a/OpenSim/Tests/Robust/Clients/Grid/GridClient.cs b/OpenSim/Tests/Robust/Clients/Grid/GridClient.cs new file mode 100644 index 0000000..671aca7 --- /dev/null +++ b/OpenSim/Tests/Robust/Clients/Grid/GridClient.cs | |||
@@ -0,0 +1,133 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenMetaverse; | ||
34 | using NUnit.Framework; | ||
35 | |||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Services.Interfaces; | ||
38 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
39 | using OpenSim.Services.Connectors; | ||
40 | |||
41 | namespace Robust.Tests | ||
42 | { | ||
43 | [TestFixture] | ||
44 | public class GridClient | ||
45 | { | ||
46 | // private static readonly ILog m_log = | ||
47 | // LogManager.GetLogger( | ||
48 | // MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | [Test] | ||
51 | public void Grid_001() | ||
52 | { | ||
53 | GridServicesConnector m_Connector = new GridServicesConnector(DemonServer.Address); | ||
54 | |||
55 | GridRegion r1 = CreateRegion("Test Region 1", 1000, 1000); | ||
56 | GridRegion r2 = CreateRegion("Test Region 2", 1001, 1000); | ||
57 | GridRegion r3 = CreateRegion("Test Region 3", 1005, 1000); | ||
58 | |||
59 | string msg = m_Connector.RegisterRegion(UUID.Zero, r1); | ||
60 | Assert.AreEqual(msg, string.Empty, "Region 1 failed to register"); | ||
61 | |||
62 | msg = m_Connector.RegisterRegion(UUID.Zero, r2); | ||
63 | Assert.AreEqual(msg, string.Empty, "Region 2 failed to register"); | ||
64 | |||
65 | msg = m_Connector.RegisterRegion(UUID.Zero, r3); | ||
66 | Assert.AreEqual(msg, string.Empty, "Region 3 failed to register"); | ||
67 | |||
68 | bool success; | ||
69 | success = m_Connector.DeregisterRegion(r3.RegionID); | ||
70 | Assert.AreEqual(success, true, "Region 3 failed to deregister"); | ||
71 | |||
72 | msg = m_Connector.RegisterRegion(UUID.Zero, r3); | ||
73 | Assert.AreEqual(msg, string.Empty, "Region 3 failed to re-register"); | ||
74 | |||
75 | List<GridRegion> regions = m_Connector.GetNeighbours(UUID.Zero, r1.RegionID); | ||
76 | Assert.AreNotEqual(regions, null, "GetNeighbours of region 1 failed"); | ||
77 | Assert.AreEqual(regions.Count, 1, "Region 1 should have 1 neighbor"); | ||
78 | Assert.AreEqual(regions[0].RegionName, "Test Region 2", "Region 1 has the wrong neighbor"); | ||
79 | |||
80 | GridRegion region = m_Connector.GetRegionByUUID(UUID.Zero, r2.RegionID); | ||
81 | Assert.AreNotEqual(region, null, "GetRegionByUUID for region 2 failed"); | ||
82 | Assert.AreEqual(region.RegionName, "Test Region 2", "GetRegionByUUID of region 2 returned wrong region"); | ||
83 | |||
84 | region = m_Connector.GetRegionByUUID(UUID.Zero, UUID.Random()); | ||
85 | Assert.AreEqual(region, null, "Region with randon id should not exist"); | ||
86 | |||
87 | region = m_Connector.GetRegionByName(UUID.Zero, r3.RegionName); | ||
88 | Assert.AreNotEqual(region, null, "GetRegionByUUID for region 3 failed"); | ||
89 | Assert.AreEqual(region.RegionName, "Test Region 3", "GetRegionByUUID of region 3 returned wrong region"); | ||
90 | |||
91 | region = m_Connector.GetRegionByName(UUID.Zero, "Foo"); | ||
92 | Assert.AreEqual(region, null, "Region Foo should not exist"); | ||
93 | |||
94 | regions = m_Connector.GetRegionsByName(UUID.Zero, "Test", 10); | ||
95 | Assert.AreNotEqual(regions, null, "GetRegionsByName failed"); | ||
96 | Assert.AreEqual(regions.Count, 3, "GetRegionsByName should return 3"); | ||
97 | |||
98 | regions = m_Connector.GetRegionRange(UUID.Zero, | ||
99 | (int)Util.RegionToWorldLoc(900), (int)Util.RegionToWorldLoc(1002), | ||
100 | (int)Util.RegionToWorldLoc(900), (int)Util.RegionToWorldLoc(1002) ); | ||
101 | Assert.AreNotEqual(regions, null, "GetRegionRange failed"); | ||
102 | Assert.AreEqual(regions.Count, 2, "GetRegionRange should return 2"); | ||
103 | |||
104 | regions = m_Connector.GetRegionRange(UUID.Zero, | ||
105 | (int)Util.RegionToWorldLoc(900), (int)Util.RegionToWorldLoc(950), | ||
106 | (int)Util.RegionToWorldLoc(900), (int)Util.RegionToWorldLoc(950) ); | ||
107 | Assert.AreNotEqual(regions, null, "GetRegionRange (bis) failed"); | ||
108 | Assert.AreEqual(regions.Count, 0, "GetRegionRange (bis) should return 0"); | ||
109 | |||
110 | // Deregister them all | ||
111 | success = m_Connector.DeregisterRegion(r1.RegionID); | ||
112 | Assert.AreEqual(success, true, "Region 1 failed to deregister"); | ||
113 | |||
114 | success = m_Connector.DeregisterRegion(r2.RegionID); | ||
115 | Assert.AreEqual(success, true, "Region 2 failed to deregister"); | ||
116 | |||
117 | success = m_Connector.DeregisterRegion(r3.RegionID); | ||
118 | Assert.AreEqual(success, true, "Region 3 failed to deregister"); | ||
119 | } | ||
120 | |||
121 | private static GridRegion CreateRegion(string name, uint xcell, uint ycell) | ||
122 | { | ||
123 | GridRegion region = new GridRegion(xcell, ycell); | ||
124 | region.RegionName = name; | ||
125 | region.RegionID = UUID.Random(); | ||
126 | region.ExternalHostName = "127.0.0.1"; | ||
127 | region.HttpPort = 9000; | ||
128 | region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), 9000); | ||
129 | |||
130 | return region; | ||
131 | } | ||
132 | } | ||
133 | } | ||
diff --git a/OpenSim/Tests/Clients/Grid/GridForm.html b/OpenSim/Tests/Robust/Clients/Grid/GridForm.html index 252920f..252920f 100644 --- a/OpenSim/Tests/Clients/Grid/GridForm.html +++ b/OpenSim/Tests/Robust/Clients/Grid/GridForm.html | |||
diff --git a/OpenSim/Tests/Clients/InstantMessage/IMClient.cs b/OpenSim/Tests/Robust/Clients/InstantMessage/IMClient.cs index e7304a2..8f312eb 100644 --- a/OpenSim/Tests/Clients/InstantMessage/IMClient.cs +++ b/OpenSim/Tests/Robust/Clients/InstantMessage/IMClient.cs | |||
@@ -28,47 +28,30 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Text; | 30 | using System.Text; |
31 | using System.Reflection; | ||
32 | 31 | ||
33 | using OpenMetaverse; | 32 | using OpenMetaverse; |
34 | using log4net; | 33 | using NUnit.Framework; |
35 | using log4net.Appender; | ||
36 | using log4net.Layout; | ||
37 | 34 | ||
38 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
39 | using OpenSim.Services.Interfaces; | 36 | using OpenSim.Services.Interfaces; |
40 | using OpenSim.Services.Connectors.InstantMessage; | 37 | using OpenSim.Services.Connectors.InstantMessage; |
41 | 38 | ||
42 | namespace OpenSim.Tests.Clients.InstantMessage | 39 | namespace Robust.Tests |
43 | { | 40 | { |
41 | [TestFixture] | ||
44 | public class IMClient | 42 | public class IMClient |
45 | { | 43 | { |
46 | private static readonly ILog m_log = | 44 | [Test] |
47 | LogManager.GetLogger( | 45 | public void HGIM_001() |
48 | MethodBase.GetCurrentMethod().DeclaringType); | ||
49 | |||
50 | public static void Main(string[] args) | ||
51 | { | 46 | { |
52 | ConsoleAppender consoleAppender = new ConsoleAppender(); | ||
53 | consoleAppender.Layout = | ||
54 | new PatternLayout("%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"); | ||
55 | log4net.Config.BasicConfigurator.Configure(consoleAppender); | ||
56 | |||
57 | string serverURI = "http://127.0.0.1:8002"; | ||
58 | GridInstantMessage im = new GridInstantMessage(); | 47 | GridInstantMessage im = new GridInstantMessage(); |
59 | im.fromAgentID = new Guid(); | 48 | im.fromAgentID = new Guid(); |
60 | im.toAgentID = new Guid(); | 49 | im.toAgentID = new Guid(); |
61 | im.message = "Hello"; | 50 | im.message = "Hello"; |
62 | im.imSessionID = new Guid(); | 51 | im.imSessionID = new Guid(); |
63 | 52 | ||
64 | bool success = InstantMessageServiceConnector.SendInstantMessage(serverURI, im); | 53 | bool success = InstantMessageServiceConnector.SendInstantMessage(DemonServer.Address, im); |
65 | 54 | Assert.IsFalse(success, "Sending of IM succeeded, but it should have failed"); | |
66 | if (success) | ||
67 | m_log.InfoFormat("[IM CLIENT]: Successfully IMed {0}", serverURI); | ||
68 | else | ||
69 | m_log.InfoFormat("[IM CLIENT]: failed to IM {0}", serverURI); | ||
70 | |||
71 | System.Console.WriteLine("\n"); | ||
72 | } | 55 | } |
73 | 56 | ||
74 | } | 57 | } |
diff --git a/OpenSim/Tests/Robust/Clients/Inventory/InventoryClient.cs b/OpenSim/Tests/Robust/Clients/Inventory/InventoryClient.cs new file mode 100644 index 0000000..9d3f400 --- /dev/null +++ b/OpenSim/Tests/Robust/Clients/Inventory/InventoryClient.cs | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenMetaverse; | ||
34 | using NUnit.Framework; | ||
35 | |||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Services.Interfaces; | ||
38 | using OpenSim.Services.Connectors; | ||
39 | |||
40 | namespace Robust.Tests | ||
41 | { | ||
42 | [TestFixture] | ||
43 | public class InventoryClient | ||
44 | { | ||
45 | // private static readonly ILog m_log = | ||
46 | // LogManager.GetLogger( | ||
47 | // MethodBase.GetCurrentMethod().DeclaringType); | ||
48 | |||
49 | private UUID m_userID = new UUID("00000000-0000-0000-0000-333333333333"); | ||
50 | private UUID m_rootFolderID; | ||
51 | private UUID m_notecardsFolder; | ||
52 | private UUID m_objectsFolder; | ||
53 | |||
54 | [Test] | ||
55 | public void Inventory_001_CreateInventory() | ||
56 | { | ||
57 | XInventoryServicesConnector m_Connector = new XInventoryServicesConnector(DemonServer.Address); | ||
58 | |||
59 | // Create an inventory that looks like this: | ||
60 | // | ||
61 | // /My Inventory | ||
62 | // <other system folders> | ||
63 | // /Objects | ||
64 | // Some Object | ||
65 | // /Notecards | ||
66 | // Notecard 1 | ||
67 | // Notecard 2 | ||
68 | // /Test Folder | ||
69 | // Link to notecard -> /Notecards/Notecard 2 | ||
70 | // Link to Objects folder -> /Objects | ||
71 | |||
72 | Console.WriteLine("Starting inventory test"); | ||
73 | bool success = m_Connector.CreateUserInventory(m_userID); | ||
74 | Assert.IsTrue(success, "Failed to create user inventory"); | ||
75 | |||
76 | m_rootFolderID = m_Connector.GetRootFolder(m_userID).ID; | ||
77 | Assert.AreNotEqual(m_rootFolderID, UUID.Zero, "Root folder ID must not be UUID.Zero"); | ||
78 | |||
79 | InventoryFolderBase of = m_Connector.GetFolderForType(m_userID, AssetType.Object); | ||
80 | Assert.IsNotNull(of, "Failed to retrieve Objects folder"); | ||
81 | m_objectsFolder = of.ID; | ||
82 | Assert.AreNotEqual(m_objectsFolder, UUID.Zero, "Objects folder ID must not be UUID.Zero"); | ||
83 | |||
84 | // Add an object | ||
85 | InventoryItemBase item = new InventoryItemBase(new UUID("b0000000-0000-0000-0000-00000000000b"), m_userID); | ||
86 | item.AssetID = UUID.Random(); | ||
87 | item.AssetType = (int)AssetType.Object; | ||
88 | item.Folder = m_objectsFolder; | ||
89 | item.Name = "Some Object"; | ||
90 | item.Description = string.Empty; | ||
91 | success = m_Connector.AddItem(item); | ||
92 | Assert.IsTrue(success, "Failed to add object to inventory"); | ||
93 | |||
94 | InventoryFolderBase ncf = m_Connector.GetFolderForType(m_userID, AssetType.Notecard); | ||
95 | Assert.IsNotNull(of, "Failed to retrieve Notecards folder"); | ||
96 | m_notecardsFolder = ncf.ID; | ||
97 | Assert.AreNotEqual(m_notecardsFolder, UUID.Zero, "Notecards folder ID must not be UUID.Zero"); | ||
98 | m_notecardsFolder = ncf.ID; | ||
99 | |||
100 | // Add a notecard | ||
101 | item = new InventoryItemBase(new UUID("10000000-0000-0000-0000-000000000001"), m_userID); | ||
102 | item.AssetID = UUID.Random(); | ||
103 | item.AssetType = (int)AssetType.Notecard; | ||
104 | item.Folder = m_notecardsFolder; | ||
105 | item.Name = "Test Notecard 1"; | ||
106 | item.Description = string.Empty; | ||
107 | success = m_Connector.AddItem(item); | ||
108 | Assert.IsTrue(success, "Failed to add Notecard 1 to inventory"); | ||
109 | // Add another notecard | ||
110 | item.ID = new UUID("20000000-0000-0000-0000-000000000002"); | ||
111 | item.AssetID = new UUID("a0000000-0000-0000-0000-00000000000a"); | ||
112 | item.Name = "Test Notecard 2"; | ||
113 | item.Description = string.Empty; | ||
114 | success = m_Connector.AddItem(item); | ||
115 | Assert.IsTrue(success, "Failed to add Notecard 2 to inventory"); | ||
116 | |||
117 | // Add a folder | ||
118 | InventoryFolderBase folder = new InventoryFolderBase(new UUID("f0000000-0000-0000-0000-00000000000f"), "Test Folder", m_userID, m_rootFolderID); | ||
119 | folder.Type = (int)AssetType.Folder; | ||
120 | success = m_Connector.AddFolder(folder); | ||
121 | Assert.IsTrue(success, "Failed to add Test Folder to inventory"); | ||
122 | |||
123 | // Add a link to notecard 2 in Test Folder | ||
124 | item.AssetID = item.ID; // use item ID of notecard 2 | ||
125 | item.ID = new UUID("40000000-0000-0000-0000-000000000004"); | ||
126 | item.AssetType = (int)AssetType.Link; | ||
127 | item.Folder = folder.ID; | ||
128 | item.Name = "Link to notecard"; | ||
129 | item.Description = string.Empty; | ||
130 | success = m_Connector.AddItem(item); | ||
131 | Assert.IsTrue(success, "Failed to add link to notecard to inventory"); | ||
132 | |||
133 | // Add a link to the Objects folder in Test Folder | ||
134 | item.AssetID = m_Connector.GetFolderForType(m_userID, AssetType.Object).ID; // use item ID of Objects folder | ||
135 | item.ID = new UUID("50000000-0000-0000-0000-000000000005"); | ||
136 | item.AssetType = (int)AssetType.LinkFolder; | ||
137 | item.Folder = folder.ID; | ||
138 | item.Name = "Link to Objects folder"; | ||
139 | item.Description = string.Empty; | ||
140 | success = m_Connector.AddItem(item); | ||
141 | Assert.IsTrue(success, "Failed to add link to objects folder to inventory"); | ||
142 | |||
143 | InventoryCollection coll = m_Connector.GetFolderContent(m_userID, m_rootFolderID); | ||
144 | Assert.IsNotNull(coll, "Failed to retrieve contents of root folder"); | ||
145 | Assert.Greater(coll.Folders.Count, 0, "Root folder does not have any subfolders"); | ||
146 | |||
147 | coll = m_Connector.GetFolderContent(m_userID, folder.ID); | ||
148 | Assert.IsNotNull(coll, "Failed to retrieve contents of Test Folder"); | ||
149 | Assert.AreEqual(coll.Items.Count + coll.Folders.Count, 2, "Test Folder is expected to have exactly 2 things inside"); | ||
150 | |||
151 | } | ||
152 | } | ||
153 | } | ||
diff --git a/OpenSim/Tests/Robust/Clients/Presence/PresenceClient.cs b/OpenSim/Tests/Robust/Clients/Presence/PresenceClient.cs new file mode 100644 index 0000000..31c8ee9 --- /dev/null +++ b/OpenSim/Tests/Robust/Clients/Presence/PresenceClient.cs | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenMetaverse; | ||
34 | using NUnit.Framework; | ||
35 | |||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Services.Interfaces; | ||
38 | using OpenSim.Services.Connectors; | ||
39 | |||
40 | namespace Robust.Tests | ||
41 | { | ||
42 | [TestFixture] | ||
43 | public class PresenceClient | ||
44 | { | ||
45 | [Test] | ||
46 | public void Presence_001() | ||
47 | { | ||
48 | PresenceServicesConnector m_Connector = new PresenceServicesConnector(DemonServer.Address); | ||
49 | |||
50 | UUID user1 = UUID.Random(); | ||
51 | UUID session1 = UUID.Random(); | ||
52 | UUID region1 = UUID.Random(); | ||
53 | |||
54 | bool success = m_Connector.LoginAgent(user1.ToString(), session1, UUID.Zero); | ||
55 | Assert.AreEqual(success, true, "Failed to add user session"); | ||
56 | |||
57 | PresenceInfo pinfo = m_Connector.GetAgent(session1); | ||
58 | Assert.AreNotEqual(pinfo, null, "Unable to retrieve session"); | ||
59 | Assert.AreEqual(pinfo.UserID, user1.ToString(), "Retrieved session does not match expected userID"); | ||
60 | Assert.AreNotEqual(pinfo.RegionID, region1, "Retrieved session is unexpectedly in region"); | ||
61 | |||
62 | success = m_Connector.ReportAgent(session1, region1); | ||
63 | Assert.AreEqual(success, true, "Failed to report session in region 1"); | ||
64 | |||
65 | pinfo = m_Connector.GetAgent(session1); | ||
66 | Assert.AreNotEqual(pinfo, null, "Unable to session presence"); | ||
67 | Assert.AreEqual(pinfo.UserID, user1.ToString(), "Retrieved session does not match expected userID"); | ||
68 | Assert.AreEqual(pinfo.RegionID, region1, "Retrieved session is not in expected region"); | ||
69 | |||
70 | success = m_Connector.LogoutAgent(session1); | ||
71 | Assert.AreEqual(success, true, "Failed to remove session"); | ||
72 | |||
73 | pinfo = m_Connector.GetAgent(session1); | ||
74 | Assert.AreEqual(pinfo, null, "Session is still there, even though it shouldn't"); | ||
75 | |||
76 | success = m_Connector.ReportAgent(session1, UUID.Random()); | ||
77 | Assert.AreEqual(success, false, "Remove non-existing session should fail"); | ||
78 | } | ||
79 | |||
80 | } | ||
81 | } | ||
diff --git a/OpenSim/Tests/Robust/Clients/UserAccounts/UserAccountsClient.cs b/OpenSim/Tests/Robust/Clients/UserAccounts/UserAccountsClient.cs new file mode 100644 index 0000000..2c327e8 --- /dev/null +++ b/OpenSim/Tests/Robust/Clients/UserAccounts/UserAccountsClient.cs | |||
@@ -0,0 +1,85 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Text; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenMetaverse; | ||
34 | using NUnit.Framework; | ||
35 | |||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Services.Interfaces; | ||
38 | using OpenSim.Services.Connectors; | ||
39 | |||
40 | namespace Robust.Tests | ||
41 | { | ||
42 | [TestFixture] | ||
43 | public class UserAccountsClient | ||
44 | { | ||
45 | [Test] | ||
46 | public void UserAccounts_001() | ||
47 | { | ||
48 | UserAccountServicesConnector m_Connector = new UserAccountServicesConnector(DemonServer.Address); | ||
49 | |||
50 | string first = "Completely"; | ||
51 | string last = "Clueless"; | ||
52 | string email = "foo@bar.com"; | ||
53 | |||
54 | UserAccount account = m_Connector.CreateUser(first, last, "123", email, UUID.Zero); | ||
55 | Assert.IsNotNull(account, "Failed to create account " + first + " " + last); | ||
56 | UUID user1 = account.PrincipalID; | ||
57 | |||
58 | account = m_Connector.GetUserAccount(UUID.Zero, user1); | ||
59 | Assert.NotNull(account, "Failed to retrieve account for user id " + user1); | ||
60 | Assert.AreEqual(account.FirstName, first, "First name does not match"); | ||
61 | Assert.AreEqual(account.LastName, last, "Last name does not match"); | ||
62 | |||
63 | account = m_Connector.GetUserAccount(UUID.Zero, first, last); | ||
64 | Assert.IsNotNull(account, "Failed to retrieve account for user " + first + " " + last); | ||
65 | Assert.AreEqual(account.FirstName, first, "First name does not match (bis)"); | ||
66 | Assert.AreEqual(account.LastName, last, "Last name does not match (bis)"); | ||
67 | |||
68 | account.Email = "user@example.com"; | ||
69 | bool success = m_Connector.StoreUserAccount(account); | ||
70 | Assert.IsTrue(success, "Failed to store existing account"); | ||
71 | |||
72 | account = m_Connector.GetUserAccount(UUID.Zero, user1); | ||
73 | Assert.NotNull(account, "Failed to retrieve account for user id " + user1); | ||
74 | Assert.AreEqual(account.Email, "user@example.com", "Incorrect email"); | ||
75 | |||
76 | account = m_Connector.GetUserAccount(UUID.Zero, "DoesNot", "Exist"); | ||
77 | Assert.IsNull(account, "Account DoesNot Exit must not be there"); | ||
78 | |||
79 | account = new UserAccount(UUID.Zero, "DoesNot", "Exist", "xxx@xxx.com"); | ||
80 | success = m_Connector.StoreUserAccount(account); | ||
81 | Assert.IsFalse(success, "Storing a non-existing account must fail"); | ||
82 | } | ||
83 | |||
84 | } | ||
85 | } | ||
diff --git a/OpenSim/Tests/Robust/Server/DemonServer.cs b/OpenSim/Tests/Robust/Server/DemonServer.cs new file mode 100644 index 0000000..1e0797e --- /dev/null +++ b/OpenSim/Tests/Robust/Server/DemonServer.cs | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.IO; | ||
31 | using System.Threading; | ||
32 | |||
33 | using Nini.Config; | ||
34 | using log4net; | ||
35 | using NUnit.Framework; | ||
36 | |||
37 | using OpenSim.Server; | ||
38 | |||
39 | namespace Robust.Tests | ||
40 | { | ||
41 | [SetUpFixture] | ||
42 | public class DemonServer : OpenSimServer | ||
43 | { | ||
44 | private Thread m_demon; | ||
45 | |||
46 | public static string Address = "http://localhost:8888"; | ||
47 | |||
48 | [SetUp] | ||
49 | public void StartDemon() | ||
50 | { | ||
51 | if (File.Exists("Robust.Tests.log")) | ||
52 | File.Delete("Robust.Tests.log"); | ||
53 | |||
54 | Console.WriteLine("**** Starting demon Robust server ****"); | ||
55 | m_demon = new Thread( () => Main(new string[] {"-inifile=Robust.Tests.ini"})); | ||
56 | m_demon.Start(); | ||
57 | // Give some time for the server to instantiate all services | ||
58 | Thread.Sleep(3000); | ||
59 | Console.WriteLine("**** Setup Finished ****"); | ||
60 | } | ||
61 | |||
62 | [TearDown] | ||
63 | public void StopDemon() | ||
64 | { | ||
65 | Console.WriteLine("**** Killing demon Robust Server ****"); | ||
66 | m_Server.Shutdown(); | ||
67 | } | ||
68 | } | ||
69 | } | ||
diff --git a/OpenSim/Tools/Compiler/Properties/AssemblyInfo.cs b/OpenSim/Tools/Compiler/Properties/AssemblyInfo.cs index 7e92d76..b97c977 100644 --- a/OpenSim/Tools/Compiler/Properties/AssemblyInfo.cs +++ b/OpenSim/Tools/Compiler/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Tools/Configger/Properties/AssemblyInfo.cs b/OpenSim/Tools/Configger/Properties/AssemblyInfo.cs index c470703..e88f0f5 100644 --- a/OpenSim/Tools/Configger/Properties/AssemblyInfo.cs +++ b/OpenSim/Tools/Configger/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||
diff --git a/OpenSim/Tools/pCampBot/Behaviours/InventoryDownloadBehaviour.cs b/OpenSim/Tools/pCampBot/Behaviours/InventoryDownloadBehaviour.cs new file mode 100644 index 0000000..521415c --- /dev/null +++ b/OpenSim/Tools/pCampBot/Behaviours/InventoryDownloadBehaviour.cs | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using OpenMetaverse; | ||
29 | using System; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Diagnostics; | ||
32 | using System.Threading; | ||
33 | using System.Linq; | ||
34 | using pCampBot.Interfaces; | ||
35 | |||
36 | namespace pCampBot | ||
37 | { | ||
38 | /// <summary> | ||
39 | /// Do nothing | ||
40 | /// </summary> | ||
41 | public class InventoryDownloadBehaviour : AbstractBehaviour | ||
42 | { | ||
43 | private bool m_initialized; | ||
44 | private int m_Requests = 2; | ||
45 | private Stopwatch m_StopWatch = new Stopwatch(); | ||
46 | private List<UUID> m_processed = new List<UUID>(); | ||
47 | |||
48 | public InventoryDownloadBehaviour() | ||
49 | { | ||
50 | AbbreviatedName = "inv"; | ||
51 | Name = "Inventory"; | ||
52 | } | ||
53 | |||
54 | public override void Action() | ||
55 | { | ||
56 | if (!m_initialized) | ||
57 | { | ||
58 | m_initialized = true; | ||
59 | Bot.Client.Settings.HTTP_INVENTORY = true; | ||
60 | Bot.Client.Settings.FETCH_MISSING_INVENTORY = true; | ||
61 | Bot.Client.Inventory.FolderUpdated += Inventory_FolderUpdated; | ||
62 | Console.WriteLine("Lib owner is " + Bot.Client.Inventory.Store.LibraryRootNode.Data.OwnerID); | ||
63 | m_StopWatch.Start(); | ||
64 | Bot.Client.Inventory.RequestFolderContents(Bot.Client.Inventory.Store.RootFolder.UUID, Bot.Client.Self.AgentID, true, true, InventorySortOrder.ByDate); | ||
65 | Bot.Client.Inventory.RequestFolderContents(Bot.Client.Inventory.Store.LibraryRootNode.Data.UUID, Bot.Client.Inventory.Store.LibraryRootNode.Data.OwnerID, true, true, InventorySortOrder.ByDate); | ||
66 | } | ||
67 | |||
68 | Thread.Sleep(1000); | ||
69 | Console.WriteLine("Total items: " + Bot.Client.Inventory.Store.Items.Count + "; Total requests: " + m_Requests + "; Time: " + m_StopWatch.Elapsed); | ||
70 | |||
71 | } | ||
72 | |||
73 | void Inventory_FolderUpdated(object sender, FolderUpdatedEventArgs e) | ||
74 | { | ||
75 | if (e.Success) | ||
76 | { | ||
77 | //Console.WriteLine("Folder " + e.FolderID + " updated"); | ||
78 | bool fetch = false; | ||
79 | lock (m_processed) | ||
80 | { | ||
81 | if (!m_processed.Contains(e.FolderID)) | ||
82 | { | ||
83 | m_processed.Add(e.FolderID); | ||
84 | fetch = true; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | if (fetch) | ||
89 | { | ||
90 | List<InventoryFolder> m_foldersToFetch = new List<InventoryFolder>(); | ||
91 | foreach (InventoryBase item in Bot.Client.Inventory.Store.GetContents(e.FolderID)) | ||
92 | { | ||
93 | if (item is InventoryFolder) | ||
94 | { | ||
95 | InventoryFolder f = new InventoryFolder(item.UUID); | ||
96 | f.OwnerID = item.OwnerID; | ||
97 | m_foldersToFetch.Add(f); | ||
98 | } | ||
99 | } | ||
100 | if (m_foldersToFetch.Count > 0) | ||
101 | { | ||
102 | m_Requests += 1; | ||
103 | Bot.Client.Inventory.RequestFolderContentsCap(m_foldersToFetch, Bot.Client.Network.CurrentSim.Caps.CapabilityURI("FetchInventoryDescendents2"), true, true, InventorySortOrder.ByDate); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | if (Bot.Client.Inventory.Store.Items.Count >= 15739) | ||
108 | { | ||
109 | m_StopWatch.Stop(); | ||
110 | Console.WriteLine("Stop! Total items: " + Bot.Client.Inventory.Store.Items.Count + "; Total requests: " + m_Requests + "; Time: " + m_StopWatch.Elapsed); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | } | ||
115 | |||
116 | public override void Interrupt() | ||
117 | { | ||
118 | m_interruptEvent.Set(); | ||
119 | } | ||
120 | } | ||
121 | } \ No newline at end of file | ||
diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 46094d6..0af9592 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs | |||
@@ -343,6 +343,9 @@ namespace pCampBot | |||
343 | if (abName == "ph2") | 343 | if (abName == "ph2") |
344 | newBehaviour = new PhysicsBehaviour2(); | 344 | newBehaviour = new PhysicsBehaviour2(); |
345 | 345 | ||
346 | if (abName == "inv") | ||
347 | newBehaviour = new InventoryDownloadBehaviour(); | ||
348 | |||
346 | if (newBehaviour != null) | 349 | if (newBehaviour != null) |
347 | { | 350 | { |
348 | behaviours.Add(newBehaviour); | 351 | behaviours.Add(newBehaviour); |
diff --git a/OpenSim/Tools/pCampBot/Properties/AssemblyInfo.cs b/OpenSim/Tools/pCampBot/Properties/AssemblyInfo.cs index c0c2b5d..87af19a 100644 --- a/OpenSim/Tools/pCampBot/Properties/AssemblyInfo.cs +++ b/OpenSim/Tools/pCampBot/Properties/AssemblyInfo.cs | |||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices; | |||
29 | // Build Number | 29 | // Build Number |
30 | // Revision | 30 | // Revision |
31 | // | 31 | // |
32 | [assembly: AssemblyVersion("0.8.1.*")] | 32 | [assembly: AssemblyVersion("0.8.2.*")] |
33 | 33 | ||