Moving examples, mapgenerator, and VisualParamGenerator to Programs folder (SVN is seriously ruined still, don't check out yet)

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1961 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
John Hurliman
2008-07-22 23:21:49 +00:00
parent ef71c02528
commit f2dde3daae
153 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,358 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.Xml;
using System.Xml.Serialization;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenMetaverse.TestClient;
namespace OpenMetaverse.TestClient
{
public class QueuedDownloadInfo
{
public LLUUID TransferID;
public LLUUID AssetID;
public LLUUID ItemID;
public LLUUID TaskID;
public LLUUID OwnerID;
public AssetType Type;
public string FileName;
public DateTime WhenRequested;
public bool IsRequested;
public QueuedDownloadInfo(string file, LLUUID asset, LLUUID item, LLUUID task, LLUUID owner, AssetType type)
{
FileName = file;
AssetID = asset;
ItemID = item;
TaskID = task;
OwnerID = owner;
Type = type;
TransferID = LLUUID.Zero;
WhenRequested = DateTime.Now;
IsRequested = false;
}
}
public class BackupCommand : Command
{
/// <summary>Maximum number of transfer requests to send to the server</summary>
private const int MAX_TRANSFERS = 10;
// all items here, fed by the inventory walking thread
private Queue<QueuedDownloadInfo> PendingDownloads = new Queue<QueuedDownloadInfo>();
// items sent to the server here
private List<QueuedDownloadInfo> CurrentDownloads = new List<QueuedDownloadInfo>(MAX_TRANSFERS);
// background workers
private BackgroundWorker BackupWorker;
private BackgroundWorker QueueWorker;
// some stats
private int TextItemsFound;
private int TextItemsTransferred;
private int TextItemErrors;
#region Properties
/// <summary>
/// true if either of the background threads is running
/// </summary>
private bool BackgroundBackupRunning
{
get { return InventoryWalkerRunning || QueueRunnerRunning; }
}
/// <summary>
/// true if the thread walking inventory is running
/// </summary>
private bool InventoryWalkerRunning
{
get { return BackupWorker != null; }
}
/// <summary>
/// true if the thread feeding the queue to the server is running
/// </summary>
private bool QueueRunnerRunning
{
get { return QueueWorker != null; }
}
/// <summary>
/// returns a string summarizing activity
/// </summary>
/// <returns></returns>
private string BackgroundBackupStatus
{
get
{
StringBuilder sbResult = new StringBuilder();
sbResult.AppendFormat("{0} is {1} running.", Name, BoolToNot(BackgroundBackupRunning));
if (TextItemErrors != 0 || TextItemsFound != 0 || TextItemsTransferred != 0)
{
sbResult.AppendFormat("\r\n{0} : Inventory walker ( {1} running ) has found {2} items.",
Name, BoolToNot(InventoryWalkerRunning), TextItemsFound);
sbResult.AppendFormat("\r\n{0} : Server Transfers ( {1} running ) has transferred {2} items with {3} errors.",
Name, BoolToNot(QueueRunnerRunning), TextItemsTransferred, TextItemErrors);
sbResult.AppendFormat("\r\n{0} : {1} items in Queue, {2} items requested from server.",
Name, PendingDownloads.Count, CurrentDownloads.Count);
}
return sbResult.ToString();
}
}
#endregion Properties
public BackupCommand(TestClient testClient)
{
Name = "backuptext";
Description = "Backup inventory to a folder on your hard drive. Usage: " + Name + " [to <directory>] | [abort] | [status]";
testClient.Assets.OnAssetReceived += new AssetManager.AssetReceivedCallback(Assets_OnAssetReceived);
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
StringBuilder sbResult = new StringBuilder();
if (args.Length == 1 && args[0] == "status")
{
return BackgroundBackupStatus;
}
else if (args.Length == 1 && args[0] == "abort")
{
if (!BackgroundBackupRunning)
return BackgroundBackupStatus;
BackupWorker.CancelAsync();
QueueWorker.CancelAsync();
Thread.Sleep(500);
// check status
return BackgroundBackupStatus;
}
else if (args.Length != 2)
{
return "Usage: " + Name + " [to <directory>] | [abort] | [status]";
}
else if (BackgroundBackupRunning)
{
return BackgroundBackupStatus;
}
QueueWorker = new BackgroundWorker();
QueueWorker.WorkerSupportsCancellation = true;
QueueWorker.DoWork += new DoWorkEventHandler(bwQueueRunner_DoWork);
QueueWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwQueueRunner_RunWorkerCompleted);
QueueWorker.RunWorkerAsync();
BackupWorker = new BackgroundWorker();
BackupWorker.WorkerSupportsCancellation = true;
BackupWorker.DoWork +=new DoWorkEventHandler(bwBackup_DoWork);
BackupWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwBackup_RunWorkerCompleted);
BackupWorker.RunWorkerAsync(args);
return "Started background operations.";
}
void bwQueueRunner_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
QueueWorker = null;
Console.WriteLine(BackgroundBackupStatus);
}
void bwQueueRunner_DoWork(object sender, DoWorkEventArgs e)
{
TextItemErrors = TextItemsTransferred = 0;
while (QueueWorker.CancellationPending == false)
{
// have any timed out?
if (CurrentDownloads.Count > 0)
{
foreach (QueuedDownloadInfo qdi in CurrentDownloads)
{
if ((qdi.WhenRequested + TimeSpan.FromSeconds(60)) < DateTime.Now)
{
Logger.DebugLog(Name + ": timeout on asset " + qdi.AssetID.ToString(), Client);
// submit request again
qdi.TransferID = Client.Assets.RequestInventoryAsset(
qdi.AssetID, qdi.ItemID, qdi.TaskID, qdi.OwnerID, qdi.Type, true);
qdi.WhenRequested = DateTime.Now;
qdi.IsRequested = true;
}
}
}
if (PendingDownloads.Count != 0)
{
// room in the server queue?
if (CurrentDownloads.Count < MAX_TRANSFERS)
{
// yes
QueuedDownloadInfo qdi = PendingDownloads.Dequeue();
qdi.WhenRequested = DateTime.Now;
qdi.IsRequested = true;
qdi.TransferID = Client.Assets.RequestInventoryAsset(
qdi.AssetID, qdi.ItemID, qdi.TaskID, qdi.OwnerID, qdi.Type, true);
lock (CurrentDownloads) CurrentDownloads.Add(qdi);
}
}
if (CurrentDownloads.Count == 0 && PendingDownloads.Count == 0 && BackupWorker == null)
{
Logger.DebugLog(Name + ": both transfer queues empty AND inventory walking thread is done", Client);
return;
}
Thread.Sleep(100);
}
}
void bwBackup_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine(Name + ": Inventory walking thread done.");
BackupWorker = null;
}
private void bwBackup_DoWork(object sender, DoWorkEventArgs e)
{
string[] args;
TextItemsFound = 0;
args = (string[]) e.Argument;
lock (CurrentDownloads) CurrentDownloads.Clear();
// FIXME:
//Client.Inventory.RequestFolderContents(Client.Inventory.Store.RootFolder.UUID, Client.Self.AgentID,
// true, true, false, InventorySortOrder.ByName);
DirectoryInfo di = new DirectoryInfo(args[1]);
// recurse on the root folder into the entire inventory
BackupFolder(Client.Inventory.Store.RootNode, di.FullName);
}
/// <summary>
/// BackupFolder - recurse through the inventory nodes sending scripts and notecards to the transfer queue
/// </summary>
/// <param name="folder">The current leaf in the inventory tree</param>
/// <param name="sPathSoFar">path so far, in the form @"c:\here" -- this needs to be "clean" for the current filesystem</param>
private void BackupFolder(InventoryNode folder, string sPathSoFar)
{
StringBuilder sbRequests = new StringBuilder();
// FIXME:
//Client.Inventory.RequestFolderContents(folder.Data.UUID, Client.Self.AgentID, true, true, false,
// InventorySortOrder.ByName);
// first scan this folder for text
foreach (InventoryNode iNode in folder.Nodes.Values)
{
if (BackupWorker.CancellationPending)
return;
if (iNode.Data is OpenMetaverse.InventoryItem)
{
InventoryItem ii = iNode.Data as InventoryItem;
if (ii.AssetType == AssetType.LSLText || ii.AssetType == AssetType.Notecard)
{
// check permissions on scripts
if (ii.AssetType == AssetType.LSLText)
{
if ((ii.Permissions.OwnerMask & PermissionMask.Modify) == PermissionMask.None)
{
// skip this one
continue;
}
}
string sExtension = (ii.AssetType == AssetType.LSLText) ? ".lsl" : ".txt";
// make the output file
string sPath = sPathSoFar + @"\" + MakeValid(ii.Name.Trim()) + sExtension;
// create the new qdi
QueuedDownloadInfo qdi = new QueuedDownloadInfo(sPath, ii.AssetUUID, iNode.Data.UUID, LLUUID.Zero,
Client.Self.AgentID, ii.AssetType);
// add it to the queue
lock (PendingDownloads)
{
TextItemsFound++;
PendingDownloads.Enqueue(qdi);
}
}
}
}
// now run any subfolders
foreach (InventoryNode i in folder.Nodes.Values)
{
if (BackupWorker.CancellationPending)
return;
else if (i.Data is OpenMetaverse.InventoryFolder)
BackupFolder(i, sPathSoFar + @"\" + MakeValid(i.Data.Name.Trim()));
}
}
private string MakeValid(string path)
{
// FIXME: We need to strip illegal characters out
return path.Trim().Replace('"', '\'');
}
private void Assets_OnAssetReceived(AssetDownload asset, Asset blah)
{
lock (CurrentDownloads)
{
// see if we have this in our transfer list
QueuedDownloadInfo r = CurrentDownloads.Find(delegate(QueuedDownloadInfo q)
{
return q.TransferID == asset.ID;
});
if (r != null && r.TransferID == asset.ID)
{
if (asset.Success)
{
// create the directory to put this in
Directory.CreateDirectory(Path.GetDirectoryName(r.FileName));
// write out the file
File.WriteAllBytes(r.FileName, asset.AssetData);
Logger.DebugLog(Name + " Wrote: " + r.FileName, Client);
TextItemsTransferred++;
}
else
{
TextItemErrors++;
Console.WriteLine("{0}: Download of asset {1} ({2}) failed with status {3}", Name, r.FileName,
r.AssetID.ToString(), asset.Status.ToString());
}
// remove the entry
CurrentDownloads.Remove(r);
}
}
}
/// <summary>
/// returns blank or "not" if false
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
private static string BoolToNot(bool b)
{
return b ? String.Empty : "not";
}
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using OpenMetaverse;
using OpenMetaverse.Packets;
namespace OpenMetaverse.TestClient
{
public class BalanceCommand: Command
{
public BalanceCommand(TestClient testClient)
{
Name = "balance";
Description = "Shows the amount of L$.";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
System.Threading.AutoResetEvent waitBalance = new System.Threading.AutoResetEvent(false);
AgentManager.BalanceCallback del = delegate(int balance) { waitBalance.Set(); };
Client.Self.OnBalanceUpdated += del;
Client.Self.RequestBalance();
String result = "Timeout waiting for balance reply";
if (waitBalance.WaitOne(10000, false))
{
result = Client.ToString() + " has L$: " + Client.Self.Balance;
}
Client.Self.OnBalanceUpdated -= del;
return result;
}
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
{
public class ChangeDirectoryCommand : Command
{
private InventoryManager Manager;
private OpenMetaverse.Inventory Inventory;
public ChangeDirectoryCommand(TestClient client)
{
Name = "cd";
Description = "Changes the current working inventory folder.";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
Manager = Client.Inventory;
Inventory = Client.Inventory.Store;
if (args.Length > 1)
return "Usage: cd [path-to-folder]";
string pathStr = "";
string[] path = null;
if (args.Length == 0)
{
path = new string[] { "" };
// cd without any arguments doesn't do anything.
}
else if (args.Length == 1)
{
pathStr = args[0];
path = pathStr.Split(new char[] { '/' });
// Use '/' as a path seperator.
}
InventoryFolder currentFolder = Client.CurrentDirectory;
if (pathStr.StartsWith("/"))
currentFolder = Inventory.RootFolder;
if (currentFolder == null) // We need this to be set to something.
return "Error: Client not logged in.";
// Traverse the path, looking for the
for (int i = 0; i < path.Length; ++i)
{
string nextName = path[i];
if (string.IsNullOrEmpty(nextName) || nextName == ".")
continue; // Ignore '.' and blanks, stay in the current directory.
if (nextName == ".." && currentFolder != Inventory.RootFolder)
{
// If we encounter .., move to the parent folder.
currentFolder = Inventory[currentFolder.ParentUUID] as InventoryFolder;
}
else
{
List<InventoryBase> currentContents = Inventory.GetContents(currentFolder);
// Try and find an InventoryBase with the corresponding name.
bool found = false;
foreach (InventoryBase item in currentContents)
{
// Allow lookup by UUID as well as name:
if (item.Name == nextName || item.UUID.ToString() == nextName)
{
found = true;
if (item is InventoryFolder)
{
currentFolder = item as InventoryFolder;
}
else
{
return item.Name + " is not a folder.";
}
}
}
if (!found)
return nextName + " not found in " + currentFolder.Name;
}
}
Client.CurrentDirectory = currentFolder;
return "Current folder: " + currentFolder.Name;
}
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.IO;
using OpenMetaverse;
namespace OpenMetaverse.TestClient
{
public class CreateNotecardCommand : Command
{
public CreateNotecardCommand(TestClient testClient)
{
Name = "createnotecard";
Description = "Creates a notecard from a local text file.";
}
void OnNoteUpdate(bool success, string status, LLUUID itemID, LLUUID assetID)
{
if (success)
Console.WriteLine("Notecard successfully uploaded, ItemID {0} AssetID {1}", itemID, assetID);
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
if(args.Length < 1)
return "Usage: createnotecard filename.txt";
string file = String.Empty;
for (int ct = 0; ct < args.Length; ct++)
file = file + args[ct] + " ";
file = file.TrimEnd();
Console.WriteLine("Filename: {0}", file);
if (!File.Exists(file))
return String.Format("Filename '{0}' does not exist", file);
System.IO.StreamReader reader = new StreamReader(file);
string body = reader.ReadToEnd();
// FIXME: Upload the notecard asset first. When that completes, call RequestCreateItem
try
{
string desc = String.Format("{0} created by OpenMetaverse TestClient {1}", file, DateTime.Now);
// create the asset
Client.Inventory.RequestCreateItem(Client.Inventory.FindFolderForType(AssetType.Notecard),
file, desc, AssetType.Notecard, LLUUID.Random(), InventoryType.Notecard, PermissionMask.All,
delegate(bool success, InventoryItem item) {
if(success) // upload the asset
Client.Inventory.RequestUploadNotecardAsset(CreateNotecardAsset(body), item.UUID, new InventoryManager.NotecardUploadedAssetCallback(OnNoteUpdate));
}
);
return "Done";
}
catch (System.Exception e)
{
Logger.Log(e.ToString(), Helpers.LogLevel.Error, Client);
return "Error creating notecard.";
}
}
/// <summary>
/// </summary>
/// <param name="body"></param>
public static byte[] CreateNotecardAsset(string body)
{
// Format the string body into Linden text
string lindenText = "Linden text version 1\n";
lindenText += "{\n";
lindenText += "LLEmbeddedItems version 1\n";
lindenText += "{\n";
lindenText += "count 0\n";
lindenText += "}\n";
lindenText += "Text length " + body.Length + "\n";
lindenText += body;
lindenText += "}\n";
// Assume this is a string, add 1 for the null terminator
byte[] stringBytes = System.Text.Encoding.UTF8.GetBytes(lindenText);
byte[] assetData = new byte[stringBytes.Length]; //+ 1];
Array.Copy(stringBytes, 0, assetData, 0, stringBytes.Length);
return assetData;
}
}
}

View File

@@ -0,0 +1,51 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using OpenMetaverse;
namespace OpenMetaverse.TestClient
{
/// <summary>
/// Inventory Example, Moves a folder to the Trash folder
/// </summary>
public class DeleteFolderCommand : Command
{
public DeleteFolderCommand(TestClient testClient)
{
Name = "deleteFolder";
Description = "Moves a folder to the Trash Folder";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
// parse the command line
string target = String.Empty;
for (int ct = 0; ct < args.Length; ct++)
target = target + args[ct] + " ";
target = target.TrimEnd();
// initialize results list
List<InventoryBase> found = new List<InventoryBase>();
try
{
// find the folder
found = Client.Inventory.LocalFind(Client.Inventory.Store.RootFolder.UUID, target.Split('/'), 0, true);
if (found.Count.Equals(1))
{
// move the folder to the trash folder
Client.Inventory.MoveFolder(found[0].UUID, Client.Inventory.FindFolderForType(AssetType.TrashFolder));
return String.Format("Moved folder {0} to Trash", found[0].Name);
}
}
catch (InvalidOutfitException ex)
{
return "Folder Not Found: (" + ex.Message + ")";
}
return string.Empty;
}
}
}

View File

@@ -0,0 +1,124 @@
using System;
using System.Text;
using System.IO;
using System.Collections.Generic;
using OpenMetaverse;
using OpenMetaverse.Imaging;
namespace OpenMetaverse.TestClient
{
public class DumpOutfitCommand : Command
{
List<LLUUID> OutfitAssets = new List<LLUUID>();
AssetManager.ImageReceivedCallback ImageReceivedHandler;
public DumpOutfitCommand(TestClient testClient)
{
Name = "dumpoutfit";
Description = "Dumps all of the textures from an avatars outfit to the hard drive. Usage: dumpoutfit [avatar-uuid]";
ImageReceivedHandler = new AssetManager.ImageReceivedCallback(Assets_OnImageReceived);
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
if (args.Length != 1)
return "Usage: dumpoutfit [avatar-uuid]";
LLUUID target;
if (!LLUUID.TryParse(args[0], out target))
return "Usage: dumpoutfit [avatar-uuid]";
lock (Client.Network.Simulators)
{
for (int i = 0; i < Client.Network.Simulators.Count; i++)
{
Avatar targetAv;
targetAv = Client.Network.Simulators[i].ObjectsAvatars.Find(
delegate(Avatar avatar)
{
return avatar.ID == target;
}
);
if (targetAv != null)
{
StringBuilder output = new StringBuilder("Downloading ");
lock (OutfitAssets) OutfitAssets.Clear();
Client.Assets.OnImageReceived += ImageReceivedHandler;
for (int j = 0; j < targetAv.Textures.FaceTextures.Length; j++)
{
LLObject.TextureEntryFace face = targetAv.Textures.FaceTextures[j];
if (face != null)
{
ImageType type = ImageType.Normal;
switch ((AppearanceManager.TextureIndex)j)
{
case AppearanceManager.TextureIndex.HeadBaked:
case AppearanceManager.TextureIndex.EyesBaked:
case AppearanceManager.TextureIndex.UpperBaked:
case AppearanceManager.TextureIndex.LowerBaked:
case AppearanceManager.TextureIndex.SkirtBaked:
type = ImageType.Baked;
break;
}
OutfitAssets.Add(face.TextureID);
Client.Assets.RequestImage(face.TextureID, type, 100000.0f, 0);
output.Append(((AppearanceManager.TextureIndex)j).ToString());
output.Append(" ");
}
}
return output.ToString();
}
}
}
return "Couldn't find avatar " + target.ToString();
}
private void Assets_OnImageReceived(ImageDownload image, AssetTexture assetTexture)
{
lock (OutfitAssets)
{
if (OutfitAssets.Contains(image.ID))
{
if (image.Success)
{
try
{
File.WriteAllBytes(image.ID.ToString() + ".jp2", image.AssetData);
Console.WriteLine("Wrote JPEG2000 image " + image.ID.ToString() + ".jp2");
ManagedImage imgData;
OpenJPEG.DecodeToImage(image.AssetData, out imgData);
byte[] tgaFile = imgData.ExportTGA();
File.WriteAllBytes(image.ID.ToString() + ".tga", tgaFile);
Console.WriteLine("Wrote TGA image " + image.ID.ToString() + ".tga");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
else
{
Console.WriteLine("Failed to download image " + image.ID.ToString());
}
OutfitAssets.Remove(image.ID);
if (OutfitAssets.Count == 0)
Client.Assets.OnImageReceived -= ImageReceivedHandler;
}
}
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.IO;
using OpenMetaverse;
using OpenMetaverse.Packets;
namespace OpenMetaverse.TestClient
{
public class ExportOutfitCommand : Command
{
public ExportOutfitCommand(TestClient testClient)
{
Name = "exportoutfit";
Description = "Exports an avatars outfit to an xml file. Usage: exportoutfit [avataruuid] outputfile.xml";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
LLUUID id;
string path;
if (args.Length == 1)
{
id = Client.Self.AgentID;
path = args[0];
}
else if (args.Length == 2)
{
if (!LLUUID.TryParse(args[0], out id))
return "Usage: exportoutfit [avataruuid] outputfile.xml";
path = args[1];
}
else
return "Usage: exportoutfit [avataruuid] outputfile.xml";
lock (Client.Appearances)
{
if (Client.Appearances.ContainsKey(id))
{
try
{
File.WriteAllText(path, Packet.ToXmlString(Client.Appearances[id]));
}
catch (Exception e)
{
return e.ToString();
}
return "Exported appearance for avatar " + id.ToString() + " to " + args[1];
}
else
{
return "Couldn't find an appearance for avatar " + id.ToString();
}
}
}
}
}

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
using OpenMetaverse.Packets;
namespace OpenMetaverse.TestClient
{
public class GiveAllCommand: Command
{
public GiveAllCommand(TestClient testClient)
{
Name = "giveAll";
Description = "Gives you all it's money.";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
if (fromAgentID == LLUUID.Zero)
return "Unable to send money to console. This command only works when IMed.";
int amount = Client.Self.Balance;
Client.Self.GiveAvatarMoney(fromAgentID, Client.Self.Balance, "TestClient.GiveAll");
return "Gave $" + amount + " to " + fromAgentID;
}
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
{
class GiveItemCommand : Command
{
private InventoryManager Manager;
private OpenMetaverse.Inventory Inventory;
public GiveItemCommand(TestClient client)
{
Name = "give";
Description = "Gives items from the current working directory to an avatar.";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
if (args.Length < 2)
{
return "Usage: give <agent uuid> <item1> [item2] [item3] [...]";
}
LLUUID dest;
if (!LLUUID.TryParse(args[0], out dest))
{
return "First argument expected agent UUID.";
}
Manager = Client.Inventory;
Inventory = Manager.Store;
string ret = "";
string nl = "\n";
for (int i = 1; i < args.Length; ++i)
{
string inventoryName = args[i];
// WARNING: Uses local copy of inventory contents, need to download them first.
List<InventoryBase> contents = Inventory.GetContents(Client.CurrentDirectory);
bool found = false;
foreach (InventoryBase b in contents) {
if (inventoryName == b.Name || inventoryName == b.UUID.ToString())
{
found = true;
if (b is InventoryItem)
{
InventoryItem item = b as InventoryItem;
Manager.GiveItem(item.UUID, item.Name, item.AssetType, dest, true);
ret += "Gave " + item.Name + nl;
}
else
{
ret += "Unable to give folder " + b.Name + nl;
}
}
}
if (!found)
ret += "No inventory item named " + inventoryName + " found." + nl;
}
return ret;
}
}
}

View File

@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.IO;
using OpenMetaverse;
using OpenMetaverse.Packets;
namespace OpenMetaverse.TestClient
{
public class ImportOutfitCommand : Command
{
//private uint SerialNum = 1;
public ImportOutfitCommand(TestClient testClient)
{
Name = "importoutfit";
Description = "Imports an appearance from an xml file. Usage: importoutfit inputfile.xml";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
if (args.Length != 1)
return "Usage: importoutfit inputfile.xml";
return "LLSD packet import is under construction";
//try
//{
// Packet packet = Packet.FromXmlString((File.ReadAllText(args[0])));
// if (packet.Type != PacketType.AvatarAppearance)
// return "Deserialized a " + packet.Type + " packet instead of an AvatarAppearance packet";
// AvatarAppearancePacket appearance = (AvatarAppearancePacket)packet;
// AgentSetAppearancePacket set = new AgentSetAppearancePacket();
// set.AgentData.AgentID = Client.Self.AgentID;
// set.AgentData.SessionID = Client.Self.SessionID;
// set.AgentData.SerialNum = SerialNum++;
// // HACK: Weak hack to calculate size
// float AV_Height_Range = 2.025506f - 1.50856f;
// float AV_Height = 1.50856f + (((float)appearance.VisualParam[25].ParamValue / 255.0f) * AV_Height_Range);
// set.AgentData.Size = new LLVector3(0.45f, 0.6f, AV_Height);
// set.ObjectData.TextureEntry = appearance.ObjectData.TextureEntry;
// set.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[appearance.VisualParam.Length];
// int i = 0;
// foreach (AvatarAppearancePacket.VisualParamBlock block in appearance.VisualParam)
// {
// set.VisualParam[i] = new AgentSetAppearancePacket.VisualParamBlock();
// set.VisualParam[i].ParamValue = block.ParamValue;
// i++;
// }
// set.WearableData = new AgentSetAppearancePacket.WearableDataBlock[0];
// Client.Network.SendPacket(set);
//}
//catch (Exception)
//{
// return "Failed to import the appearance XML file, maybe it doesn't exist or is in the wrong format?";
//}
//return "Imported " + args[0] + " and sent an AgentSetAppearance packet";
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using System.Xml;
using System.Xml.Serialization;
using OpenMetaverse;
using OpenMetaverse.Packets;
namespace OpenMetaverse.TestClient
{
public class InventoryCommand : Command
{
private Inventory Inventory;
private InventoryManager Manager;
public InventoryCommand(TestClient testClient)
{
Name = "i";
Description = "Prints out inventory.";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
Manager = Client.Inventory;
Inventory = Manager.Store;
StringBuilder result = new StringBuilder();
InventoryFolder rootFolder = Inventory.RootFolder;
PrintFolder(rootFolder, result, 0);
return result.ToString();
}
void PrintFolder(InventoryFolder f, StringBuilder result, int indent)
{
foreach (InventoryBase i in Manager.FolderContents(f.UUID, Client.Self.AgentID, true, true, InventorySortOrder.ByName, 3000))
{
result.AppendFormat("{0}{1} ({2})\n", new String(' ', indent * 2), i.Name, i.UUID);
if (i is InventoryFolder)
{
InventoryFolder folder = (InventoryFolder)i;
PrintFolder(folder, result, indent + 1);
}
}
}
}
}

View File

@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Text;
using OpenMetaverse;
namespace OpenMetaverse.TestClient.Commands.Inventory.Shell
{
public class ListContentsCommand : Command
{
private InventoryManager Manager;
private OpenMetaverse.Inventory Inventory;
public ListContentsCommand(TestClient client)
{
Name = "ls";
Description = "Lists the contents of the current working inventory folder.";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
if (args.Length > 1)
return "Usage: ls [-l]";
bool longDisplay = false;
if (args.Length > 0 && args[0] == "-l")
longDisplay = true;
Manager = Client.Inventory;
Inventory = Manager.Store;
// WARNING: Uses local copy of inventory contents, need to download them first.
List<InventoryBase> contents = Inventory.GetContents(Client.CurrentDirectory);
string displayString = "";
string nl = "\n"; // New line character
// Pretty simple, just print out the contents.
foreach (InventoryBase b in contents)
{
if (longDisplay)
{
// Generate a nicely formatted description of the item.
// It kinda looks like the output of the unix ls.
// starts with 'd' if the inventory is a folder, '-' if not.
// 9 character permissions string
// UUID of object
// Name of object
if (b is InventoryFolder)
{
InventoryFolder folder = b as InventoryFolder;
displayString += "d--------- ";
displayString += folder.UUID;
displayString += " " + folder.Name;
}
else if (b is InventoryItem)
{
InventoryItem item = b as InventoryItem;
displayString += "-";
displayString += PermMaskString(item.Permissions.OwnerMask);
displayString += PermMaskString(item.Permissions.GroupMask);
displayString += PermMaskString(item.Permissions.EveryoneMask);
displayString += " " + item.UUID;
displayString += " " + item.Name;
}
}
else
{
displayString += b.Name;
}
displayString += nl;
}
return displayString;
}
/// <summary>
/// Returns a 3-character summary of the PermissionMask
/// CMT if the mask allows copy, mod and transfer
/// -MT if it disallows copy
/// --T if it only allows transfer
/// --- if it disallows everything
/// </summary>
/// <param name="mask"></param>
/// <returns></returns>
private static string PermMaskString(PermissionMask mask) {
string str = "";
if (((uint)mask | (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
str += "C";
else
str += "-";
if (((uint)mask | (uint)PermissionMask.Modify) == (uint)PermissionMask.Modify)
str += "M";
else
str += "-";
if (((uint)mask | (uint)PermissionMask.Transfer) == (uint)PermissionMask.Transfer)
str += "T";
else
str += "-";
return str;
}
}
}

View File

@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using OpenMetaverse;
namespace OpenMetaverse.TestClient
{
public class ObjectInventoryCommand : Command
{
public ObjectInventoryCommand(TestClient testClient)
{
Name = "objectinventory";
Description = "Retrieves a listing of items inside an object (task inventory). Usage: objectinventory [objectID]";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
if (args.Length != 1)
return "Usage: objectinventory [objectID]";
uint objectLocalID;
LLUUID objectID;
if (!LLUUID.TryParse(args[0], out objectID))
return "Usage: objectinventory [objectID]";
Primitive found = Client.Network.CurrentSim.ObjectsPrimitives.Find(delegate(Primitive prim) { return prim.ID == objectID; });
if (found != null)
objectLocalID = found.LocalID;
else
return "Couldn't find prim " + objectID.ToString();
List<InventoryBase> items = Client.Inventory.GetTaskInventory(objectID, objectLocalID, 1000 * 30);
if (items != null)
{
string result = String.Empty;
for (int i = 0; i < items.Count; i++)
{
if (items[i] is InventoryFolder)
{
result += String.Format("[Folder] Name: {0}", items[i].Name) + Environment.NewLine;
}
else
{
InventoryItem item = (InventoryItem)items[i];
result += String.Format("[Item] Name: {0} Desc: {1} Type: {2}", item.Name, item.Description,
item.AssetType) + Environment.NewLine;
}
}
return result;
}
else
{
return "Failed to download task inventory for " + objectLocalID;
}
}
}
}

View File

@@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Drawing;
using OpenMetaverse;
using OpenMetaverse.Capabilities;
using OpenMetaverse.Imaging;
namespace OpenMetaverse.TestClient
{
public class UploadImageCommand : Command
{
AutoResetEvent UploadCompleteEvent = new AutoResetEvent(false);
LLUUID TextureID = LLUUID.Zero;
DateTime start;
public UploadImageCommand(TestClient testClient)
{
Name = "uploadimage";
Description = "Upload an image to your inventory. Usage: uploadimage [inventoryname] [timeout] [filename]";
}
public override string Execute(string[] args, LLUUID fromAgentID)
{
string inventoryName;
uint timeout;
string fileName;
if (args.Length != 3)
return "Usage: uploadimage [inventoryname] [timeout] [filename]";
TextureID = LLUUID.Zero;
inventoryName = args[0];
fileName = args[2];
if (!UInt32.TryParse(args[1], out timeout))
return "Usage: uploadimage [inventoryname] [timeout] [filename]";
Console.WriteLine("Loading image " + fileName);
byte[] jpeg2k = LoadImage(fileName);
if (jpeg2k == null)
return "Failed to compress image to JPEG2000";
Console.WriteLine("Finished compressing image to JPEG2000, uploading...");
start = DateTime.Now;
DoUpload(jpeg2k, inventoryName);
if (UploadCompleteEvent.WaitOne((int)timeout, false))
{
return String.Format("Texture upload {0}: {1}", (TextureID != LLUUID.Zero) ? "succeeded" : "failed",
TextureID);
}
else
{
return "Texture upload timed out";
}
}
private void DoUpload(byte[] UploadData, string FileName)
{
if (UploadData != null)
{
string name = System.IO.Path.GetFileNameWithoutExtension(FileName);
Client.Inventory.RequestCreateItemFromAsset(UploadData, name, "Uploaded with TestClient",
AssetType.Texture, InventoryType.Texture, Client.Inventory.FindFolderForType(AssetType.Texture),
delegate(CapsClient client, long bytesReceived, long bytesSent, long totalBytesToReceive, long totalBytesToSend)
{
if (bytesSent > 0)
Console.WriteLine(String.Format("Texture upload: {0} / {1}", bytesSent, totalBytesToSend));
},
delegate(bool success, string status, LLUUID itemID, LLUUID assetID)
{
Console.WriteLine(String.Format(
"RequestCreateItemFromAsset() returned: Success={0}, Status={1}, ItemID={2}, AssetID={3}",
success, status, itemID, assetID));
TextureID = assetID;
Console.WriteLine(String.Format("Upload took {0}", DateTime.Now.Subtract(start)));
UploadCompleteEvent.Set();
}
);
}
}
private byte[] LoadImage(string fileName)
{
byte[] UploadData;
string lowfilename = fileName.ToLower();
Bitmap bitmap = null;
try
{
if (lowfilename.EndsWith(".jp2") || lowfilename.EndsWith(".j2c"))
{
Image image;
ManagedImage managedImage;
// Upload JPEG2000 images untouched
UploadData = System.IO.File.ReadAllBytes(fileName);
OpenJPEG.DecodeToImage(UploadData, out managedImage, out image);
bitmap = (Bitmap)image;
}
else
{
if (lowfilename.EndsWith(".tga"))
bitmap = LoadTGAClass.LoadTGA(fileName);
else
bitmap = (Bitmap)System.Drawing.Image.FromFile(fileName);
int oldwidth = bitmap.Width;
int oldheight = bitmap.Height;
if (!IsPowerOfTwo((uint)oldwidth) || !IsPowerOfTwo((uint)oldheight))
{
Bitmap resized = new Bitmap(256, 256, bitmap.PixelFormat);
Graphics graphics = Graphics.FromImage(resized);
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.DrawImage(bitmap, 0, 0, 256, 256);
bitmap.Dispose();
bitmap = resized;
oldwidth = 256;
oldheight = 256;
}
// Handle resizing to prevent excessively large images
if (oldwidth > 1024 || oldheight > 1024)
{
int newwidth = (oldwidth > 1024) ? 1024 : oldwidth;
int newheight = (oldheight > 1024) ? 1024 : oldheight;
Bitmap resized = new Bitmap(newwidth, newheight, bitmap.PixelFormat);
Graphics graphics = Graphics.FromImage(resized);
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
graphics.InterpolationMode =
System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.DrawImage(bitmap, 0, 0, newwidth, newheight);
bitmap.Dispose();
bitmap = resized;
}
UploadData = OpenJPEG.EncodeFromImage(bitmap, false);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString() + " SL Image Upload ");
return null;
}
return UploadData;
}
private static bool IsPowerOfTwo(uint n)
{
return (n & (n - 1)) == 0 && n != 0;
}
}
}