diff options
author | Justin Clark-Casey (justincc) | 2012-05-15 22:43:47 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-05-15 23:42:49 +0100 |
commit | 02f3b116c6531f89314be6bc58115537147e512b (patch) | |
tree | 279e2077047146b12d63b4b65743b54eca5b7b68 /OpenSim/Region | |
parent | Save the Telehub and its Spawn Points in the OAR (diff) | |
download | opensim-SC-02f3b116c6531f89314be6bc58115537147e512b.zip opensim-SC-02f3b116c6531f89314be6bc58115537147e512b.tar.gz opensim-SC-02f3b116c6531f89314be6bc58115537147e512b.tar.bz2 opensim-SC-02f3b116c6531f89314be6bc58115537147e512b.tar.xz |
Allow use of regular expressions in "show object name", "show part name" and "delete object name" console commands if --regex switch is used.
Deleteing objects by name, creator uuid or owner uuid now requires confirmation to avoid accidental deletion.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | 309 |
1 files changed, 208 insertions, 101 deletions
diff --git a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs index 5e928f3..830d9cb 100644 --- a/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/Commands/ObjectCommandsModule.cs | |||
@@ -29,8 +29,10 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using System.Text; | 31 | using System.Text; |
32 | using System.Text.RegularExpressions; | ||
32 | using log4net; | 33 | using log4net; |
33 | using Mono.Addins; | 34 | using Mono.Addins; |
35 | using NDesk.Options; | ||
34 | using Nini.Config; | 36 | using Nini.Config; |
35 | using OpenMetaverse; | 37 | using OpenMetaverse; |
36 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
@@ -78,25 +80,31 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
78 | m_scene = scene; | 80 | m_scene = scene; |
79 | m_console = MainConsole.Instance; | 81 | m_console = MainConsole.Instance; |
80 | 82 | ||
81 | m_console.Commands.AddCommand("Objects", false, "delete object owner", | 83 | m_console.Commands.AddCommand( |
82 | "delete object owner <UUID>", | 84 | "Objects", false, "delete object owner", |
83 | "Delete a scene object by owner", HandleDeleteObject); | 85 | "delete object owner <UUID>", |
86 | "Delete a scene object by owner", HandleDeleteObject); | ||
84 | 87 | ||
85 | m_console.Commands.AddCommand("Objects", false, "delete object creator", | 88 | m_console.Commands.AddCommand( |
86 | "delete object creator <UUID>", | 89 | "Objects", false, "delete object creator", |
87 | "Delete a scene object by creator", HandleDeleteObject); | 90 | "delete object creator <UUID>", |
91 | "Delete a scene object by creator", HandleDeleteObject); | ||
88 | 92 | ||
89 | m_console.Commands.AddCommand("Objects", false, "delete object uuid", | 93 | m_console.Commands.AddCommand( |
90 | "delete object uuid <UUID>", | 94 | "Objects", false, "delete object uuid", |
91 | "Delete a scene object by uuid", HandleDeleteObject); | 95 | "delete object uuid <UUID>", |
96 | "Delete a scene object by uuid", HandleDeleteObject); | ||
92 | 97 | ||
93 | m_console.Commands.AddCommand("Objects", false, "delete object name", | 98 | m_console.Commands.AddCommand( |
94 | "delete object name <name>", | 99 | "Objects", false, "delete object name", |
95 | "Delete a scene object by name", HandleDeleteObject); | 100 | "delete object name [--regex] <name>", |
101 | "Delete a scene object by name.\nIf --regex is specified then the name is treatead as a regular expression", | ||
102 | HandleDeleteObject); | ||
96 | 103 | ||
97 | m_console.Commands.AddCommand("Objects", false, "delete object outside", | 104 | m_console.Commands.AddCommand( |
98 | "delete object outside", | 105 | "Objects", false, "delete object outside", |
99 | "Delete all scene objects outside region boundaries", HandleDeleteObject); | 106 | "delete object outside", |
107 | "Delete all scene objects outside region boundaries", HandleDeleteObject); | ||
100 | 108 | ||
101 | m_console.Commands.AddCommand( | 109 | m_console.Commands.AddCommand( |
102 | "Objects", | 110 | "Objects", |
@@ -109,8 +117,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
109 | "Objects", | 117 | "Objects", |
110 | false, | 118 | false, |
111 | "show object name", | 119 | "show object name", |
112 | "show object name <name>", | 120 | "show object name [--regex] <name>", |
113 | "Show details of scene objects with the given name", HandleShowObjectByName); | 121 | "Show details of scene objects with the given name.\nIf --regex is specified then the name is treatead as a regular expression", |
122 | HandleShowObjectByName); | ||
114 | 123 | ||
115 | m_console.Commands.AddCommand( | 124 | m_console.Commands.AddCommand( |
116 | "Objects", | 125 | "Objects", |
@@ -123,8 +132,9 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
123 | "Objects", | 132 | "Objects", |
124 | false, | 133 | false, |
125 | "show part name", | 134 | "show part name", |
126 | "show part name <name>", | 135 | "show part name [--regex] <name>", |
127 | "Show details of scene object parts with the given name", HandleShowPartByName); | 136 | "Show details of scene object parts with the given name.\nIf --regex is specified then the name is treatead as a regular expression", |
137 | HandleShowPartByName); | ||
128 | } | 138 | } |
129 | 139 | ||
130 | public void RemoveRegion(Scene scene) | 140 | public void RemoveRegion(Scene scene) |
@@ -169,22 +179,38 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
169 | m_console.OutputFormat(sb.ToString()); | 179 | m_console.OutputFormat(sb.ToString()); |
170 | } | 180 | } |
171 | 181 | ||
172 | private void HandleShowObjectByName(string module, string[] cmd) | 182 | private void HandleShowObjectByName(string module, string[] cmdparams) |
173 | { | 183 | { |
174 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 184 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
175 | return; | 185 | return; |
176 | 186 | ||
177 | if (cmd.Length < 4) | 187 | bool useRegex = false; |
188 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); | ||
189 | |||
190 | List<string> mainParams = options.Parse(cmdparams); | ||
191 | |||
192 | if (mainParams.Count < 4) | ||
178 | { | 193 | { |
179 | m_console.OutputFormat("Usage: show object name <name>"); | 194 | m_console.OutputFormat("Usage: show object name [--regex] <name>"); |
180 | return; | 195 | return; |
181 | } | 196 | } |
182 | 197 | ||
183 | string name = cmd[3]; | 198 | string name = mainParams[3]; |
184 | 199 | ||
185 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); | 200 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
201 | Action<SceneObjectGroup> searchAction; | ||
202 | |||
203 | if (useRegex) | ||
204 | { | ||
205 | Regex nameRegex = new Regex(name); | ||
206 | searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; | ||
207 | } | ||
208 | else | ||
209 | { | ||
210 | searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; | ||
211 | } | ||
186 | 212 | ||
187 | m_scene.ForEachSOG(so => { if (so.Name == name) { sceneObjects.Add(so); }}); | 213 | m_scene.ForEachSOG(searchAction); |
188 | 214 | ||
189 | if (sceneObjects.Count == 0) | 215 | if (sceneObjects.Count == 0) |
190 | { | 216 | { |
@@ -235,22 +261,39 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
235 | m_console.OutputFormat(sb.ToString()); | 261 | m_console.OutputFormat(sb.ToString()); |
236 | } | 262 | } |
237 | 263 | ||
238 | private void HandleShowPartByName(string module, string[] cmd) | 264 | private void HandleShowPartByName(string module, string[] cmdparams) |
239 | { | 265 | { |
240 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) | 266 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
241 | return; | 267 | return; |
242 | 268 | ||
243 | if (cmd.Length < 4) | 269 | bool useRegex = false; |
270 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); | ||
271 | |||
272 | List<string> mainParams = options.Parse(cmdparams); | ||
273 | |||
274 | if (mainParams.Count < 4) | ||
244 | { | 275 | { |
245 | m_console.OutputFormat("Usage: show part name <name>"); | 276 | m_console.OutputFormat("Usage: show part name [--regex] <name>"); |
246 | return; | 277 | return; |
247 | } | 278 | } |
248 | 279 | ||
249 | string name = cmd[3]; | 280 | string name = mainParams[3]; |
250 | 281 | ||
251 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); | 282 | List<SceneObjectPart> parts = new List<SceneObjectPart>(); |
252 | 283 | ||
253 | m_scene.ForEachSOG(so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } })); | 284 | Action<SceneObjectGroup> searchAction; |
285 | |||
286 | if (useRegex) | ||
287 | { | ||
288 | Regex nameRegex = new Regex(name); | ||
289 | searchAction = so => so.ForEachPart(sop => { if (nameRegex.IsMatch(sop.Name)) { parts.Add(sop); } }); | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | searchAction = so => so.ForEachPart(sop => { if (sop.Name == name) { parts.Add(sop); } }); | ||
294 | } | ||
295 | |||
296 | m_scene.ForEachSOG(searchAction); | ||
254 | 297 | ||
255 | if (parts.Count == 0) | 298 | if (parts.Count == 0) |
256 | { | 299 | { |
@@ -312,105 +355,169 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands | |||
312 | o = cmd[3]; | 355 | o = cmd[3]; |
313 | } | 356 | } |
314 | 357 | ||
315 | List<SceneObjectGroup> deletes = new List<SceneObjectGroup>(); | 358 | List<SceneObjectGroup> deletes = null; |
316 | |||
317 | UUID match; | 359 | UUID match; |
360 | bool requireConfirmation = true; | ||
318 | 361 | ||
319 | switch (mode) | 362 | switch (mode) |
320 | { | 363 | { |
321 | case "owner": | 364 | case "owner": |
322 | if (!UUID.TryParse(o, out match)) | 365 | if (!UUID.TryParse(o, out match)) |
323 | return; | 366 | return; |
324 | |||
325 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
326 | { | ||
327 | if (g.OwnerID == match && !g.IsAttachment) | ||
328 | deletes.Add(g); | ||
329 | }); | ||
330 | 367 | ||
331 | // if (deletes.Count == 0) | 368 | deletes = new List<SceneObjectGroup>(); |
332 | // m_console.OutputFormat("No objects were found with owner {0}", match); | ||
333 | 369 | ||
334 | break; | 370 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) |
371 | { | ||
372 | if (g.OwnerID == match && !g.IsAttachment) | ||
373 | deletes.Add(g); | ||
374 | }); | ||
375 | |||
376 | // if (deletes.Count == 0) | ||
377 | // m_console.OutputFormat("No objects were found with owner {0}", match); | ||
378 | |||
379 | break; | ||
380 | |||
381 | case "creator": | ||
382 | if (!UUID.TryParse(o, out match)) | ||
383 | return; | ||
335 | 384 | ||
336 | case "creator": | 385 | deletes = new List<SceneObjectGroup>(); |
337 | if (!UUID.TryParse(o, out match)) | ||
338 | return; | ||
339 | 386 | ||
340 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | 387 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) |
341 | { | 388 | { |
342 | if (g.RootPart.CreatorID == match && !g.IsAttachment) | 389 | if (g.RootPart.CreatorID == match && !g.IsAttachment) |
343 | deletes.Add(g); | 390 | deletes.Add(g); |
344 | }); | 391 | }); |
392 | |||
393 | // if (deletes.Count == 0) | ||
394 | // m_console.OutputFormat("No objects were found with creator {0}", match); | ||
395 | |||
396 | break; | ||
397 | |||
398 | case "uuid": | ||
399 | if (!UUID.TryParse(o, out match)) | ||
400 | return; | ||
345 | 401 | ||
346 | // if (deletes.Count == 0) | 402 | requireConfirmation = false; |
347 | // m_console.OutputFormat("No objects were found with creator {0}", match); | 403 | deletes = new List<SceneObjectGroup>(); |
404 | |||
405 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
406 | { | ||
407 | if (g.UUID == match && !g.IsAttachment) | ||
408 | deletes.Add(g); | ||
409 | }); | ||
410 | |||
411 | // if (deletes.Count == 0) | ||
412 | // m_console.OutputFormat("No objects were found with uuid {0}", match); | ||
413 | |||
414 | break; | ||
415 | |||
416 | case "name": | ||
417 | deletes = GetDeleteCandidatesByName(module, cmd); | ||
418 | break; | ||
419 | |||
420 | case "outside": | ||
421 | deletes = new List<SceneObjectGroup>(); | ||
348 | 422 | ||
349 | break; | 423 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) |
424 | { | ||
425 | SceneObjectPart rootPart = g.RootPart; | ||
426 | bool delete = false; | ||
427 | |||
428 | if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) | ||
429 | { | ||
430 | delete = true; | ||
431 | } | ||
432 | else | ||
433 | { | ||
434 | ILandObject parcel | ||
435 | = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); | ||
436 | |||
437 | if (parcel == null || parcel.LandData.Name == "NO LAND") | ||
438 | delete = true; | ||
439 | } | ||
440 | |||
441 | if (delete && !g.IsAttachment && !deletes.Contains(g)) | ||
442 | deletes.Add(g); | ||
443 | }); | ||
444 | |||
445 | if (deletes.Count == 0) | ||
446 | m_console.OutputFormat("No objects were found outside region bounds"); | ||
447 | |||
448 | break; | ||
350 | 449 | ||
351 | case "uuid": | 450 | default: |
352 | if (!UUID.TryParse(o, out match)) | 451 | m_console.OutputFormat("Unrecognized mode {0}", mode); |
353 | return; | 452 | return; |
453 | } | ||
354 | 454 | ||
355 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | 455 | if (deletes == null || deletes.Count <= 0) |
356 | { | 456 | return; |
357 | if (g.UUID == match && !g.IsAttachment) | ||
358 | deletes.Add(g); | ||
359 | }); | ||
360 | |||
361 | // if (deletes.Count == 0) | ||
362 | // m_console.OutputFormat("No objects were found with uuid {0}", match); | ||
363 | |||
364 | break; | ||
365 | 457 | ||
366 | case "name": | 458 | if (requireConfirmation) |
367 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | 459 | { |
460 | string response = MainConsole.Instance.CmdPrompt( | ||
461 | string.Format( | ||
462 | "Are you sure that you want to delete {0} objects from {1}", | ||
463 | deletes.Count, m_scene.RegionInfo.RegionName), | ||
464 | "n"); | ||
465 | |||
466 | if (response.ToLower() != "y") | ||
368 | { | 467 | { |
369 | if (g.RootPart.Name == o && !g.IsAttachment) | 468 | MainConsole.Instance.OutputFormat( |
370 | deletes.Add(g); | 469 | "Aborting delete of {0} objects from {1}", deletes.Count, m_scene.RegionInfo.RegionName); |
371 | }); | ||
372 | |||
373 | // if (deletes.Count == 0) | ||
374 | // m_console.OutputFormat("No objects were found with name {0}", o); | ||
375 | 470 | ||
376 | break; | 471 | return; |
472 | } | ||
473 | } | ||
377 | 474 | ||
378 | case "outside": | 475 | m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); |
379 | m_scene.ForEachSOG(delegate (SceneObjectGroup g) | ||
380 | { | ||
381 | SceneObjectPart rootPart = g.RootPart; | ||
382 | bool delete = false; | ||
383 | 476 | ||
384 | if (rootPart.GroupPosition.Z < 0.0 || rootPart.GroupPosition.Z > 10000.0) | 477 | foreach (SceneObjectGroup g in deletes) |
385 | { | 478 | { |
386 | delete = true; | 479 | m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); |
387 | } | 480 | m_scene.DeleteSceneObject(g, false); |
388 | else | 481 | } |
389 | { | 482 | } |
390 | ILandObject parcel | ||
391 | = m_scene.LandChannel.GetLandObject(rootPart.GroupPosition.X, rootPart.GroupPosition.Y); | ||
392 | 483 | ||
393 | if (parcel == null || parcel.LandData.Name == "NO LAND") | 484 | private List<SceneObjectGroup> GetDeleteCandidatesByName(string module, string[] cmdparams) |
394 | delete = true; | 485 | { |
395 | } | 486 | if (!(m_console.ConsoleScene == null || m_console.ConsoleScene == m_scene)) |
487 | return null; | ||
396 | 488 | ||
397 | if (delete && !g.IsAttachment && !deletes.Contains(g)) | 489 | bool useRegex = false; |
398 | deletes.Add(g); | 490 | OptionSet options = new OptionSet().Add("regex", v=> useRegex = v != null ); |
399 | }); | ||
400 | 491 | ||
401 | // if (deletes.Count == 0) | 492 | List<string> mainParams = options.Parse(cmdparams); |
402 | // m_console.OutputFormat("No objects were found outside region bounds"); | ||
403 | 493 | ||
404 | break; | 494 | if (mainParams.Count < 4) |
495 | { | ||
496 | m_console.OutputFormat("Usage: delete object name [--regex] <name>"); | ||
497 | return null; | ||
405 | } | 498 | } |
406 | 499 | ||
407 | m_console.OutputFormat("Deleting {0} objects in {1}", deletes.Count, m_scene.RegionInfo.RegionName); | 500 | string name = mainParams[3]; |
408 | 501 | ||
409 | foreach (SceneObjectGroup g in deletes) | 502 | List<SceneObjectGroup> sceneObjects = new List<SceneObjectGroup>(); |
503 | Action<SceneObjectGroup> searchAction; | ||
504 | |||
505 | if (useRegex) | ||
410 | { | 506 | { |
411 | m_console.OutputFormat("Deleting object {0} {1}", g.UUID, g.Name); | 507 | Regex nameRegex = new Regex(name); |
412 | m_scene.DeleteSceneObject(g, false); | 508 | searchAction = so => { if (nameRegex.IsMatch(so.Name)) { sceneObjects.Add(so); }}; |
509 | } | ||
510 | else | ||
511 | { | ||
512 | searchAction = so => { if (so.Name == name) { sceneObjects.Add(so); }}; | ||
413 | } | 513 | } |
514 | |||
515 | m_scene.ForEachSOG(searchAction); | ||
516 | |||
517 | if (sceneObjects.Count == 0) | ||
518 | m_console.OutputFormat("No objects with name {0} found in {1}", name, m_scene.RegionInfo.RegionName); | ||
519 | |||
520 | return sceneObjects; | ||
414 | } | 521 | } |
415 | } | 522 | } |
416 | } \ No newline at end of file | 523 | } \ No newline at end of file |