diff options
author | Justin Clark-Casey (justincc) | 2014-10-28 23:00:49 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2014-11-25 23:23:09 +0000 |
commit | 3a1ce2715a522dcb1971944af17ad10d2263c7ab (patch) | |
tree | 910296da502f599c8d019c88fdcea7128eff25be /OpenSim | |
parent | Add "wearables show" console command. (diff) | |
download | opensim-SC_OLD-3a1ce2715a522dcb1971944af17ad10d2263c7ab.zip opensim-SC_OLD-3a1ce2715a522dcb1971944af17ad10d2263c7ab.tar.gz opensim-SC_OLD-3a1ce2715a522dcb1971944af17ad10d2263c7ab.tar.bz2 opensim-SC_OLD-3a1ce2715a522dcb1971944af17ad10d2263c7ab.tar.xz |
Add "wearables check" console command
This checks that all the wearable assets and any assets for a given logged in avatar exist in the asset service
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/UuidGatherer.cs | 222 | ||||
-rw-r--r-- | OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | 96 |
2 files changed, 245 insertions, 73 deletions
diff --git a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs index d07cc6a..20ff5b5 100644 --- a/OpenSim/Region/Framework/Scenes/UuidGatherer.cs +++ b/OpenSim/Region/Framework/Scenes/UuidGatherer.cs | |||
@@ -72,6 +72,67 @@ namespace OpenSim.Region.Framework.Scenes | |||
72 | { | 72 | { |
73 | m_assetService = assetService; | 73 | m_assetService = assetService; |
74 | } | 74 | } |
75 | |||
76 | /// <summary> | ||
77 | /// Gather all the asset uuids associated with the asset referenced by a given uuid | ||
78 | /// </summary> | ||
79 | /// <remarks> | ||
80 | /// This includes both those directly associated with | ||
81 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
82 | /// within this object). | ||
83 | /// This method assumes that the asset type associated with this asset in persistent storage is correct (which | ||
84 | /// should always be the case). So with this method we always need to retrieve asset data even if the asset | ||
85 | /// is of a type which is known not to reference any other assets | ||
86 | /// </remarks> | ||
87 | /// <param name="assetUuid">The uuid of the asset for which to gather referenced assets</param> | ||
88 | /// <param name="assetUuids">The assets gathered</param> | ||
89 | public void GatherAssetUuids(UUID assetUuid, IDictionary<UUID, sbyte> assetUuids) | ||
90 | { | ||
91 | // avoid infinite loops | ||
92 | if (assetUuids.ContainsKey(assetUuid)) | ||
93 | return; | ||
94 | |||
95 | try | ||
96 | { | ||
97 | AssetBase assetBase = GetAsset(assetUuid); | ||
98 | |||
99 | if (null != assetBase) | ||
100 | { | ||
101 | sbyte assetType = assetBase.Type; | ||
102 | assetUuids[assetUuid] = assetType; | ||
103 | |||
104 | if ((sbyte)AssetType.Bodypart == assetType || (sbyte)AssetType.Clothing == assetType) | ||
105 | { | ||
106 | GetWearableAssetUuids(assetBase, assetUuids); | ||
107 | } | ||
108 | else if ((sbyte)AssetType.Gesture == assetType) | ||
109 | { | ||
110 | GetGestureAssetUuids(assetBase, assetUuids); | ||
111 | } | ||
112 | else if ((sbyte)AssetType.Notecard == assetType) | ||
113 | { | ||
114 | GetTextEmbeddedAssetUuids(assetBase, assetUuids); | ||
115 | } | ||
116 | else if ((sbyte)AssetType.LSLText == assetType) | ||
117 | { | ||
118 | GetTextEmbeddedAssetUuids(assetBase, assetUuids); | ||
119 | } | ||
120 | else if ((sbyte)OpenSimAssetType.Material == assetType) | ||
121 | { | ||
122 | GetMaterialAssetUuids(assetBase, assetUuids); | ||
123 | } | ||
124 | else if ((sbyte)AssetType.Object == assetType) | ||
125 | { | ||
126 | GetSceneObjectAssetUuids(assetBase, assetUuids); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | catch (Exception) | ||
131 | { | ||
132 | m_log.ErrorFormat("[UUID GATHERER]: Failed to gather uuids for asset id {0}", assetUuid); | ||
133 | throw; | ||
134 | } | ||
135 | } | ||
75 | 136 | ||
76 | /// <summary> | 137 | /// <summary> |
77 | /// Gather all the asset uuids associated with the asset referenced by a given uuid | 138 | /// Gather all the asset uuids associated with the asset referenced by a given uuid |
@@ -246,19 +307,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
246 | } | 307 | } |
247 | } | 308 | } |
248 | 309 | ||
249 | // /// <summary> | ||
250 | // /// The callback made when we request the asset for an object from the asset service. | ||
251 | // /// </summary> | ||
252 | // private void AssetReceived(string id, Object sender, AssetBase asset) | ||
253 | // { | ||
254 | // lock (this) | ||
255 | // { | ||
256 | // m_requestedObjectAsset = asset; | ||
257 | // m_waitingForObjectAsset = false; | ||
258 | // Monitor.Pulse(this); | ||
259 | // } | ||
260 | // } | ||
261 | |||
262 | /// <summary> | 310 | /// <summary> |
263 | /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps | 311 | /// Gather all of the texture asset UUIDs used to reference "Materials" such as normal and specular maps |
264 | /// stored in legacy format in part.DynAttrs | 312 | /// stored in legacy format in part.DynAttrs |
@@ -362,32 +410,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
362 | } | 410 | } |
363 | 411 | ||
364 | /// <summary> | 412 | /// <summary> |
365 | /// Record the asset uuids embedded within the given script. | 413 | /// Record the asset uuids embedded within the given text (e.g. a script). |
366 | /// </summary> | 414 | /// </summary> |
367 | /// <param name="scriptUuid"></param> | 415 | /// <param name="textAssetUuid"></param> |
368 | /// <param name="assetUuids">Dictionary in which to record the references</param> | 416 | /// <param name="assetUuids">Dictionary in which to record the references</param> |
369 | private void GetTextEmbeddedAssetUuids(UUID embeddingAssetId, IDictionary<UUID, sbyte> assetUuids) | 417 | private void GetTextEmbeddedAssetUuids(UUID textAssetUuid, IDictionary<UUID, sbyte> assetUuids) |
370 | { | 418 | { |
371 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); | 419 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); |
372 | 420 | ||
373 | AssetBase embeddingAsset = GetAsset(embeddingAssetId); | 421 | AssetBase textAsset = GetAsset(textAssetUuid); |
374 | 422 | ||
375 | if (null != embeddingAsset) | 423 | if (null != textAsset) |
376 | { | 424 | GetTextEmbeddedAssetUuids(textAsset, assetUuids); |
377 | string script = Utils.BytesToString(embeddingAsset.Data); | 425 | } |
378 | // m_log.DebugFormat("[ARCHIVER]: Script {0}", script); | ||
379 | MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script); | ||
380 | // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count); | ||
381 | 426 | ||
382 | foreach (Match uuidMatch in uuidMatches) | 427 | /// <summary> |
383 | { | 428 | /// Record the asset uuids embedded within the given text (e.g. a script). |
384 | UUID uuid = new UUID(uuidMatch.Value); | 429 | /// </summary> |
385 | // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); | 430 | /// <param name="textAsset"></param> |
431 | /// <param name="assetUuids">Dictionary in which to record the references</param> | ||
432 | private void GetTextEmbeddedAssetUuids(AssetBase textAsset, IDictionary<UUID, sbyte> assetUuids) | ||
433 | { | ||
434 | // m_log.DebugFormat("[ASSET GATHERER]: Getting assets for uuid references in asset {0}", embeddingAssetId); | ||
386 | 435 | ||
387 | // Embedded asset references (if not false positives) could be for many types of asset, so we will | 436 | string script = Utils.BytesToString(textAsset.Data); |
388 | // label these as unknown. | 437 | // m_log.DebugFormat("[ARCHIVER]: Script {0}", script); |
389 | assetUuids[uuid] = (sbyte)AssetType.Unknown; | 438 | MatchCollection uuidMatches = Util.PermissiveUUIDPattern.Matches(script); |
390 | } | 439 | // m_log.DebugFormat("[ARCHIVER]: Found {0} matches in text", uuidMatches.Count); |
440 | |||
441 | foreach (Match uuidMatch in uuidMatches) | ||
442 | { | ||
443 | UUID uuid = new UUID(uuidMatch.Value); | ||
444 | // m_log.DebugFormat("[ARCHIVER]: Recording {0} in text", uuid); | ||
445 | |||
446 | // Embedded asset references (if not false positives) could be for many types of asset, so we will | ||
447 | // label these as unknown. | ||
448 | assetUuids[uuid] = (sbyte)AssetType.Unknown; | ||
391 | } | 449 | } |
392 | } | 450 | } |
393 | 451 | ||
@@ -401,18 +459,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
401 | AssetBase assetBase = GetAsset(wearableAssetUuid); | 459 | AssetBase assetBase = GetAsset(wearableAssetUuid); |
402 | 460 | ||
403 | if (null != assetBase) | 461 | if (null != assetBase) |
462 | GetWearableAssetUuids(assetBase, assetUuids); | ||
463 | } | ||
464 | |||
465 | /// <summary> | ||
466 | /// Record the uuids referenced by the given wearable asset | ||
467 | /// </summary> | ||
468 | /// <param name="assetBase"></param> | ||
469 | /// <param name="assetUuids">Dictionary in which to record the references</param> | ||
470 | private void GetWearableAssetUuids(AssetBase assetBase, IDictionary<UUID, sbyte> assetUuids) | ||
471 | { | ||
472 | //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); | ||
473 | AssetWearable wearableAsset = new AssetBodypart(assetBase.FullID, assetBase.Data); | ||
474 | wearableAsset.Decode(); | ||
475 | |||
476 | //m_log.DebugFormat( | ||
477 | // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count); | ||
478 | |||
479 | foreach (UUID uuid in wearableAsset.Textures.Values) | ||
404 | { | 480 | { |
405 | //m_log.Debug(new System.Text.ASCIIEncoding().GetString(bodypartAsset.Data)); | 481 | assetUuids[uuid] = (sbyte)AssetType.Texture; |
406 | AssetWearable wearableAsset = new AssetBodypart(wearableAssetUuid, assetBase.Data); | ||
407 | wearableAsset.Decode(); | ||
408 | |||
409 | //m_log.DebugFormat( | ||
410 | // "[ARCHIVER]: Wearable asset {0} references {1} assets", wearableAssetUuid, wearableAsset.Textures.Count); | ||
411 | |||
412 | foreach (UUID uuid in wearableAsset.Textures.Values) | ||
413 | { | ||
414 | assetUuids[uuid] = (sbyte)AssetType.Texture; | ||
415 | } | ||
416 | } | 482 | } |
417 | } | 483 | } |
418 | 484 | ||
@@ -425,25 +491,35 @@ namespace OpenSim.Region.Framework.Scenes | |||
425 | /// <param name="assetUuids"></param> | 491 | /// <param name="assetUuids"></param> |
426 | private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids) | 492 | private void GetSceneObjectAssetUuids(UUID sceneObjectUuid, IDictionary<UUID, sbyte> assetUuids) |
427 | { | 493 | { |
428 | AssetBase objectAsset = GetAsset(sceneObjectUuid); | 494 | AssetBase sceneObjectAsset = GetAsset(sceneObjectUuid); |
429 | 495 | ||
430 | if (null != objectAsset) | 496 | if (null != sceneObjectAsset) |
497 | GetSceneObjectAssetUuids(sceneObjectAsset, assetUuids); | ||
498 | } | ||
499 | |||
500 | /// <summary> | ||
501 | /// Get all the asset uuids associated with a given object. This includes both those directly associated with | ||
502 | /// it (e.g. face textures) and recursively, those of items within it's inventory (e.g. objects contained | ||
503 | /// within this object). | ||
504 | /// </summary> | ||
505 | /// <param name="sceneObjectAsset"></param> | ||
506 | /// <param name="assetUuids"></param> | ||
507 | private void GetSceneObjectAssetUuids(AssetBase sceneObjectAsset, IDictionary<UUID, sbyte> assetUuids) | ||
508 | { | ||
509 | string xml = Utils.BytesToString(sceneObjectAsset.Data); | ||
510 | |||
511 | CoalescedSceneObjects coa; | ||
512 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) | ||
431 | { | 513 | { |
432 | string xml = Utils.BytesToString(objectAsset.Data); | 514 | foreach (SceneObjectGroup sog in coa.Objects) |
433 | 515 | GatherAssetUuids(sog, assetUuids); | |
434 | CoalescedSceneObjects coa; | 516 | } |
435 | if (CoalescedSceneObjectsSerializer.TryFromXml(xml, out coa)) | 517 | else |
436 | { | 518 | { |
437 | foreach (SceneObjectGroup sog in coa.Objects) | 519 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); |
438 | GatherAssetUuids(sog, assetUuids); | 520 | |
439 | } | 521 | if (null != sog) |
440 | else | 522 | GatherAssetUuids(sog, assetUuids); |
441 | { | ||
442 | SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xml); | ||
443 | |||
444 | if (null != sog) | ||
445 | GatherAssetUuids(sog, assetUuids); | ||
446 | } | ||
447 | } | 523 | } |
448 | } | 524 | } |
449 | 525 | ||
@@ -454,12 +530,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
454 | /// <param name="assetUuids"></param> | 530 | /// <param name="assetUuids"></param> |
455 | private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids) | 531 | private void GetGestureAssetUuids(UUID gestureUuid, IDictionary<UUID, sbyte> assetUuids) |
456 | { | 532 | { |
457 | AssetBase assetBase = GetAsset(gestureUuid); | 533 | AssetBase gestureAsset = GetAsset(gestureUuid); |
458 | if (null == assetBase) | 534 | if (null == gestureAsset) |
459 | return; | 535 | return; |
460 | 536 | ||
461 | using (MemoryStream ms = new MemoryStream(assetBase.Data)) | 537 | GetGestureAssetUuids(gestureAsset, assetUuids); |
462 | using (StreamReader sr = new StreamReader(ms)) | 538 | } |
539 | |||
540 | /// <summary> | ||
541 | /// Get the asset uuid associated with a gesture | ||
542 | /// </summary> | ||
543 | /// <param name="gestureAsset"></param> | ||
544 | /// <param name="assetUuids"></param> | ||
545 | private void GetGestureAssetUuids(AssetBase gestureAsset, IDictionary<UUID, sbyte> assetUuids) | ||
546 | { | ||
547 | using (MemoryStream ms = new MemoryStream(gestureAsset.Data)) | ||
548 | using (StreamReader sr = new StreamReader(ms)) | ||
463 | { | 549 | { |
464 | sr.ReadLine(); // Unknown (Version?) | 550 | sr.ReadLine(); // Unknown (Version?) |
465 | sr.ReadLine(); // Unknown | 551 | sr.ReadLine(); // Unknown |
@@ -500,7 +586,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
500 | if (null == assetBase) | 586 | if (null == assetBase) |
501 | return; | 587 | return; |
502 | 588 | ||
503 | OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(assetBase.Data); | 589 | GetMaterialAssetUuids(assetBase, assetUuids); |
590 | } | ||
591 | |||
592 | /// <summary> | ||
593 | /// Get the asset uuid's referenced in a material. | ||
594 | /// </summary> | ||
595 | private void GetMaterialAssetUuids(AssetBase materialAsset, IDictionary<UUID, sbyte> assetUuids) | ||
596 | { | ||
597 | OSDMap mat = (OSDMap)OSDParser.DeserializeLLSDXml(materialAsset.Data); | ||
504 | 598 | ||
505 | UUID normMap = mat["NormMap"].AsUUID(); | 599 | UUID normMap = mat["NormMap"].AsUUID(); |
506 | if (normMap != UUID.Zero) | 600 | if (normMap != UUID.Zero) |
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs index 51dfd47..f67f613 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs | |||
@@ -51,7 +51,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
51 | { | 51 | { |
52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
53 | 53 | ||
54 | private Dictionary<UUID, Scene> m_scenes = new Dictionary<UUID, Scene>(); | 54 | private List<Scene> m_scenes = new List<Scene>(); |
55 | |||
55 | // private IAvatarFactoryModule m_avatarFactory; | 56 | // private IAvatarFactoryModule m_avatarFactory; |
56 | 57 | ||
57 | public string Name { get { return "Appearance Information Module"; } } | 58 | public string Name { get { return "Appearance Information Module"; } } |
@@ -83,7 +84,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
83 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); | 84 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); |
84 | 85 | ||
85 | lock (m_scenes) | 86 | lock (m_scenes) |
86 | m_scenes.Remove(scene.RegionInfo.RegionID); | 87 | m_scenes.Remove(scene); |
87 | } | 88 | } |
88 | 89 | ||
89 | public void RegionLoaded(Scene scene) | 90 | public void RegionLoaded(Scene scene) |
@@ -91,7 +92,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
91 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); | 92 | // m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); |
92 | 93 | ||
93 | lock (m_scenes) | 94 | lock (m_scenes) |
94 | m_scenes[scene.RegionInfo.RegionID] = scene; | 95 | m_scenes.Add(scene); |
95 | 96 | ||
96 | scene.AddCommand( | 97 | scene.AddCommand( |
97 | "Users", this, "show appearance", | 98 | "Users", this, "show appearance", |
@@ -140,6 +141,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
140 | "If no avatar name is given then a general summary for all avatars in the scene is shown.\n" | 141 | "If no avatar name is given then a general summary for all avatars in the scene is shown.\n" |
141 | + "If an avatar name is given then specific information about current wearables is shown.", | 142 | + "If an avatar name is given then specific information about current wearables is shown.", |
142 | HandleShowWearablesCommand); | 143 | HandleShowWearablesCommand); |
144 | |||
145 | scene.AddCommand( | ||
146 | "Users", this, "wearables check", | ||
147 | "wearables check <first-name> <last-name>", | ||
148 | "Check that the wearables of a given avatar in the scene are valid.", | ||
149 | "This currently checks that the wearable assets themselves and any assets referenced by them exist.", | ||
150 | HandleCheckWearablesCommand); | ||
143 | } | 151 | } |
144 | 152 | ||
145 | private void HandleSendAppearanceCommand(string module, string[] cmd) | 153 | private void HandleSendAppearanceCommand(string module, string[] cmd) |
@@ -163,7 +171,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
163 | 171 | ||
164 | lock (m_scenes) | 172 | lock (m_scenes) |
165 | { | 173 | { |
166 | foreach (Scene scene in m_scenes.Values) | 174 | foreach (Scene scene in m_scenes) |
167 | { | 175 | { |
168 | if (targetNameSupplied) | 176 | if (targetNameSupplied) |
169 | { | 177 | { |
@@ -215,7 +223,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
215 | 223 | ||
216 | lock (m_scenes) | 224 | lock (m_scenes) |
217 | { | 225 | { |
218 | foreach (Scene scene in m_scenes.Values) | 226 | foreach (Scene scene in m_scenes) |
219 | { | 227 | { |
220 | if (targetNameSupplied) | 228 | if (targetNameSupplied) |
221 | { | 229 | { |
@@ -251,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
251 | 259 | ||
252 | lock (m_scenes) | 260 | lock (m_scenes) |
253 | { | 261 | { |
254 | foreach (Scene scene in m_scenes.Values) | 262 | foreach (Scene scene in m_scenes) |
255 | { | 263 | { |
256 | ScenePresence sp = scene.GetScenePresence(firstname, lastname); | 264 | ScenePresence sp = scene.GetScenePresence(firstname, lastname); |
257 | if (sp != null && !sp.IsChildAgent) | 265 | if (sp != null && !sp.IsChildAgent) |
@@ -285,7 +293,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
285 | 293 | ||
286 | lock (m_scenes) | 294 | lock (m_scenes) |
287 | { | 295 | { |
288 | foreach (Scene scene in m_scenes.Values) | 296 | foreach (Scene scene in m_scenes) |
289 | { | 297 | { |
290 | scene.ForEachRootScenePresence( | 298 | scene.ForEachRootScenePresence( |
291 | sp => | 299 | sp => |
@@ -338,7 +346,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
338 | { | 346 | { |
339 | lock (m_scenes) | 347 | lock (m_scenes) |
340 | { | 348 | { |
341 | foreach (Scene scene in m_scenes.Values) | 349 | foreach (Scene scene in m_scenes) |
342 | { | 350 | { |
343 | ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); | 351 | ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName); |
344 | if (sp != null && !sp.IsChildAgent) | 352 | if (sp != null && !sp.IsChildAgent) |
@@ -354,7 +362,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
354 | 362 | ||
355 | lock (m_scenes) | 363 | lock (m_scenes) |
356 | { | 364 | { |
357 | foreach (Scene scene in m_scenes.Values) | 365 | foreach (Scene scene in m_scenes) |
358 | { | 366 | { |
359 | scene.ForEachRootScenePresence( | 367 | scene.ForEachRootScenePresence( |
360 | sp => | 368 | sp => |
@@ -376,6 +384,76 @@ namespace OpenSim.Region.OptionalModules.Avatar.Appearance | |||
376 | MainConsole.Instance.Output(sb.ToString()); | 384 | MainConsole.Instance.Output(sb.ToString()); |
377 | } | 385 | } |
378 | 386 | ||
387 | private void HandleCheckWearablesCommand(string module, string[] cmd) | ||
388 | { | ||
389 | if (cmd.Length != 4) | ||
390 | { | ||
391 | MainConsole.Instance.OutputFormat("Usage: wearables check <first-name> <last-name>"); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | string firstname = cmd[2]; | ||
396 | string lastname = cmd[3]; | ||
397 | |||
398 | StringBuilder sb = new StringBuilder(); | ||
399 | UuidGatherer uuidGatherer = new UuidGatherer(m_scenes[0].AssetService); | ||
400 | |||
401 | lock (m_scenes) | ||
402 | { | ||
403 | foreach (Scene scene in m_scenes) | ||
404 | { | ||
405 | ScenePresence sp = scene.GetScenePresence(firstname, lastname); | ||
406 | if (sp != null && !sp.IsChildAgent) | ||
407 | { | ||
408 | sb.AppendFormat("Wearables checks for {0}\n\n", sp.Name); | ||
409 | |||
410 | for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++) | ||
411 | { | ||
412 | AvatarWearable aw = sp.Appearance.Wearables[i]; | ||
413 | |||
414 | if (aw.Count > 0) | ||
415 | { | ||
416 | sb.Append(Enum.GetName(typeof(WearableType), i)); | ||
417 | sb.Append("\n"); | ||
418 | |||
419 | for (int j = 0; j < aw.Count; j++) | ||
420 | { | ||
421 | WearableItem wi = aw[j]; | ||
422 | |||
423 | ConsoleDisplayList cdl = new ConsoleDisplayList(); | ||
424 | cdl.Indent = 2; | ||
425 | cdl.AddRow("Item UUID", wi.ItemID); | ||
426 | cdl.AddRow("Assets", ""); | ||
427 | sb.Append(cdl.ToString()); | ||
428 | |||
429 | Dictionary<UUID, sbyte> assetUuids = new Dictionary<UUID, sbyte>(); | ||
430 | uuidGatherer.GatherAssetUuids(wi.AssetID, assetUuids); | ||
431 | string[] assetStrings | ||
432 | = Array.ConvertAll<UUID, string>(assetUuids.Keys.ToArray(), u => u.ToString()); | ||
433 | |||
434 | bool[] existChecks = scene.AssetService.AssetsExist(assetStrings); | ||
435 | |||
436 | ConsoleDisplayTable cdt = new ConsoleDisplayTable(); | ||
437 | cdt.Indent = 4; | ||
438 | cdt.AddColumn("Type", 10); | ||
439 | cdt.AddColumn("UUID", ConsoleDisplayUtil.UuidSize); | ||
440 | cdt.AddColumn("Found", 5); | ||
441 | |||
442 | for (int k = 0; k < existChecks.Length; k++) | ||
443 | cdt.AddRow((AssetType)assetUuids[new UUID(assetStrings[k])], assetStrings[k], existChecks[k] ? "yes" : "no"); | ||
444 | |||
445 | sb.Append(cdt.ToString()); | ||
446 | sb.Append("\n"); | ||
447 | } | ||
448 | } | ||
449 | } | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | |||
454 | MainConsole.Instance.Output(sb.ToString()); | ||
455 | } | ||
456 | |||
379 | private void AppendWearablesDetailReport(ScenePresence sp, StringBuilder sb) | 457 | private void AppendWearablesDetailReport(ScenePresence sp, StringBuilder sb) |
380 | { | 458 | { |
381 | sb.AppendFormat("\nWearables for {0}\n", sp.Name); | 459 | sb.AppendFormat("\nWearables for {0}\n", sp.Name); |