corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Threading;
5 using OpenMetaverse;
6 using OpenMetaverse.StructuredData;
7 using OpenMetaverse.Assets;
8  
9 namespace OpenMetaverse.TestClient
10 {
11 public class ExportCommand : Command
12 {
13 List<UUID> Textures = new List<UUID>();
14 AutoResetEvent GotPermissionsEvent = new AutoResetEvent(false);
15 Primitive.ObjectProperties Properties;
16 bool GotPermissions = false;
17 UUID SelectedObject = UUID.Zero;
18  
19 Dictionary<UUID, Primitive> PrimsWaiting = new Dictionary<UUID, Primitive>();
20 AutoResetEvent AllPropertiesReceived = new AutoResetEvent(false);
21  
22 public ExportCommand(TestClient testClient)
23 {
24 testClient.Objects.ObjectPropertiesFamily += new EventHandler<ObjectPropertiesFamilyEventArgs>(Objects_OnObjectPropertiesFamily);
25  
26 testClient.Objects.ObjectProperties += new EventHandler<ObjectPropertiesEventArgs>(Objects_OnObjectProperties);
27 testClient.Avatars.ViewerEffectPointAt += new EventHandler<ViewerEffectPointAtEventArgs>(Avatars_ViewerEffectPointAt);
28  
29 Name = "export";
30 Description = "Exports an object to an xml file. Usage: export uuid outputfile.xml";
31 Category = CommandCategory.Objects;
32 }
33  
34 void Avatars_ViewerEffectPointAt(object sender, ViewerEffectPointAtEventArgs e)
35 {
36 if (e.SourceID == Client.MasterKey)
37 {
38 //Client.DebugLog("Master is now selecting " + targetID.ToString());
39 SelectedObject = e.TargetID;
40 }
41 }
42  
43 public override string Execute(string[] args, UUID fromAgentID)
44 {
45 if (args.Length != 2 && !(args.Length == 1 && SelectedObject != UUID.Zero))
46 return "Usage: export uuid outputfile.xml";
47  
48 UUID id;
49 uint localid;
50 string file;
51  
52 if (args.Length == 2)
53 {
54 file = args[1];
55 if (!UUID.TryParse(args[0], out id))
56 return "Usage: export uuid outputfile.xml";
57 }
58 else
59 {
60 file = args[0];
61 id = SelectedObject;
62 }
63  
64 Primitive exportPrim;
65  
66 exportPrim = Client.Network.CurrentSim.ObjectsPrimitives.Find(
67 delegate(Primitive prim) { return prim.ID == id; }
68 );
69  
70 if (exportPrim != null)
71 {
72 if (exportPrim.ParentID != 0)
73 localid = exportPrim.ParentID;
74 else
75 localid = exportPrim.LocalID;
76  
77 // Check for export permission first
78 Client.Objects.RequestObjectPropertiesFamily(Client.Network.CurrentSim, id);
79 GotPermissionsEvent.WaitOne(1000 * 10, false);
80  
81 if (!GotPermissions)
82 {
83 return "Couldn't fetch permissions for the requested object, try again";
84 }
85 else
86 {
87 GotPermissions = false;
88 if (Properties.OwnerID != Client.Self.AgentID &&
89 Properties.OwnerID != Client.MasterKey &&
90 Client.Self.AgentID != Client.Self.AgentID)
91 {
92 return "That object is owned by " + Properties.OwnerID + ", we don't have permission " +
93 "to export it";
94 }
95 }
96  
97 List<Primitive> prims = Client.Network.CurrentSim.ObjectsPrimitives.FindAll(
98 delegate(Primitive prim)
99 {
100 return (prim.LocalID == localid || prim.ParentID == localid);
101 }
102 );
103  
104 bool complete = RequestObjectProperties(prims, 250);
105  
106 if (!complete)
107 {
108 Logger.Log("Warning: Unable to retrieve full properties for:", Helpers.LogLevel.Warning, Client);
109 foreach (UUID uuid in PrimsWaiting.Keys)
110 Logger.Log(uuid.ToString(), Helpers.LogLevel.Warning, Client);
111 }
112  
113 string output = OSDParser.SerializeLLSDXmlString(Helpers.PrimListToOSD(prims));
114 try { File.WriteAllText(file, output); }
115 catch (Exception e) { return e.Message; }
116  
117 Logger.Log("Exported " + prims.Count + " prims to " + file, Helpers.LogLevel.Info, Client);
118  
119 // Create a list of all of the textures to download
120 List<ImageRequest> textureRequests = new List<ImageRequest>();
121  
122 lock (Textures)
123 {
124 for (int i = 0; i < prims.Count; i++)
125 {
126 Primitive prim = prims[i];
127  
128 if (prim.Textures.DefaultTexture.TextureID != Primitive.TextureEntry.WHITE_TEXTURE &&
129 !Textures.Contains(prim.Textures.DefaultTexture.TextureID))
130 {
131 Textures.Add(prim.Textures.DefaultTexture.TextureID);
132 }
133  
134 for (int j = 0; j < prim.Textures.FaceTextures.Length; j++)
135 {
136 if (prim.Textures.FaceTextures[j] != null &&
137 prim.Textures.FaceTextures[j].TextureID != Primitive.TextureEntry.WHITE_TEXTURE &&
138 !Textures.Contains(prim.Textures.FaceTextures[j].TextureID))
139 {
140 Textures.Add(prim.Textures.FaceTextures[j].TextureID);
141 }
142 }
143  
144 if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero && !Textures.Contains(prim.Sculpt.SculptTexture))
145 {
146 Textures.Add(prim.Sculpt.SculptTexture);
147 }
148 }
149  
150 // Create a request list from all of the images
151 for (int i = 0; i < Textures.Count; i++)
152 textureRequests.Add(new ImageRequest(Textures[i], ImageType.Normal, 1013000.0f, 0));
153 }
154  
155 // Download all of the textures in the export list
156 foreach (ImageRequest request in textureRequests)
157 {
158 Client.Assets.RequestImage(request.ImageID, request.Type, Assets_OnImageReceived);
159 }
160  
161 return "XML exported, began downloading " + Textures.Count + " textures";
162 }
163 else
164 {
165 return "Couldn't find UUID " + id.ToString() + " in the " +
166 Client.Network.CurrentSim.ObjectsPrimitives.Count +
167 "objects currently indexed in the current simulator";
168 }
169 }
170  
171 private bool RequestObjectProperties(List<Primitive> objects, int msPerRequest)
172 {
173 // Create an array of the local IDs of all the prims we are requesting properties for
174 uint[] localids = new uint[objects.Count];
175  
176 lock (PrimsWaiting)
177 {
178 PrimsWaiting.Clear();
179  
180 for (int i = 0; i < objects.Count; ++i)
181 {
182 localids[i] = objects[i].LocalID;
183 PrimsWaiting.Add(objects[i].ID, objects[i]);
184 }
185 }
186  
187 Client.Objects.SelectObjects(Client.Network.CurrentSim, localids);
188  
189 return AllPropertiesReceived.WaitOne(2000 + msPerRequest * objects.Count, false);
190 }
191  
192 private void Assets_OnImageReceived(TextureRequestState state, AssetTexture asset)
193 {
194  
195 if (state == TextureRequestState.Finished && Textures.Contains(asset.AssetID))
196 {
197 lock (Textures)
198 Textures.Remove(asset.AssetID);
199  
200 if (state == TextureRequestState.Finished)
201 {
202 try { File.WriteAllBytes(asset.AssetID + ".jp2", asset.AssetData); }
203 catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client); }
204  
205 if (asset.Decode())
206 {
207 try { File.WriteAllBytes(asset.AssetID + ".tga", asset.Image.ExportTGA()); }
208 catch (Exception ex) { Logger.Log(ex.Message, Helpers.LogLevel.Error, Client); }
209 }
210 else
211 {
212 Logger.Log("Failed to decode image " + asset.AssetID, Helpers.LogLevel.Error, Client);
213 }
214  
215 Logger.Log("Finished downloading image " + asset.AssetID, Helpers.LogLevel.Info, Client);
216 }
217 else
218 {
219 Logger.Log("Failed to download image " + asset.AssetID + ":" + state, Helpers.LogLevel.Warning, Client);
220 }
221 }
222 }
223  
224 void Objects_OnObjectPropertiesFamily(object sender, ObjectPropertiesFamilyEventArgs e)
225 {
226 Properties = new Primitive.ObjectProperties();
227 Properties.SetFamilyProperties(e.Properties);
228 GotPermissions = true;
229 GotPermissionsEvent.Set();
230 }
231  
232 void Objects_OnObjectProperties(object sender, ObjectPropertiesEventArgs e)
233 {
234 lock (PrimsWaiting)
235 {
236 PrimsWaiting.Remove(e.Properties.ObjectID);
237  
238 if (PrimsWaiting.Count == 0)
239 AllPropertiesReceived.Set();
240 }
241 }
242 }
243 }