From 7a6a7c12adf07bfca168a56bfb3a9c533400bbba Mon Sep 17 00:00:00 2001 From: Jim Radford Date: Sun, 11 May 2008 09:02:59 +0000 Subject: [PATCH] TC-35 Adds new TestClient inventory commands, cd, ls, and give Patch courtesy of CrisOmega git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1854 52acb1d6-8a22-11de-b505-999d5b087335 --- .../Inventory/ChangeDirectoryCommand.cs | 85 +++++++++++++++++ .../Commands/Inventory/GiveItemCommand.cs | 59 ++++++++++++ .../Commands/Inventory/ListContentsCommand.cs | 95 +++++++++++++++++++ .../examples/TestClient/TestClient.cs | 18 +++- .../examples/TestClient/TestClient.csproj | 3 + 5 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 libsecondlife/examples/TestClient/Commands/Inventory/ChangeDirectoryCommand.cs create mode 100644 libsecondlife/examples/TestClient/Commands/Inventory/GiveItemCommand.cs create mode 100644 libsecondlife/examples/TestClient/Commands/Inventory/ListContentsCommand.cs diff --git a/libsecondlife/examples/TestClient/Commands/Inventory/ChangeDirectoryCommand.cs b/libsecondlife/examples/TestClient/Commands/Inventory/ChangeDirectoryCommand.cs new file mode 100644 index 00000000..c54f791c --- /dev/null +++ b/libsecondlife/examples/TestClient/Commands/Inventory/ChangeDirectoryCommand.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; + +namespace libsecondlife.TestClient.Commands.Inventory.Shell +{ + public class ChangeDirectoryCommand : Command + { + private InventoryManager Manager; + private libsecondlife.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 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; + } + } +} \ No newline at end of file diff --git a/libsecondlife/examples/TestClient/Commands/Inventory/GiveItemCommand.cs b/libsecondlife/examples/TestClient/Commands/Inventory/GiveItemCommand.cs new file mode 100644 index 00000000..5c9533c2 --- /dev/null +++ b/libsecondlife/examples/TestClient/Commands/Inventory/GiveItemCommand.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace libsecondlife.TestClient.Commands.Inventory.Shell +{ + class GiveItemCommand : Command + { + private InventoryManager Manager; + private libsecondlife.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 [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 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; + } + } +} diff --git a/libsecondlife/examples/TestClient/Commands/Inventory/ListContentsCommand.cs b/libsecondlife/examples/TestClient/Commands/Inventory/ListContentsCommand.cs new file mode 100644 index 00000000..55729a3a --- /dev/null +++ b/libsecondlife/examples/TestClient/Commands/Inventory/ListContentsCommand.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Text; +using libsecondlife; + +namespace libsecondlife.TestClient.Commands.Inventory.Shell +{ + public class ListContentsCommand : Command + { + private InventoryManager Manager; + private libsecondlife.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 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; + } + + /// + /// 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 + /// + /// + /// + 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; + } + } +} diff --git a/libsecondlife/examples/TestClient/TestClient.cs b/libsecondlife/examples/TestClient/TestClient.cs index 476a76f8..c0d23016 100644 --- a/libsecondlife/examples/TestClient/TestClient.cs +++ b/libsecondlife/examples/TestClient/TestClient.cs @@ -20,6 +20,8 @@ namespace libsecondlife.TestClient public LLUUID MasterKey = LLUUID.Zero; public ClientManager ClientManager; public VoiceManager VoiceManager; + // Shell-like inventory commands need to be aware of the 'current' inventory folder. + public InventoryFolder CurrentDirectory = null; private LLQuaternion bodyRotation = LLQuaternion.Identity; private LLVector3 forward = new LLVector3(0, 0.9999f, 0); @@ -48,7 +50,7 @@ namespace libsecondlife.TestClient Settings.USE_TEXTURE_CACHE = true; Network.RegisterCallback(PacketType.AgentDataUpdate, new NetworkManager.PacketCallback(AgentDataUpdateHandler)); - + Network.OnLogin += new NetworkManager.LoginCallback(LoginHandler); Self.OnInstantMessage += new AgentManager.InstantMessageCallback(Self_OnInstantMessage); Groups.OnGroupMembers += new GroupManager.GroupMembersCallback(GroupMembersHandler); Inventory.OnObjectOffered += new InventoryManager.ObjectOfferedCallback(Inventory_OnInventoryObjectReceived); @@ -61,6 +63,20 @@ namespace libsecondlife.TestClient updateTimer.Start(); } + /// + /// Initialize everything that needs to be initialized once we're logged in. + /// + /// The status of the login + /// Error message on failure, MOTD on success. + public void LoginHandler(LoginStatus login, string message) + { + if (login == LoginStatus.Success) + { + // Start in the inventory root folder. + CurrentDirectory = Inventory.Store.RootFolder; + } + } + public void RegisterAllCommands(Assembly assembly) { foreach (Type t in assembly.GetTypes()) diff --git a/libsecondlife/examples/TestClient/TestClient.csproj b/libsecondlife/examples/TestClient/TestClient.csproj index 5ecd9c0c..c027877c 100644 --- a/libsecondlife/examples/TestClient/TestClient.csproj +++ b/libsecondlife/examples/TestClient/TestClient.csproj @@ -71,12 +71,15 @@ + + +