2 // Radegast Metaverse Client
3 // Copyright (c) 2009-2014, Radegast Development Team
4 // All rights reserved.
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
9 // * Redistributions of source code must retain the above copyright notice,
10 // this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 // * Neither the name of the application "Radegast", nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 using System.Collections.Generic;
32 using System.Threading;
34 using OpenMetaverse.StructuredData;
38 public class InitialOutfit
41 RadegastInstance Instance;
42 GridClient Client { get { return Instance.Client; }}
45 public InitialOutfit(RadegastInstance instance)
47 this.Instance = instance;
48 Store = Client.Inventory.Store;
51 public static InventoryNode FindNodeMyName(InventoryNode root, string name)
53 if (root.Data.Name == name)
58 foreach (var node in root.Nodes.Values)
60 var ret = FindNodeMyName(node, name);
70 public UUID CreateFolder(UUID parent, string name, FolderType type)
73 AutoResetEvent folderCreated = new AutoResetEvent(false);
75 EventHandler<InventoryObjectAddedEventArgs> handler = (object sender, InventoryObjectAddedEventArgs e) =>
77 if (e.Obj.Name == name && e.Obj is InventoryFolder && ((InventoryFolder)e.Obj).PreferredType == type)
81 Logger.Log("Created folder " + e.Obj.Name, Helpers.LogLevel.Info);
85 Client.Inventory.Store.InventoryObjectAdded += handler;
86 ret = Client.Inventory.CreateFolder(parent, name, type);
87 bool success = folderCreated.WaitOne(20 * 1000, false);
88 Client.Inventory.Store.InventoryObjectAdded -= handler;
100 List<InventoryBase> FetchFolder(InventoryFolder folder)
102 List<InventoryBase> ret = new List<InventoryBase>();
104 AutoResetEvent folderFetched = new AutoResetEvent(false);
106 EventHandler<FolderUpdatedEventArgs> handler = (object sender, FolderUpdatedEventArgs e) =>
108 if (e.FolderID == folder.UUID)
110 ret = Store.GetContents(e.FolderID);
115 Client.Inventory.FolderUpdated += handler;
116 Client.Inventory.RequestFolderContents(folder.UUID, folder.OwnerID, true, true, InventorySortOrder.ByName);
117 bool success = folderFetched.WaitOne(20 * 1000, false);
118 Client.Inventory.FolderUpdated -= handler;
122 public void CheckFolders()
124 // Check if we have clothing folder
125 var clothingID = Client.Inventory.FindFolderForType(FolderType.Clothing);
126 if (clothingID == Store.RootFolder.UUID)
128 clothingID = CreateFolder(Store.RootFolder.UUID, "Clothing", FolderType.Clothing);
131 // Check if we have trash folder
132 var trashID = Client.Inventory.FindFolderForType(FolderType.Trash);
133 if (trashID == Store.RootFolder.UUID)
135 trashID = CreateFolder(Store.RootFolder.UUID, "Trash", FolderType.Trash);
139 public UUID CopyFolder(InventoryFolder folder, UUID destination)
141 UUID newFolderID = CreateFolder(destination, folder.Name, folder.PreferredType);
142 //var newFolder = (InventoryFolder)Store[newFolderID];
144 var items = FetchFolder(folder);
145 foreach (var item in items)
147 if (item is InventoryItem)
149 AutoResetEvent itemCopied = new AutoResetEvent(false);
150 Client.Inventory.RequestCopyItem(item.UUID, newFolderID, item.Name, item.OwnerID, (newItem) =>
154 if (itemCopied.WaitOne(20 * 1000, false))
156 Logger.Log("Copied item " + item.Name, Helpers.LogLevel.Info);
160 Logger.Log("Failed to copy item " + item.Name, Helpers.LogLevel.Warning);
163 else if (item is InventoryFolder)
165 CopyFolder((InventoryFolder)item, newFolderID);
172 public void SetInitialOutfit(string outfit)
174 Thread t = new Thread(() => PerformInit(outfit));
176 t.IsBackground = true;
177 t.Name = "Initial outfit thread";
181 void PerformInit(string initialOutfitName)
183 Logger.Log("Starting intial outfit thread (first login)", Helpers.LogLevel.Debug);
184 var outfitFolder = FindNodeMyName(Store.LibraryRootNode, initialOutfitName);
186 if (outfitFolder == null)
193 UUID newClothingFolder = CopyFolder((InventoryFolder)outfitFolder.Data, Client.Inventory.FindFolderForType(AssetType.Clothing));
195 List<InventoryItem> newOutfit = new List<InventoryItem>();
196 foreach (var item in Store.GetContents(newClothingFolder))
198 if (item is InventoryWearable || item is InventoryAttachment || item is InventoryObject)
200 newOutfit.Add((InventoryItem)item);
204 Instance.COF.ReplaceOutfit(newOutfit);
205 Logger.Log("Intial outfit thread (first login) exiting", Helpers.LogLevel.Debug);