aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/OptionalModules/Avatar/Appearance
diff options
context:
space:
mode:
authorUbitUmarov2015-09-01 11:43:07 +0100
committerUbitUmarov2015-09-01 11:43:07 +0100
commitfb78b182520fc9bb0f971afd0322029c70278ea6 (patch)
treeb4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Region/OptionalModules/Avatar/Appearance
parentlixo (diff)
parentMantis #7713: fixed bug introduced by 1st MOSES patch. (diff)
downloadopensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.zip
opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz
opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2
opensim-SC_OLD-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/Appearance')
-rw-r--r--OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs482
1 files changed, 482 insertions, 0 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
new file mode 100644
index 0000000..2f9bb1e
--- /dev/null
+++ b/OpenSim/Region/OptionalModules/Avatar/Appearance/AppearanceInfoModule.cs
@@ -0,0 +1,482 @@
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
28using System;
29using System.Collections.Generic;
30using System.Linq;
31using System.Reflection;
32using System.Text;
33using log4net;
34using Mono.Addins;
35using Nini.Config;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Framework.Console;
39using OpenSim.Framework.Monitoring;
40using OpenSim.Region.ClientStack.LindenUDP;
41using OpenSim.Region.Framework.Interfaces;
42using OpenSim.Region.Framework.Scenes;
43
44namespace OpenSim.Region.OptionalModules.Avatar.Appearance
45{
46 /// <summary>
47 /// A module that just holds commands for inspecting avatar appearance.
48 /// </summary>
49 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AppearanceInfoModule")]
50 public class AppearanceInfoModule : ISharedRegionModule
51 {
52// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53
54 private List<Scene> m_scenes = new List<Scene>();
55
56// private IAvatarFactoryModule m_avatarFactory;
57
58 public string Name { get { return "Appearance Information Module"; } }
59
60 public Type ReplaceableInterface { get { return null; } }
61
62 public void Initialise(IConfigSource source)
63 {
64// m_log.DebugFormat("[APPEARANCE INFO MODULE]: INITIALIZED MODULE");
65 }
66
67 public void PostInitialise()
68 {
69// m_log.DebugFormat("[APPEARANCE INFO MODULE]: POST INITIALIZED MODULE");
70 }
71
72 public void Close()
73 {
74// m_log.DebugFormat("[APPEARANCE INFO MODULE]: CLOSED MODULE");
75 }
76
77 public void AddRegion(Scene scene)
78 {
79// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName);
80 }
81
82 public void RemoveRegion(Scene scene)
83 {
84// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
85
86 lock (m_scenes)
87 m_scenes.Remove(scene);
88 }
89
90 public void RegionLoaded(Scene scene)
91 {
92// m_log.DebugFormat("[APPEARANCE INFO MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName);
93
94 lock (m_scenes)
95 m_scenes.Add(scene);
96
97 scene.AddCommand(
98 "Users", this, "show appearance",
99 "show appearance [<first-name> <last-name>]",
100 "Synonym for 'appearance show'",
101 HandleShowAppearanceCommand);
102
103 scene.AddCommand(
104 "Users", this, "appearance show",
105 "appearance show [<first-name> <last-name>]",
106 "Show appearance information for avatars.",
107 "This command checks whether the simulator has all the baked textures required to display an avatar to other viewers. "
108 + "\nIf not, then appearance is 'corrupt' and other avatars will continue to see it as a cloud."
109 + "\nOptionally, you can view just a particular avatar's appearance information."
110 + "\nIn this case, the texture UUID for each bake type is also shown and whether the simulator can find the referenced texture.",
111 HandleShowAppearanceCommand);
112
113 scene.AddCommand(
114 "Users", this, "appearance send",
115 "appearance send [<first-name> <last-name>]",
116 "Send appearance data for each avatar in the simulator to other viewers.",
117 "Optionally, you can specify that only a particular avatar's appearance data is sent.",
118 HandleSendAppearanceCommand);
119
120 scene.AddCommand(
121 "Users", this, "appearance rebake",
122 "appearance rebake <first-name> <last-name>",
123 "Send a request to the user's viewer for it to rebake and reupload its appearance textures.",
124 "This is currently done for all baked texture references previously received, whether the simulator can find the asset or not."
125 + "\nThis will only work for texture ids that the viewer has already uploaded."
126 + "\nIf the viewer has not yet sent the server any texture ids then nothing will happen"
127 + "\nsince requests can only be made for ids that the client has already sent us",
128 HandleRebakeAppearanceCommand);
129
130 scene.AddCommand(
131 "Users", this, "appearance find",
132 "appearance find <uuid-or-start-of-uuid>",
133 "Find out which avatar uses the given asset as a baked texture, if any.",
134 "You can specify just the beginning of the uuid, e.g. 2008a8d. A longer UUID must be in dashed format.",
135 HandleFindAppearanceCommand);
136
137 scene.AddCommand(
138 "Users", this, "wearables show",
139 "wearables show [<first-name> <last-name>]",
140 "Show information about wearables for avatars.",
141 "If no avatar name is given then a general summary for all avatars in the scene is shown.\n"
142 + "If an avatar name is given then specific information about current wearables is shown.",
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);
151 }
152
153 private void HandleSendAppearanceCommand(string module, string[] cmd)
154 {
155 if (cmd.Length != 2 && cmd.Length < 4)
156 {
157 MainConsole.Instance.OutputFormat("Usage: appearance send [<first-name> <last-name>]");
158 return;
159 }
160
161 bool targetNameSupplied = false;
162 string optionalTargetFirstName = null;
163 string optionalTargetLastName = null;
164
165 if (cmd.Length >= 4)
166 {
167 targetNameSupplied = true;
168 optionalTargetFirstName = cmd[2];
169 optionalTargetLastName = cmd[3];
170 }
171
172 lock (m_scenes)
173 {
174 foreach (Scene scene in m_scenes)
175 {
176 if (targetNameSupplied)
177 {
178 ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName);
179 if (sp != null && !sp.IsChildAgent)
180 {
181 MainConsole.Instance.OutputFormat(
182 "Sending appearance information for {0} to all other avatars in {1}",
183 sp.Name, scene.RegionInfo.RegionName);
184
185 scene.AvatarFactory.SendAppearance(sp.UUID);
186 }
187 }
188 else
189 {
190 scene.ForEachRootScenePresence(
191 sp =>
192 {
193 MainConsole.Instance.OutputFormat(
194 "Sending appearance information for {0} to all other avatars in {1}",
195 sp.Name, scene.RegionInfo.RegionName);
196
197 scene.AvatarFactory.SendAppearance(sp.UUID);
198 }
199 );
200 }
201 }
202 }
203 }
204
205 private void HandleShowAppearanceCommand(string module, string[] cmd)
206 {
207 if (cmd.Length != 2 && cmd.Length < 4)
208 {
209 MainConsole.Instance.OutputFormat("Usage: appearance show [<first-name> <last-name>]");
210 return;
211 }
212
213 bool targetNameSupplied = false;
214 string optionalTargetFirstName = null;
215 string optionalTargetLastName = null;
216
217 if (cmd.Length >= 4)
218 {
219 targetNameSupplied = true;
220 optionalTargetFirstName = cmd[2];
221 optionalTargetLastName = cmd[3];
222 }
223
224 lock (m_scenes)
225 {
226 foreach (Scene scene in m_scenes)
227 {
228 if (targetNameSupplied)
229 {
230 ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName);
231 if (sp != null && !sp.IsChildAgent)
232 scene.AvatarFactory.WriteBakedTexturesReport(sp, MainConsole.Instance.OutputFormat);
233 }
234 else
235 {
236 scene.ForEachRootScenePresence(
237 sp =>
238 {
239 bool bakedTextureValid = scene.AvatarFactory.ValidateBakedTextureCache(sp);
240 MainConsole.Instance.OutputFormat(
241 "{0} baked appearance texture is {1}", sp.Name, bakedTextureValid ? "OK" : "incomplete");
242 }
243 );
244 }
245 }
246 }
247 }
248
249 private void HandleRebakeAppearanceCommand(string module, string[] cmd)
250 {
251 if (cmd.Length != 4)
252 {
253 MainConsole.Instance.OutputFormat("Usage: appearance rebake <first-name> <last-name>");
254 return;
255 }
256
257 string firstname = cmd[2];
258 string lastname = cmd[3];
259
260 lock (m_scenes)
261 {
262 foreach (Scene scene in m_scenes)
263 {
264 ScenePresence sp = scene.GetScenePresence(firstname, lastname);
265 if (sp != null && !sp.IsChildAgent)
266 {
267 int rebakesRequested = scene.AvatarFactory.RequestRebake(sp, false);
268
269 if (rebakesRequested > 0)
270 MainConsole.Instance.OutputFormat(
271 "Requesting rebake of {0} uploaded textures for {1} in {2}",
272 rebakesRequested, sp.Name, scene.RegionInfo.RegionName);
273 else
274 MainConsole.Instance.OutputFormat(
275 "No texture IDs available for rebake request for {0} in {1}",
276 sp.Name, scene.RegionInfo.RegionName);
277 }
278 }
279 }
280 }
281
282 private void HandleFindAppearanceCommand(string module, string[] cmd)
283 {
284 if (cmd.Length != 3)
285 {
286 MainConsole.Instance.OutputFormat("Usage: appearance find <uuid-or-start-of-uuid>");
287 return;
288 }
289
290 string rawUuid = cmd[2];
291
292 HashSet<ScenePresence> matchedAvatars = new HashSet<ScenePresence>();
293
294 lock (m_scenes)
295 {
296 foreach (Scene scene in m_scenes)
297 {
298 scene.ForEachRootScenePresence(
299 sp =>
300 {
301 Dictionary<BakeType, Primitive.TextureEntryFace> bakedFaces = scene.AvatarFactory.GetBakedTextureFaces(sp.UUID);
302 foreach (Primitive.TextureEntryFace face in bakedFaces.Values)
303 {
304 if (face != null && face.TextureID.ToString().StartsWith(rawUuid))
305 matchedAvatars.Add(sp);
306 }
307 });
308 }
309 }
310
311 if (matchedAvatars.Count == 0)
312 {
313 MainConsole.Instance.OutputFormat("{0} did not match any baked avatar textures in use", rawUuid);
314 }
315 else
316 {
317 MainConsole.Instance.OutputFormat(
318 "{0} matched {1}",
319 rawUuid,
320 string.Join(", ", matchedAvatars.ToList().ConvertAll<string>(sp => sp.Name).ToArray()));
321 }
322 }
323
324 protected void HandleShowWearablesCommand(string module, string[] cmd)
325 {
326 if (cmd.Length != 2 && cmd.Length < 4)
327 {
328 MainConsole.Instance.OutputFormat("Usage: wearables show [<first-name> <last-name>]");
329 return;
330 }
331
332 bool targetNameSupplied = false;
333 string optionalTargetFirstName = null;
334 string optionalTargetLastName = null;
335
336 if (cmd.Length >= 4)
337 {
338 targetNameSupplied = true;
339 optionalTargetFirstName = cmd[2];
340 optionalTargetLastName = cmd[3];
341 }
342
343 StringBuilder sb = new StringBuilder();
344
345 if (targetNameSupplied)
346 {
347 lock (m_scenes)
348 {
349 foreach (Scene scene in m_scenes)
350 {
351 ScenePresence sp = scene.GetScenePresence(optionalTargetFirstName, optionalTargetLastName);
352 if (sp != null && !sp.IsChildAgent)
353 AppendWearablesDetailReport(sp, sb);
354 }
355 }
356 }
357 else
358 {
359 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
360 cdt.AddColumn("Name", ConsoleDisplayUtil.UserNameSize);
361 cdt.AddColumn("Wearables", 2);
362
363 lock (m_scenes)
364 {
365 foreach (Scene scene in m_scenes)
366 {
367 scene.ForEachRootScenePresence(
368 sp =>
369 {
370 int count = 0;
371
372 for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++)
373 count += sp.Appearance.Wearables[i].Count;
374
375 cdt.AddRow(sp.Name, count);
376 }
377 );
378 }
379 }
380
381 sb.Append(cdt.ToString());
382 }
383
384 MainConsole.Instance.Output(sb.ToString());
385 }
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 uuidGatherer.AddForInspection(wi.AssetID);
430 uuidGatherer.GatherAll();
431 string[] assetStrings
432 = Array.ConvertAll<UUID, string>(uuidGatherer.GatheredUuids.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(
444 (AssetType)uuidGatherer.GatheredUuids[new UUID(assetStrings[k])],
445 assetStrings[k], existChecks[k] ? "yes" : "no");
446
447 sb.Append(cdt.ToString());
448 sb.Append("\n");
449 }
450 }
451 }
452 }
453 }
454 }
455
456 MainConsole.Instance.Output(sb.ToString());
457 }
458
459 private void AppendWearablesDetailReport(ScenePresence sp, StringBuilder sb)
460 {
461 sb.AppendFormat("\nWearables for {0}\n", sp.Name);
462
463 ConsoleDisplayTable cdt = new ConsoleDisplayTable();
464 cdt.AddColumn("Type", 10);
465 cdt.AddColumn("Item UUID", ConsoleDisplayUtil.UuidSize);
466 cdt.AddColumn("Asset UUID", ConsoleDisplayUtil.UuidSize);
467
468 for (int i = (int)WearableType.Shape; i < (int)WearableType.Physics; i++)
469 {
470 AvatarWearable aw = sp.Appearance.Wearables[i];
471
472 for (int j = 0; j < aw.Count; j++)
473 {
474 WearableItem wi = aw[j];
475 cdt.AddRow(Enum.GetName(typeof(WearableType), i), wi.ItemID, wi.AssetID);
476 }
477 }
478
479 sb.Append(cdt.ToString());
480 }
481 }
482} \ No newline at end of file