aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-10-24 02:05:28 +0100
committerJustin Clark-Casey (justincc)2012-10-24 02:05:28 +0100
commit73db057fa1dbda7d6dff7de770cef8670b234f84 (patch)
tree6f20e418aafe23b6a21044195dd100afa9aa65de
parentMerge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff)
downloadopensim-SC-73db057fa1dbda7d6dff7de770cef8670b234f84.zip
opensim-SC-73db057fa1dbda7d6dff7de770cef8670b234f84.tar.gz
opensim-SC-73db057fa1dbda7d6dff7de770cef8670b234f84.tar.bz2
opensim-SC-73db057fa1dbda7d6dff7de770cef8670b234f84.tar.xz
Add "dump object uuid" console command. This allows any object in the scene to be serialized and dumped to XML for debug purposes.
-rw-r--r--OpenSim/Framework/Console/ConsoleUtil.cs206
-rw-r--r--OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs53
2 files changed, 168 insertions, 91 deletions
diff --git a/OpenSim/Framework/Console/ConsoleUtil.cs b/OpenSim/Framework/Console/ConsoleUtil.cs
index 027753d..5c25ccb 100644
--- a/OpenSim/Framework/Console/ConsoleUtil.cs
+++ b/OpenSim/Framework/Console/ConsoleUtil.cs
@@ -32,100 +32,124 @@ using System.Reflection;
32using log4net; 32using log4net;
33using OpenMetaverse; 33using OpenMetaverse;
34 34
35public class ConsoleUtil 35namespace OpenSim.Framework.Console
36{ 36{
37// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 37 public class ConsoleUtil
38
39 /// <summary>
40 /// Used by modules to display stock co-ordinate help, though possibly this should be under some general section
41 /// rather than in each help summary.
42 /// </summary>
43 public const string CoordHelp
44= @"Each component of the coord is comma separated. There must be no spaces between the commas.
45If you don't care about the z component you can simply omit it.
46If you don't care about the x or y components then you can leave them blank (though a comma is still required)
47If you want to specify the maxmimum value of a component then you can use ~ instead of a number
48If you want to specify the minimum value of a component then you can use -~ instead of a number
49e.g.
50delete object pos 20,20,20 to 40,40,40
51delete object pos 20,20 to 40,40
52delete object pos ,20,20 to ,40,40
53delete object pos ,,30 to ,,~
54delete object pos ,,-~ to ,,30";
55
56 public const string MinRawConsoleVectorValue = "-~";
57 public const string MaxRawConsoleVectorValue = "~";
58
59 public const string VectorSeparator = ",";
60 public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray();
61
62 /// <summary>
63 /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
64 /// </summary>
65 /// <param name='rawConsoleVector'>/param>
66 /// <param name='vector'></param>
67 /// <returns></returns>
68 public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector)
69 { 38 {
70 return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector); 39 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
71 } 40
72 41 /// <summary>
73 /// <summary> 42 /// Used by modules to display stock co-ordinate help, though possibly this should be under some general section
74 /// Convert a maximum vector input from the console to an OpenMetaverse.Vector3 43 /// rather than in each help summary.
75 /// </summary> 44 /// </summary>
76 /// <param name='rawConsoleVector'>/param> 45 public const string CoordHelp
77 /// <param name='vector'></param> 46 = @"Each component of the coord is comma separated. There must be no spaces between the commas.
78 /// <returns></returns> 47 If you don't care about the z component you can simply omit it.
79 public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector) 48 If you don't care about the x or y components then you can leave them blank (though a comma is still required)
80 { 49 If you want to specify the maxmimum value of a component then you can use ~ instead of a number
81 return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector); 50 If you want to specify the minimum value of a component then you can use -~ instead of a number
82 } 51 e.g.
83 52 delete object pos 20,20,20 to 40,40,40
84 /// <summary> 53 delete object pos 20,20 to 40,40
85 /// Convert a vector input from the console to an OpenMetaverse.Vector3 54 delete object pos ,20,20 to ,40,40
86 /// </summary> 55 delete object pos ,,30 to ,,~
87 /// <param name='rawConsoleVector'> 56 delete object pos ,,-~ to ,,30";
88 /// A string in the form <x>,<y>,<z> where there is no space between values. 57
89 /// Any component can be missing (e.g. ,,40). blankComponentFunc is invoked to replace the blank with a suitable value 58 public const string MinRawConsoleVectorValue = "-~";
90 /// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40,30 or 40) 59 public const string MaxRawConsoleVectorValue = "~";
91 /// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue 60
92 /// Other than that, component values must be numeric. 61 public const string VectorSeparator = ",";
93 /// </param> 62 public static char[] VectorSeparatorChars = VectorSeparator.ToCharArray();
94 /// <param name='blankComponentFunc'></param> 63
95 /// <param name='vector'></param> 64 /// <summary>
96 /// <returns></returns> 65 /// Try to parse a console UUID from the console.
97 public static bool TryParseConsoleVector( 66 /// </summary>
98 string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector3 vector) 67 /// <remarks>
99 { 68 /// Will complain to the console if parsing fails.
100 List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList(); 69 /// </remarks>
101 70 /// <returns></returns>
102 if (components.Count < 1 || components.Count > 3) 71 /// <param name='console'></param>
72 /// <param name='rawUuid'></param>
73 /// <param name='uuid'></param>
74 public static bool TryParseConsoleUuid(ICommandConsole console, string rawUuid, out UUID uuid)
103 { 75 {
104 vector = Vector3.Zero; 76 if (!UUID.TryParse(rawUuid, out uuid))
105 return false; 77 {
78 console.OutputFormat("{0} is not a valid uuid", rawUuid);
79 return false;
80 }
81
82 return true;
83 }
84
85 /// <summary>
86 /// Convert a minimum vector input from the console to an OpenMetaverse.Vector3
87 /// </summary>
88 /// <param name='rawConsoleVector'>/param>
89 /// <param name='vector'></param>
90 /// <returns></returns>
91 public static bool TryParseConsoleMinVector(string rawConsoleVector, out Vector3 vector)
92 {
93 return TryParseConsoleVector(rawConsoleVector, c => float.MinValue.ToString(), out vector);
94 }
95
96 /// <summary>
97 /// Convert a maximum vector input from the console to an OpenMetaverse.Vector3
98 /// </summary>
99 /// <param name='rawConsoleVector'>/param>
100 /// <param name='vector'></param>
101 /// <returns></returns>
102 public static bool TryParseConsoleMaxVector(string rawConsoleVector, out Vector3 vector)
103 {
104 return TryParseConsoleVector(rawConsoleVector, c => float.MaxValue.ToString(), out vector);
105 }
106
107 /// <summary>
108 /// Convert a vector input from the console to an OpenMetaverse.Vector3
109 /// </summary>
110 /// <param name='rawConsoleVector'>
111 /// A string in the form <x>,<y>,<z> where there is no space between values.
112 /// Any component can be missing (e.g. ,,40). blankComponentFunc is invoked to replace the blank with a suitable value
113 /// Also, if the blank component is at the end, then the comma can be missed off entirely (e.g. 40,30 or 40)
114 /// The strings "~" and "-~" are valid in components. The first substitutes float.MaxValue whilst the second is float.MinValue
115 /// Other than that, component values must be numeric.
116 /// </param>
117 /// <param name='blankComponentFunc'></param>
118 /// <param name='vector'></param>
119 /// <returns></returns>
120 public static bool TryParseConsoleVector(
121 string rawConsoleVector, Func<string, string> blankComponentFunc, out Vector3 vector)
122 {
123 List<string> components = rawConsoleVector.Split(VectorSeparatorChars).ToList();
124
125 if (components.Count < 1 || components.Count > 3)
126 {
127 vector = Vector3.Zero;
128 return false;
129 }
130
131 for (int i = components.Count; i < 3; i++)
132 components.Add("");
133
134 List<string> semiDigestedComponents
135 = components.ConvertAll<string>(
136 c =>
137 {
138 if (c == "")
139 return blankComponentFunc.Invoke(c);
140 else if (c == MaxRawConsoleVectorValue)
141 return float.MaxValue.ToString();
142 else if (c == MinRawConsoleVectorValue)
143 return float.MinValue.ToString();
144 else
145 return c;
146 });
147
148 string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray());
149
150 // m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector);
151
152 return Vector3.TryParse(semiDigestedConsoleVector, out vector);
106 } 153 }
107
108 for (int i = components.Count; i < 3; i++)
109 components.Add("");
110
111 List<string> semiDigestedComponents
112 = components.ConvertAll<string>(
113 c =>
114 {
115 if (c == "")
116 return blankComponentFunc.Invoke(c);
117 else if (c == MaxRawConsoleVectorValue)
118 return float.MaxValue.ToString();
119 else if (c == MinRawConsoleVectorValue)
120 return float.MinValue.ToString();
121 else
122 return c;
123 });
124
125 string semiDigestedConsoleVector = string.Join(VectorSeparator, semiDigestedComponents.ToArray());
126
127// m_log.DebugFormat("[CONSOLE UTIL]: Parsing {0} into OpenMetaverse.Vector3", semiDigestedConsoleVector);
128
129 return Vector3.TryParse(semiDigestedConsoleVector, out vector);
130 } 154 }
131} \ No newline at end of file 155} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
index 6435ae6..41a1afd 100644
--- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
+++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs
@@ -27,10 +27,12 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.IO;
30using System.Linq; 31using System.Linq;
31using System.Reflection; 32using System.Reflection;
32using System.Text; 33using System.Text;
33using System.Text.RegularExpressions; 34using System.Text.RegularExpressions;
35using System.Xml;
34using log4net; 36using log4net;
35using Mono.Addins; 37using Mono.Addins;
36using NDesk.Options; 38using NDesk.Options;
@@ -41,6 +43,7 @@ using OpenSim.Framework.Console;
41using OpenSim.Framework.Monitoring; 43using OpenSim.Framework.Monitoring;
42using OpenSim.Region.Framework.Interfaces; 44using OpenSim.Region.Framework.Interfaces;
43using OpenSim.Region.Framework.Scenes; 45using OpenSim.Region.Framework.Scenes;
46using OpenSim.Region.Framework.Scenes.Serialization;
44 47
45namespace OpenSim.Region.CoreModules.World.Objects.Commands 48namespace OpenSim.Region.CoreModules.World.Objects.Commands
46{ 49{
@@ -181,6 +184,16 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
181 "Show details of scene object parts within the given area.", 184 "Show details of scene object parts within the given area.",
182 ConsoleUtil.CoordHelp, 185 ConsoleUtil.CoordHelp,
183 HandleShowPartByPos); 186 HandleShowPartByPos);
187
188 m_console.Commands.AddCommand(
189 "Objects",
190 false,
191 "dump object uuid",
192 "dump object uuid <UUID>",
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 in the first place, you need to use the other show object commands",
196 HandleDumpObjectByUuid);
184 } 197 }
185 198
186 public void RemoveRegion(Scene scene) 199 public void RemoveRegion(Scene scene)
@@ -447,6 +460,46 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands
447 OutputSopsToConsole(searchPredicate, true); 460 OutputSopsToConsole(searchPredicate, true);
448 } 461 }
449 462
463 private void HandleDumpObjectByUuid(string module, string[] cmdparams)
464 {
465 if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene))
466 return;
467
468 if (cmdparams.Length < 4)
469 {
470 m_console.OutputFormat("Usage: dump object uuid <uuid>");
471 return;
472 }
473
474 UUID objectUuid;
475 if (!ConsoleUtil.TryParseConsoleUuid(m_console, cmdparams[3], out objectUuid))
476 return;
477
478 SceneObjectGroup so = m_scene.GetSceneObjectGroup(objectUuid);
479
480 if (so == null)
481 {
482// m_console.OutputFormat("No part found with uuid {0}", objectUuid);
483 return;
484 }
485
486 string fileName = string.Format("{0}.xml", objectUuid);
487
488 if (File.Exists(fileName))
489 {
490 m_console.OutputFormat("File {0} already exists. Please move or remove it.", fileName);
491 return;
492 }
493
494 using (XmlTextWriter xtw = new XmlTextWriter(fileName, Encoding.UTF8))
495 {
496 xtw.Formatting = Formatting.Indented;
497 SceneObjectSerializer.ToOriginalXmlFormat(so, xtw, true);
498 }
499
500 m_console.OutputFormat("Object dumped to file {0}", fileName);
501 }
502
450 /// <summary> 503 /// <summary>
451 /// Append a scene object report to an input StringBuilder 504 /// Append a scene object report to an input StringBuilder
452 /// </summary> 505 /// </summary>