2021-07-09 18:45:54 -05:00
|
|
|
/**
|
|
|
|
|
* Copyright (c) 2006-2016, openmetaverse.co
|
2022-01-02 09:04:28 -06:00
|
|
|
* Copyright (c) 2021-2022, Sjofn LLC.
|
2021-07-09 18:45:54 -05:00
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* - Redistribution and use in source and binary forms, with or without
|
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
|
*
|
|
|
|
|
* - Redistributions of source code must retain the above copyright notice, this
|
|
|
|
|
* list of conditions and the following disclaimer.
|
|
|
|
|
* - Neither the name of the openmetaverse.co nor the names
|
|
|
|
|
* of its contributors may be used to endorse or promote products derived from
|
|
|
|
|
* this software without specific prior written permission.
|
|
|
|
|
*
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
*/
|
|
|
|
|
|
2007-04-28 20:54:02 +00:00
|
|
|
using System;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Collections.Generic;
|
2009-05-12 00:07:35 +00:00
|
|
|
using OpenMetaverse.Assets;
|
2007-04-28 20:54:02 +00:00
|
|
|
|
2008-07-21 21:12:59 +00:00
|
|
|
namespace OpenMetaverse.TestClient
|
2007-04-28 20:54:02 +00:00
|
|
|
{
|
|
|
|
|
public class DumpOutfitCommand : Command
|
|
|
|
|
{
|
2008-07-25 05:15:05 +00:00
|
|
|
List<UUID> OutfitAssets = new List<UUID>();
|
2007-04-28 20:54:02 +00:00
|
|
|
|
|
|
|
|
public DumpOutfitCommand(TestClient testClient)
|
|
|
|
|
{
|
|
|
|
|
Name = "dumpoutfit";
|
|
|
|
|
Description = "Dumps all of the textures from an avatars outfit to the hard drive. Usage: dumpoutfit [avatar-uuid]";
|
2008-07-25 08:55:36 +00:00
|
|
|
Category = CommandCategory.Inventory;
|
|
|
|
|
|
2007-04-28 20:54:02 +00:00
|
|
|
}
|
|
|
|
|
|
2008-07-25 05:15:05 +00:00
|
|
|
public override string Execute(string[] args, UUID fromAgentID)
|
2007-04-28 20:54:02 +00:00
|
|
|
{
|
|
|
|
|
if (args.Length != 1)
|
|
|
|
|
return "Usage: dumpoutfit [avatar-uuid]";
|
|
|
|
|
|
2008-07-25 05:15:05 +00:00
|
|
|
UUID target;
|
2007-04-28 20:54:02 +00:00
|
|
|
|
2008-07-25 05:15:05 +00:00
|
|
|
if (!UUID.TryParse(args[0], out target))
|
2007-04-28 20:54:02 +00:00
|
|
|
return "Usage: dumpoutfit [avatar-uuid]";
|
|
|
|
|
|
2007-08-20 09:26:21 +00:00
|
|
|
lock (Client.Network.Simulators)
|
2007-04-28 20:54:02 +00:00
|
|
|
{
|
2021-07-25 11:10:52 -05:00
|
|
|
foreach (var sim in Client.Network.Simulators)
|
2007-04-28 20:54:02 +00:00
|
|
|
{
|
2021-07-25 11:10:52 -05:00
|
|
|
Avatar targetAv = sim.ObjectsAvatars.Find(
|
2020-05-09 12:59:06 -05:00
|
|
|
avatar => avatar.ID == target
|
2007-08-29 08:55:53 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (targetAv != null)
|
2007-04-28 20:54:02 +00:00
|
|
|
{
|
2007-08-29 08:55:53 +00:00
|
|
|
StringBuilder output = new StringBuilder("Downloading ");
|
|
|
|
|
|
|
|
|
|
lock (OutfitAssets) OutfitAssets.Clear();
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < targetAv.Textures.FaceTextures.Length; j++)
|
2007-08-20 09:26:21 +00:00
|
|
|
{
|
2008-08-24 05:06:51 +00:00
|
|
|
Primitive.TextureEntryFace face = targetAv.Textures.FaceTextures[j];
|
2007-04-28 20:54:02 +00:00
|
|
|
|
2007-08-29 08:55:53 +00:00
|
|
|
if (face != null)
|
|
|
|
|
{
|
|
|
|
|
ImageType type = ImageType.Normal;
|
2007-04-28 20:54:02 +00:00
|
|
|
|
2009-07-31 17:43:01 +00:00
|
|
|
switch ((AvatarTextureIndex)j)
|
2007-08-20 09:26:21 +00:00
|
|
|
{
|
2009-07-31 17:43:01 +00:00
|
|
|
case AvatarTextureIndex.HeadBaked:
|
|
|
|
|
case AvatarTextureIndex.EyesBaked:
|
|
|
|
|
case AvatarTextureIndex.UpperBaked:
|
|
|
|
|
case AvatarTextureIndex.LowerBaked:
|
|
|
|
|
case AvatarTextureIndex.SkirtBaked:
|
2007-08-29 08:55:53 +00:00
|
|
|
type = ImageType.Baked;
|
|
|
|
|
break;
|
2007-08-20 09:26:21 +00:00
|
|
|
}
|
2007-04-28 20:54:02 +00:00
|
|
|
|
2007-08-29 08:55:53 +00:00
|
|
|
OutfitAssets.Add(face.TextureID);
|
2009-05-07 16:10:52 +00:00
|
|
|
Client.Assets.RequestImage(face.TextureID, type, Assets_OnImageReceived);
|
2009-07-31 17:43:01 +00:00
|
|
|
output.Append(((AvatarTextureIndex)j).ToString());
|
2007-08-29 08:55:53 +00:00
|
|
|
output.Append(" ");
|
2007-08-20 09:26:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2007-08-29 08:55:53 +00:00
|
|
|
|
|
|
|
|
return output.ToString();
|
2007-04-28 20:54:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-25 19:38:11 -06:00
|
|
|
return "Couldn't find avatar " + target;
|
2007-04-28 20:54:02 +00:00
|
|
|
}
|
|
|
|
|
|
2009-05-07 16:10:52 +00:00
|
|
|
private void Assets_OnImageReceived(TextureRequestState state, AssetTexture assetTexture)
|
2007-04-28 20:54:02 +00:00
|
|
|
{
|
2007-07-11 09:17:46 +00:00
|
|
|
lock (OutfitAssets)
|
2007-04-28 20:54:02 +00:00
|
|
|
{
|
2009-05-07 16:10:52 +00:00
|
|
|
if (OutfitAssets.Contains(assetTexture.AssetID))
|
2007-04-28 20:54:02 +00:00
|
|
|
{
|
2009-05-07 16:10:52 +00:00
|
|
|
if (state == TextureRequestState.Finished)
|
2007-07-11 09:17:46 +00:00
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2009-05-07 16:10:52 +00:00
|
|
|
File.WriteAllBytes(assetTexture.AssetID + ".jp2", assetTexture.AssetData);
|
|
|
|
|
Console.WriteLine("Wrote JPEG2000 image " + assetTexture.AssetID + ".jp2");
|
2007-04-28 20:54:02 +00:00
|
|
|
|
2021-07-09 18:45:54 -05:00
|
|
|
using (var reader = new OpenJpegDotNet.IO.Reader(assetTexture.AssetData))
|
2021-07-04 18:01:05 -05:00
|
|
|
{
|
|
|
|
|
reader.ReadHeader();
|
2021-07-09 18:45:54 -05:00
|
|
|
OpenJpegDotNet.RawImage tga = reader.Decode().ToTarga();
|
|
|
|
|
File.WriteAllBytes(assetTexture.AssetID + ".tga", tga.Bytes);
|
2021-07-04 18:01:05 -05:00
|
|
|
}
|
2009-05-07 16:10:52 +00:00
|
|
|
Console.WriteLine("Wrote TGA image " + assetTexture.AssetID + ".tga");
|
2007-07-11 09:17:46 +00:00
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(e.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-05-07 16:10:52 +00:00
|
|
|
Console.WriteLine("Failed to download image " + assetTexture.AssetID);
|
2007-07-11 09:17:46 +00:00
|
|
|
}
|
|
|
|
|
|
2009-05-07 16:10:52 +00:00
|
|
|
OutfitAssets.Remove(assetTexture.AssetID);
|
2007-04-28 20:54:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|