Files
NatiBot/SLBot/bot/Commands/Prims/ExportCommand.cs
2014-09-04 04:26:22 +01:00

315 lines
12 KiB
C#

/***************************************************************************
The Disc Image Chef
----------------------------------------------------------------------------
Filename : ExportCommand.cs
Version : 1.0.326
Author(s) : Natalia Portillo
Component : NatiBot
Revision : r326
Last change by : Natalia Portillo
Date : 2010/01/01
--[ License ] --------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
----------------------------------------------------------------------------
Copyright (C) 2008-2014 Claunia.com
****************************************************************************/
namespace bot.Commands
{
using bot;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using OpenMetaverse.Assets;
public class ExportCommand : Command
{
List<UUID> Textures = new List<UUID>();
AutoResetEvent GotPermissionsEvent = new AutoResetEvent(false);
Primitive.ObjectProperties Properties;
bool GotPermissions = false;
UUID SelectedObject = UUID.Zero;
Dictionary<UUID, Primitive> PrimsWaiting = new Dictionary<UUID, Primitive>();
AutoResetEvent AllPropertiesReceived = new AutoResetEvent(false);
public ExportCommand(SecondLifeBot SecondLifeBot)
{
SecondLifeBot.Objects.ObjectPropertiesFamily += new EventHandler<ObjectPropertiesFamilyEventArgs>(Objects_OnObjectPropertiesFamily);
SecondLifeBot.Objects.ObjectProperties += new EventHandler<ObjectPropertiesEventArgs>(Objects_OnObjectProperties);
SecondLifeBot.Avatars.ViewerEffectPointAt += new EventHandler<ViewerEffectPointAtEventArgs>(Avatars_ViewerEffectPointAt);
base.Name = "export";
base.Description = bot.Localization.clResourceManager.getText("Commands.Export.Description") + " " + bot.Localization.clResourceManager.getText("Commands.Export.Usage");
}
public override string Execute(string[] args, UUID fromAgentID, bool fromSL)
{
if (args.Length != 2 && !(args.Length == 1 && SelectedObject != UUID.Zero))
return bot.Localization.clResourceManager.getText("Commands.Export.Usage");
UUID id;
uint localid;
string file;
if (args.Length == 2)
{
file = args[1];
if (!UUID.TryParse(args[0], out id))
return bot.Localization.clResourceManager.getText("Commands.Export.Usage");
}
else
{
file = args[0];
id = SelectedObject;
}
Primitive exportPrim;
exportPrim = Client.Network.CurrentSim.ObjectsPrimitives.Find(
delegate(Primitive prim)
{
return prim.ID == id;
}
);
Program.NBStats.AddStatData(String.Format("{0}: {1} exporting object {2} on sim {3}.", DateTime.Now.ToString(), Client, id, Client.Network.CurrentSim.Name));
if (exportPrim != null)
{
if (exportPrim.ParentID != 0)
localid = exportPrim.ParentID;
else
localid = exportPrim.LocalID;
// Check for export permission first
Client.Objects.SelectObject(Client.Network.CurrentSim, localid);
Client.Objects.RequestObjectPropertiesFamily(Client.Network.CurrentSim, id);
GotPermissionsEvent.WaitOne(1000 * 10, false);
#if !DEBUG
if (!GotPermissions)
{
//return "Couldn't fetch permissions for the requested object, try again";
}
else
{
GotPermissions = false;
if (Properties.OwnerID != Client.Self.AgentID &&
Properties.OwnerID != Client.MasterKey || Properties.Permissions.EveryoneMask != PermissionMask.All)
{
return bot.Localization.clResourceManager.getText("NoPermissions");
}
}
#endif
List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll(
delegate(Primitive prim)
{
return (prim.LocalID == localid || prim.ParentID == localid);
}
);
bool complete = RequestObjectProperties(prims, 250);
if (!complete)
{
bot.Console.WriteLine(bot.Localization.clResourceManager.getText("Commands.Export.NotProperties"));
//foreach (UUID uuid in PrimsWaiting.Keys)
// bot.Console.WriteLine(uuid.ToString());
}
string output = OSDParser.SerializeLLSDXmlString(Helpers.PrimListToOSD(prims));
if (Directory.Exists("objects/") == false)
{
Directory.CreateDirectory("objects/");
}
try
{
File.WriteAllText("objects/" + file, output);
}
catch (Exception e)
{
return e.Message;
}
bot.Console.WriteLine(bot.Localization.clResourceManager.getText("Commands.Export.Exported"), prims.Count, file);
// Create a list of all of the textures to download
List<ImageRequest> textureRequests = new List<ImageRequest>();
lock (Textures)
{
for (int i = 0; i < prims.Count; i++)
{
Primitive prim = prims[i];
if (prim.Textures != null)
{
if (prim.Textures.DefaultTexture != null) //WTF
{
if (prim.Textures.DefaultTexture.TextureID != Primitive.TextureEntry.WHITE_TEXTURE &&
!Textures.Contains(prim.Textures.DefaultTexture.TextureID))
{
Textures.Add(prim.Textures.DefaultTexture.TextureID);
}
}
for (int j = 0; j < prim.Textures.FaceTextures.Length; j++)
{
if (prim.Textures.FaceTextures[j] != null &&
prim.Textures.FaceTextures[j].TextureID != Primitive.TextureEntry.WHITE_TEXTURE &&
!Textures.Contains(prim.Textures.FaceTextures[j].TextureID))
{
Textures.Add(prim.Textures.FaceTextures[j].TextureID);
}
}
}
if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero && !Textures.Contains(prim.Sculpt.SculptTexture))
{
Textures.Add(prim.Sculpt.SculptTexture);
}
}
// Create a request list from all of the images
for (int i = 0; i < Textures.Count; i++)
textureRequests.Add(new ImageRequest(Textures[i], ImageType.Normal, 1013000.0f, 0));
}
// Download all of the textures in the export list
foreach (ImageRequest request in textureRequests)
{
Client.Assets.RequestImage(request.ImageID, request.Type, Assets_OnImageReceived);
}
Client.Objects.DeselectObject(base.Client.Network.CurrentSim, localid);
return String.Format(bot.Localization.clResourceManager.getText("Commands.Export.Downloading"), Textures.Count);
}
else
{
return String.Format(bot.Localization.clResourceManager.getText("Commands.Export.NotFound"), id.ToString(),
Client.Network.CurrentSim.ObjectsPrimitives.Count);
}
}
private bool RequestObjectProperties(List<Primitive> objects, int msPerRequest)
{
// Create an array of the local IDs of all the prims we are requesting properties for
uint[] localids = new uint[objects.Count];
lock (PrimsWaiting)
{
PrimsWaiting.Clear();
for (int i = 0; i < objects.Count; ++i)
{
localids[i] = objects[i].LocalID;
PrimsWaiting.Add(objects[i].ID, objects[i]);
}
}
Client.Objects.SelectObjects(Client.Network.CurrentSim, localids);
return AllPropertiesReceived.WaitOne(2000 + msPerRequest * objects.Count, false);
}
private void Assets_OnImageReceived(TextureRequestState state, AssetTexture asset)
{
if (Directory.Exists("textures/") == false)
{
Directory.CreateDirectory("textures/");
}
if (state == TextureRequestState.Finished && Textures.Contains(asset.AssetID))
{
lock (Textures)
Textures.Remove(asset.AssetID);
if (state == TextureRequestState.Finished)
{
try
{
File.WriteAllBytes("textures/" + asset.AssetID + ".jp2", asset.AssetData);
}
catch (Exception ex)
{
bot.Console.WriteLine(ex.Message, Helpers.LogLevel.Error, Client);
}
if (asset.Decode())
{
try
{
File.WriteAllBytes("textures/" + asset.AssetID + ".tga", asset.Image.ExportTGA());
}
catch (Exception ex)
{
bot.Console.WriteLine(ex.Message, Helpers.LogLevel.Error, Client);
}
}
else
{
bot.Console.WriteLine(bot.Localization.clResourceManager.getText("Assets.Image.FailDecode"), asset.AssetID);
}
bot.Console.WriteLine(bot.Localization.clResourceManager.getText("Assets.Image.ImageDownloaded"), asset.AssetID);
}
else
{
bot.Console.WriteLine(bot.Localization.clResourceManager.getText("Assets.Image.FailDownload"), asset.AssetID, state);
}
}
}
void Avatars_ViewerEffectPointAt(object sender, ViewerEffectPointAtEventArgs e)
{
if (e.SourceID == Client.MasterKey)
{
//Client.DebugLog("Master is now selecting " + targetID.ToString());
SelectedObject = e.TargetID;
}
}
void Objects_OnObjectPropertiesFamily(object sender, ObjectPropertiesFamilyEventArgs e)
{
Properties = new Primitive.ObjectProperties();
Properties.SetFamilyProperties(e.Properties);
GotPermissions = true;
GotPermissionsEvent.Set();
}
void Objects_OnObjectProperties(object sender, ObjectPropertiesEventArgs e)
{
lock (PrimsWaiting)
{
PrimsWaiting.Remove(e.Properties.ObjectID);
if (PrimsWaiting.Count == 0)
AllPropertiesReceived.Set();
}
}
}
}