OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
ObjectCommandsModule.cs
Go to the documentation of this file.
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.Linq;
32 using System.Reflection;
33 using System.Text;
34 using System.Text.RegularExpressions;
35 using System.Xml;
36 using log4net;
37 using Mono.Addins;
38 using NDesk.Options;
39 using Nini.Config;
40 using OpenMetaverse;
41 using OpenSim.Framework;
42 using OpenSim.Framework.Console;
43 using OpenSim.Framework.Monitoring;
44 using OpenSim.Region.Framework.Interfaces;
45 using OpenSim.Region.Framework.Scenes;
46 using OpenSim.Region.Framework.Scenes.Serialization;
47 
48 namespace OpenSim.Region.CoreModules.World.Objects.Commands
49 {
53  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "ObjectCommandsModule")]
55  {
56 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
57 
58  private Scene m_scene;
59  private ICommandConsole m_console;
60 
61  public string Name { get { return "Object Commands Module"; } }
62 
63  public Type ReplaceableInterface { get { return null; } }
64 
65  public void Initialise(IConfigSource source)
66  {
67 // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: INITIALIZED MODULE");
68  }
69 
70  public void PostInitialise()
71  {
72 // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: POST INITIALIZED MODULE");
73  }
74 
75  public void Close()
76  {
77 // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: CLOSED MODULE");
78  }
79 
80  public void AddRegion(Scene scene)
81  {
82 // m_log.DebugFormat("[OBJECT COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
83 
84  m_scene = scene;
85  m_console = MainConsole.Instance;
86 
87  m_console.Commands.AddCommand(
88  "Objects", false, "delete object owner",
89  "delete object owner <UUID>",
90  "Delete scene objects by owner",
91  "Command will ask for confirmation before proceeding.",
92  HandleDeleteObject);
93 
94  m_console.Commands.AddCommand(
95  "Objects", false, "delete object creator",
96  "delete object creator <UUID>",
97  "Delete scene objects by creator",
98  "Command will ask for confirmation before proceeding.",
99  HandleDeleteObject);
100 
101  m_console.Commands.AddCommand(
102  "Objects", false, "delete object id",
103  "delete object id <UUID-or-localID>",
104  "Delete a scene object by uuid or localID",
105  HandleDeleteObject);
106 
107  m_console.Commands.AddCommand(
108  "Objects", false, "delete object name",
109  "delete object name [--regex] <name>",
110  "Delete a scene object by name.",
111  "Command will ask for confirmation before proceeding.\n"
112  + "If --regex is specified then the name is treatead as a regular expression",
113  HandleDeleteObject);
114 
115  m_console.Commands.AddCommand(
116  "Objects", false, "delete object outside",
117  "delete object outside",
118  "Delete all scene objects outside region boundaries",
119  "Command will ask for confirmation before proceeding.",
120  HandleDeleteObject);
121 
122  m_console.Commands.AddCommand(
123  "Objects",
124  false,
125  "delete object pos",
126  "delete object pos <start-coord> to <end-coord>",
127  "Delete scene objects within the given area.",
128  ConsoleUtil.CoordHelp,
129  HandleDeleteObject);
130 
131  m_console.Commands.AddCommand(
132  "Objects",
133  false,
134  "show object id",
135  "show object id [--full] <UUID-or-localID>",
136  "Show details of a scene object with the given UUID or localID",
137  "The --full option will print out information on all the parts of the object.\n"
138  + "For yet more detailed part information, use the \"show part\" commands.",
139  HandleShowObjectById);
140 
141  m_console.Commands.AddCommand(
142  "Objects",
143  false,
144  "show object name",
145  "show object name [--full] [--regex] <name>",
146  "Show details of scene objects with the given name.",
147  "The --full option will print out information on all the parts of the object.\n"
148  + "For yet more detailed part information, use the \"show part\" commands.\n"
149  + "If --regex is specified then the name is treatead as a regular expression.",
150  HandleShowObjectByName);
151 
152  m_console.Commands.AddCommand(
153  "Objects",
154  false,
155  "show object pos",
156  "show object pos [--full] <start-coord> to <end-coord>",
157  "Show details of scene objects within the given area.",
158  "The --full option will print out information on all the parts of the object.\n"
159  + "For yet more detailed part information, use the \"show part\" commands.\n"
160  + ConsoleUtil.CoordHelp,
161  HandleShowObjectByPos);
162 
163  m_console.Commands.AddCommand(
164  "Objects",
165  false,
166  "show part id",
167  "show part id <UUID-or-localID>",
168  "Show details of a scene object part with the given UUID or localID", HandleShowPartById);
169 
170  m_console.Commands.AddCommand(
171  "Objects",
172  false,
173  "show part name",
174  "show part name [--regex] <name>",
175  "Show details of scene object parts with the given name.",
176  "If --regex is specified then the name is treated as a regular expression",
177  HandleShowPartByName);
178 
179  m_console.Commands.AddCommand(
180  "Objects",
181  false,
182  "show part pos",
183  "show part pos <start-coord> to <end-coord>",
184  "Show details of scene object parts within the given area.",
185  ConsoleUtil.CoordHelp,
186  HandleShowPartByPos);
187 
188  m_console.Commands.AddCommand(
189  "Objects",
190  false,
191  "dump object id",
192  "dump object id <UUID-or-localID>",
193  "Dump the formatted serialization of the given object to the file <UUID>.xml",
194  "e.g. dump object uuid c1ed6809-cc24-4061-a4c2-93082a2d1f1d will dump serialization to c1ed6809-cc24-4061-a4c2-93082a2d1f1d.xml\n"
195  + "To locate the UUID or localID in the first place, you need to use the other show object commands.\n"
196  + "If a local ID is given then the filename used is still that for the UUID",
197  HandleDumpObjectById);
198  }
199 
200  public void RemoveRegion(Scene scene)
201  {
202 // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
203  }
204 
205  public void RegionLoaded(Scene scene)
206  {
207 // m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
208  }
209 
215  private void OutputSogsToConsole(Predicate<SceneObjectGroup> searchPredicate, bool showFull)
216  {
217  List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups().FindAll(searchPredicate);
218 
219  StringBuilder sb = new StringBuilder();
220 
221  foreach (SceneObjectGroup so in sceneObjects)
222  {
223  AddSceneObjectReport(sb, so, showFull);
224  sb.Append("\n");
225  }
226 
227  sb.AppendFormat("{0} object(s) found in {1}\n", sceneObjects.Count, m_scene.Name);
228 
229  m_console.OutputFormat(sb.ToString());
230  }
231 
232  private void OutputSopsToConsole(Predicate<SceneObjectPart> searchPredicate, bool showFull)
233  {
234  List<SceneObjectGroup> sceneObjects = m_scene.GetSceneObjectGroups();
235  List<SceneObjectPart> parts = new List<SceneObjectPart>();
236 
237  sceneObjects.ForEach(so => parts.AddRange(Array.FindAll<SceneObjectPart>(so.Parts, searchPredicate)));
238 
239  StringBuilder sb = new StringBuilder();
240 
241  foreach (SceneObjectPart part in parts)
242  {
243  AddScenePartReport(sb, part, showFull);
244  sb.Append("\n");
245  }
246 
247  sb.AppendFormat("{0} parts found in {1}\n", parts.Count, m_scene.Name);
248 
249  m_console.OutputFormat(sb.ToString());
250  }
251 
252  private void HandleShowObjectById(string module, string[] cmdparams)
253  {
254  if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
255  return;
256 
257  bool showFull = false;
258  OptionSet options = new OptionSet().Add("full", v => showFull = v != null );
259 
260  List<string> mainParams = options.Parse(cmdparams);
261 
262  if (mainParams.Count < 4)
263  {
264  m_console.OutputFormat("Usage: show object uuid <uuid>");
265  return;
266  }
267 
268  UUID uuid;
269  uint localId;
270  if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out uuid, out localId))
271  return;
272 
273  SceneObjectGroup so;
274 
275  if (localId != ConsoleUtil.LocalIdNotFound)
276  so = m_scene.GetSceneObjectGroup(localId);
277  else
278  so = m_scene.GetSceneObjectGroup(uuid);
279 
280  if (so == null)
281  {
282 // m_console.OutputFormat("No part found with uuid {0}", objectUuid);
283  return;
284  }
285 
286  StringBuilder sb = new StringBuilder();
287  AddSceneObjectReport(sb, so, showFull);
288 
289  m_console.OutputFormat(sb.ToString());
290  }
291 
292  private void HandleShowObjectByName(string module, string[] cmdparams)
293  {
294  if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
295  return;
296 
297  bool showFull = false;
298  bool useRegex = false;
299  OptionSet options = new OptionSet();
300  options.Add("full", v => showFull = v != null );
301  options.Add("regex", v => useRegex = v != null );
302 
303  List<string> mainParams = options.Parse(cmdparams);
304 
305  if (mainParams.Count < 4)
306  {
307  m_console.OutputFormat("Usage: show object name [--full] [--regex] <name>");
308  return;
309  }
310 
311  string name = mainParams[3];
312 
313  Predicate<SceneObjectGroup> searchPredicate;
314 
315  if (useRegex)
316  {
317  Regex nameRegex = new Regex(name);
318  searchPredicate = so => nameRegex.IsMatch(so.Name);
319  }
320  else
321  {
322  searchPredicate = so => so.Name == name;
323  }
324 
325  OutputSogsToConsole(searchPredicate, showFull);
326  }
327 
328  private void HandleShowObjectByPos(string module, string[] cmdparams)
329  {
330  if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
331  return;
332 
333  bool showFull = false;
334  OptionSet options = new OptionSet().Add("full", v => showFull = v != null );
335 
336  List<string> mainParams = options.Parse(cmdparams);
337 
338  if (mainParams.Count < 5)
339  {
340  m_console.OutputFormat("Usage: show object pos [--full] <start-coord> to <end-coord>");
341  return;
342  }
343 
344  Vector3 startVector, endVector;
345 
346  if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector))
347  return;
348 
349  Predicate<SceneObjectGroup> searchPredicate
350  = so => Util.IsInsideBox(so.AbsolutePosition, startVector, endVector);
351 
352  OutputSogsToConsole(searchPredicate, showFull);
353  }
354 
355  private void HandleShowPartById(string module, string[] cmdparams)
356  {
357  if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
358  return;
359 
360 // bool showFull = false;
361  OptionSet options = new OptionSet();
362 // options.Add("full", v => showFull = v != null );
363 
364  List<string> mainParams = options.Parse(cmdparams);
365 
366  if (mainParams.Count < 4)
367  {
368  //m_console.OutputFormat("Usage: show part id [--full] <UUID-or-localID>");
369  m_console.OutputFormat("Usage: show part id <UUID-or-localID>");
370  return;
371  }
372 
373  UUID objectUuid;
374  uint localId;
375  if (!ConsoleUtil.TryParseConsoleId(m_console, mainParams[3], out objectUuid, out localId))
376  return;
377 
378  SceneObjectPart sop;
379  if (localId == ConsoleUtil.LocalIdNotFound)
380  sop = m_scene.GetSceneObjectPart(objectUuid);
381  else
382  sop = m_scene.GetSceneObjectPart(localId);
383 
384  if (sop == null)
385  {
386 // m_console.OutputFormat("No part found with uuid {0}", objectUuid);
387  return;
388  }
389 
390  StringBuilder sb = new StringBuilder();
391  AddScenePartReport(sb, sop, true);
392 
393  m_console.OutputFormat(sb.ToString());
394  }
395 
396  private void HandleShowPartByPos(string module, string[] cmdparams)
397  {
398  if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
399  return;
400 
401 // bool showFull = false;
402  OptionSet options = new OptionSet();
403 // options.Add("full", v => showFull = v != null );
404 
405  List<string> mainParams = options.Parse(cmdparams);
406 
407  if (mainParams.Count < 5)
408  {
409  //m_console.OutputFormat("Usage: show part pos <start-coord> to <end-coord>");
410  m_console.OutputFormat("Usage: show part pos [--full] <start-coord> to <end-coord>");
411  return;
412  }
413 
414  string rawConsoleStartVector = mainParams[3];
415  Vector3 startVector;
416 
417  if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
418  {
419  m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector);
420  return;
421  }
422 
423  string rawConsoleEndVector = mainParams[5];
424  Vector3 endVector;
425 
426  if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
427  {
428  m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector);
429  return;
430  }
431 
432  OutputSopsToConsole(sop => Util.IsInsideBox(sop.AbsolutePosition, startVector, endVector), true);
433  }
434 
435  private void HandleShowPartByName(string module, string[] cmdparams)
436  {
437  if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
438  return;
439 
440 // bool showFull = false;
441  bool useRegex = false;
442  OptionSet options = new OptionSet();
443 // options.Add("full", v => showFull = v != null );
444  options.Add("regex", v => useRegex = v != null );
445 
446  List<string> mainParams = options.Parse(cmdparams);
447 
448  if (mainParams.Count < 4)
449  {
450  m_console.OutputFormat("Usage: show part name [--regex] <name>");
451  //m_console.OutputFormat("Usage: show part name [--full] [--regex] <name>");
452  return;
453  }
454 
455  string name = mainParams[3];
456 
457  Predicate<SceneObjectPart> searchPredicate;
458 
459  if (useRegex)
460  {
461  Regex nameRegex = new Regex(name);
462  searchPredicate = sop => nameRegex.IsMatch(sop.Name);
463  }
464  else
465  {
466  searchPredicate = sop => sop.Name == name;
467  }
468 
469  OutputSopsToConsole(searchPredicate, true);
470  }
471 
472  private void HandleDumpObjectById(string module, string[] cmdparams)
473  {
474  if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
475  return;
476 
477  if (cmdparams.Length < 4)
478  {
479  m_console.OutputFormat("Usage: dump object id <UUID-or-localID>");
480  return;
481  }
482 
483  UUID objectUuid;
484  uint localId;
485  if (!ConsoleUtil.TryParseConsoleId(m_console, cmdparams[3], out objectUuid, out localId))
486  return;
487 
488  SceneObjectGroup so;
489  if (localId == ConsoleUtil.LocalIdNotFound)
490  so = m_scene.GetSceneObjectGroup(objectUuid);
491  else
492  so = m_scene.GetSceneObjectGroup(localId);
493 
494  if (so == null)
495  {
496 // m_console.OutputFormat("No part found with uuid {0}", objectUuid);
497  return;
498  }
499 
500  // In case we found it via local ID.
501  objectUuid = so.UUID;
502 
503  string fileName = string.Format("{0}.xml", objectUuid);
504 
505  if (!ConsoleUtil.CheckFileDoesNotExist(m_console, fileName))
506  return;
507 
508  using (XmlTextWriter xtw = new XmlTextWriter(fileName, Encoding.UTF8))
509  {
510  xtw.Formatting = Formatting.Indented;
511  SceneObjectSerializer.ToOriginalXmlFormat(so, xtw, true);
512  }
513 
514  m_console.OutputFormat("Object dumped to file {0}", fileName);
515  }
516 
527  private StringBuilder AddSceneObjectReport(StringBuilder sb, SceneObjectGroup so, bool showFull)
528  {
529  if (showFull)
530  {
531  foreach (SceneObjectPart sop in so.Parts)
532  {
533  AddScenePartReport(sb, sop, false);
534  sb.Append("\n");
535  }
536  }
537  else
538  {
539  AddSummarySceneObjectReport(sb, so);
540  }
541 
542  return sb;
543  }
544 
545  private StringBuilder AddSummarySceneObjectReport(StringBuilder sb, SceneObjectGroup so)
546  {
548  cdl.AddRow("Name", so.Name);
549  cdl.AddRow("Description", so.Description);
550  cdl.AddRow("Local ID", so.LocalId);
551  cdl.AddRow("UUID", so.UUID);
552  cdl.AddRow("Location", string.Format("{0} @ {1}", so.AbsolutePosition, so.Scene.Name));
553  cdl.AddRow("Parts", so.PrimCount);
554  cdl.AddRow("Flags", so.RootPart.Flags);
555 
556  return sb.Append(cdl.ToString());
557  }
558 
569  private StringBuilder AddScenePartReport(StringBuilder sb, SceneObjectPart sop, bool showFull)
570  {
572  cdl.AddRow("Name", sop.Name);
573  cdl.AddRow("Description", sop.Description);
574  cdl.AddRow("Local ID", sop.LocalId);
575  cdl.AddRow("UUID", sop.UUID);
576  cdl.AddRow("Location", string.Format("{0} @ {1}", sop.AbsolutePosition, sop.ParentGroup.Scene.Name));
577  cdl.AddRow(
578  "Parent",
579  sop.IsRoot ? "Is Root" : string.Format("{0} {1}", sop.ParentGroup.Name, sop.ParentGroup.UUID));
580  cdl.AddRow("Link number", sop.LinkNum);
581  cdl.AddRow("Flags", sop.Flags);
582 
583  if (showFull)
584  {
585  PrimitiveBaseShape s = sop.Shape;
586  cdl.AddRow("FlexiDrag", s.FlexiDrag);
587  cdl.AddRow("FlexiEntry", s.FlexiEntry);
588  cdl.AddRow("FlexiForce", string.Format("<{0},{1},{2}>", s.FlexiForceX, s.FlexiForceY, s.FlexiForceZ));
589  cdl.AddRow("FlexiGravity", s.FlexiGravity);
590  cdl.AddRow("FlexiSoftness", s.FlexiSoftness);
591  cdl.AddRow("HollowShape", s.HollowShape);
592  cdl.AddRow(
593  "LightColor",
594  string.Format("<{0},{1},{2},{3}>", s.LightColorR, s.LightColorB, s.LightColorG, s.LightColorA));
595  cdl.AddRow("LightCutoff", s.LightCutoff);
596  cdl.AddRow("LightEntry", s.LightEntry);
597  cdl.AddRow("LightFalloff", s.LightFalloff);
598  cdl.AddRow("LightIntensity", s.LightIntensity);
599  cdl.AddRow("LightRadius", s.LightRadius);
600  cdl.AddRow("Location (relative)", sop.RelativePosition);
601  cdl.AddRow("Media", string.Format("{0} entries", s.Media != null ? s.Media.Count.ToString() : "n/a"));
602  cdl.AddRow("PathBegin", s.PathBegin);
603  cdl.AddRow("PathEnd", s.PathEnd);
604  cdl.AddRow("PathCurve", s.PathCurve);
605  cdl.AddRow("PathRadiusOffset", s.PathRadiusOffset);
606  cdl.AddRow("PathRevolutions", s.PathRevolutions);
607  cdl.AddRow("PathScale", string.Format("<{0},{1}>", s.PathScaleX, s.PathScaleY));
608  cdl.AddRow("PathSkew", string.Format("<{0},{1}>", s.PathShearX, s.PathShearY));
609  cdl.AddRow("FlexiDrag", s.PathSkew);
610  cdl.AddRow("PathTaper", string.Format("<{0},{1}>", s.PathTaperX, s.PathTaperY));
611  cdl.AddRow("PathTwist", s.PathTwist);
612  cdl.AddRow("PathTwistBegin", s.PathTwistBegin);
613  cdl.AddRow("PCode", s.PCode);
614  cdl.AddRow("ProfileBegin", s.ProfileBegin);
615  cdl.AddRow("ProfileEnd", s.ProfileEnd);
616  cdl.AddRow("ProfileHollow", s.ProfileHollow);
617  cdl.AddRow("ProfileShape", s.ProfileShape);
618  cdl.AddRow("ProjectionAmbiance", s.ProjectionAmbiance);
619  cdl.AddRow("ProjectionEntry", s.ProjectionEntry);
620  cdl.AddRow("ProjectionFocus", s.ProjectionFocus);
621  cdl.AddRow("ProjectionFOV", s.ProjectionFOV);
622  cdl.AddRow("ProjectionTextureUUID", s.ProjectionTextureUUID);
623  cdl.AddRow("Rotation (Relative)", sop.RotationOffset);
624  cdl.AddRow("Rotation (World)", sop.GetWorldRotation());
625  cdl.AddRow("Scale", s.Scale);
626  cdl.AddRow(
627  "SculptData",
628  string.Format("{0} bytes", s.SculptData != null ? s.SculptData.Length.ToString() : "n/a"));
629  cdl.AddRow("SculptEntry", s.SculptEntry);
630  cdl.AddRow("SculptTexture", s.SculptTexture);
631  cdl.AddRow("SculptType", s.SculptType);
632  cdl.AddRow("State", s.State);
633 
634  // TODO, need to display more information about textures but in a compact format
635  // to stop output becoming huge.
636  for (int i = 0; i < sop.GetNumberOfSides(); i++)
637  {
638  Primitive.TextureEntryFace teFace = s.Textures.FaceTextures[i];
639 
640  UUID textureID;
641 
642  if (teFace != null)
643  textureID = teFace.TextureID;
644  else
645  textureID = s.Textures.DefaultTexture.TextureID;
646 
647  cdl.AddRow(string.Format("Face {0} texture ID", i), textureID);
648  }
649 
650  //cdl.AddRow("Textures", string.Format("{0} entries", s.Textures.
651  }
652 
653  object itemsOutput;
654  if (showFull)
655  {
656  StringBuilder itemsSb = new StringBuilder("\n");
657  itemsOutput = AddScenePartItemsReport(itemsSb, sop.Inventory).ToString();
658  }
659  else
660  {
661  itemsOutput = sop.Inventory.Count;
662  }
663 
664  cdl.AddRow("Items", itemsOutput);
665 
666  return sb.Append(cdl.ToString());
667  }
668 
669  private StringBuilder AddScenePartItemsReport(StringBuilder sb, IEntityInventory inv)
670  {
672  cdt.Indent = 2;
673 
674  cdt.AddColumn("Name", 50);
675  cdt.AddColumn("Type", 12);
676  cdt.AddColumn("Running", 7);
677  cdt.AddColumn("Item UUID", 36);
678  cdt.AddColumn("Asset UUID", 36);
679 
680  foreach (TaskInventoryItem item in inv.GetInventoryItems())
681  {
682  bool foundScriptInstance, scriptRunning;
683  foundScriptInstance
684  = SceneObjectPartInventory.TryGetScriptInstanceRunning(m_scene, item, out scriptRunning);
685 
686  cdt.AddRow(
687  item.Name,
688  ((InventoryType)item.InvType).ToString(),
689  foundScriptInstance ? scriptRunning.ToString() : "n/a",
690  item.ItemID.ToString(),
691  item.AssetID.ToString());
692  }
693 
694  return sb.Append(cdt.ToString());
695  }
696 
697  private void HandleDeleteObject(string module, string[] cmd)
698  {
699  if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
700  return;
701 
702  if (cmd.Length < 3)
703  return;
704 
705  string mode = cmd[2];
706  string o = "";
707 
708  if (mode != "outside")
709  {
710  if (cmd.Length < 4)
711  return;
712 
713  o = cmd[3];
714  }
715 
716  List<SceneObjectGroup> deletes = null;
717  UUID match;
718  bool requireConfirmation = true;
719 
720  switch (mode)
721  {
722  case "owner":
723  if (!UUID.TryParse(o, out match))
724  return;
725 
726  deletes = new List<SceneObjectGroup>();
727 
728  m_scene.ForEachSOG(delegate (SceneObjectGroup g)
729  {
730  if (g.OwnerID == match && !g.IsAttachment)
731  deletes.Add(g);
732  });
733 
734  // if (deletes.Count == 0)
735  // m_console.OutputFormat("No objects were found with owner {0}", match);
736 
737  break;
738 
739  case "creator":
740  if (!UUID.TryParse(o, out match))
741  return;
742 
743  deletes = new List<SceneObjectGroup>();
744 
745  m_scene.ForEachSOG(delegate (SceneObjectGroup g)
746  {
747  if (g.RootPart.CreatorID == match && !g.IsAttachment)
748  deletes.Add(g);
749  });
750 
751  // if (deletes.Count == 0)
752  // m_console.OutputFormat("No objects were found with creator {0}", match);
753 
754  break;
755 
756  case "id":
757  UUID uuid;
758  uint localId;
759  if (!ConsoleUtil.TryParseConsoleId(m_console, o, out uuid, out localId))
760  return;
761 
762  requireConfirmation = false;
763  deletes = new List<SceneObjectGroup>();
764 
765  SceneObjectGroup so;
766  if (localId == ConsoleUtil.LocalIdNotFound)
767  so = m_scene.GetSceneObjectGroup(uuid);
768  else
769  so = m_scene.GetSceneObjectGroup(localId);
770 
771  if (!so.IsAttachment)
772  deletes.Add(so);
773 
774  // if (deletes.Count == 0)
775  // m_console.OutputFormat("No objects were found with uuid {0}", match);
776 
777  break;
778 
779  case "name":
780  deletes = GetDeleteCandidatesByName(module, cmd);
781  break;
782 
783  case "outside":
784  deletes = new List<SceneObjectGroup>();
785 
786  m_scene.ForEachSOG(delegate (SceneObjectGroup g)
787  {
788  SceneObjectPart rootPart = g.RootPart;
789  bool delete = false;
790 
791  if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0)
792  {
793  delete = true;
794  }
795  else
796  {
797  ILandObject parcel
798  = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y);
799 
800  if (parcel == null || parcel.LandData.Name == "NO LAND")
801  delete = true;
802  }
803 
804  if (delete && !g.IsAttachment && !deletes.Contains(g))
805  deletes.Add(g);
806  });
807 
808  if (deletes.Count == 0)
809  m_console.OutputFormat("No objects were found outside region bounds");
810 
811  break;
812 
813  case "pos":
814  deletes = GetDeleteCandidatesByPos(module, cmd);
815  break;
816 
817  default:
818  m_console.OutputFormat("Unrecognized mode {0}", mode);
819  return;
820  }
821 
822  if (deletes == null || deletes.Count <= 0)
823  return;
824 
825  if (requireConfirmation)
826  {
827  string response = MainConsole.Instance.CmdPrompt(
828  string.Format(
829  "Are you sure that you want to delete {0} objects from {1}",
830  deletes.Count, m_scene.RegionInfo.RegionName),
831  "y/N");
832 
833  if (response.ToLower() != "y")
834  {
835  MainConsole.Instance.OutputFormat(
836  "Aborting delete of {0} objects from {1}", deletes.Count, m_scene.RegionInfo.RegionName);
837 
838  return;
839  }
840  }
841 
842  m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName);
843 
844  foreach (SceneObjectGroup g in deletes)
845  {
846  m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name);
847  m_scene.DeleteSceneObject(g, false);
848  }
849  }
850 
851  private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams)
852  {
853  bool useRegex = false;
854  OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null );
855 
856  List<string> mainParams = options.Parse(cmdparams);
857 
858  if (mainParams.Count < 4)
859  {
860  m_console.OutputFormat("Usage: delete object name [--regex] <name>");
861  return null;
862  }
863 
864  string name = mainParams[3];
865 
866  List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>();
867  Action<SceneObjectGroup> searchAction;
868 
869  if (useRegex)
870  {
871  Regex nameRegex = new Regex(name);
872  searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }};
873  }
874  else
875  {
876  searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }};
877  }
878 
879  m_scene.ForEachSOG(searchAction);
880 
881  if (sceneObjects.Count == 0)
882  m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName);
883 
884  return sceneObjects;
885  }
886 
894  private List<SceneObjectGroup> GetDeleteCandidatesByPos(string module, string[] cmdparams)
895  {
896  if (cmdparams.Length < 5)
897  {
898  m_console.OutputFormat("Usage: delete object pos <start-coord> to <end-coord>");
899  return null;
900  }
901 
902  Vector3 startVector, endVector;
903 
904  if (!TryParseVectorRange(cmdparams.Skip(3).Take(3), out startVector, out endVector))
905  return null;
906 
907  return m_scene.GetSceneObjectGroups().FindAll(
908  so => !so.IsAttachment && Util.IsInsideBox(so.AbsolutePosition, startVector, endVector));
909  }
910 
911  private bool TryParseVectorRange(IEnumerable<string> rawComponents, out Vector3 startVector, out Vector3 endVector)
912  {
913  string rawConsoleStartVector = rawComponents.Take(1).Single();
914 
915  if (!ConsoleUtil.TryParseConsoleMinVector(rawConsoleStartVector, out startVector))
916  {
917  m_console.OutputFormat("Error: Start vector '{0}' does not have a valid format", rawConsoleStartVector);
918  endVector = Vector3.Zero;
919 
920  return false;
921  }
922 
923  string rawConsoleEndVector = rawComponents.Skip(2).Take(1).Single();
924 
925  if (!ConsoleUtil.TryParseConsoleMaxVector(rawConsoleEndVector, out endVector))
926  {
927  m_console.OutputFormat("Error: End vector '{0}' does not have a valid format", rawConsoleEndVector);
928  return false;
929  }
930 
931  return true;
932  }
933  }
934 }
Used to generated a formatted table for the console.
static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector)
Convert a maximum vector input from the console to an OpenMetaverse.Vector3
Definition: ConsoleUtil.cs:280
static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector)
Convert a minimum vector input from the console to an OpenMetaverse.Vector3
Definition: ConsoleUtil.cs:269
Vector3 GroupPosition
The position of the entire group that this prim belongs to.
IEntityInventory Inventory
This part's inventory
Used to generated a formatted table for the console.
static bool TryParseConsoleId(ICommandConsole console, string rawId, out UUID uuid, out uint localId)
Tries to parse the input as either a UUID or a local ID.
Definition: ConsoleUtil.cs:139
A module that holds commands for manipulating objects in the scene.
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
Represents an item in a task inventory
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
List< TaskInventoryItem > GetInventoryItems()
Get all inventory items.
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
OpenSim.Region.OptionalModules.Scripting.Minimodule.Object.SculptType SculptType
Definition: SOPObject.cs:39
string Name
Parcel Name
Definition: LandData.cs:433
System.Collections.IEnumerable IEnumerable
Interactive OpenSim region server
Definition: OpenSim.cs:55
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
Interface to an entity's (SceneObjectPart's) inventory
static bool CheckFileDoesNotExist(ICommandConsole console, string path)
Check if the given file path exists.
Definition: ConsoleUtil.cs:74
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
bool IsAttachment
Is this scene object acting as an attachment?