aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs')
-rw-r--r--OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs550
1 files changed, 0 insertions, 550 deletions
diff --git a/OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs b/OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs
deleted file mode 100644
index 923b06c..0000000
--- a/OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs
+++ /dev/null
@@ -1,550 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using System.Threading;
33using log4net;
34using Nwc.XmlRpc;
35using OpenMetaverse;
36using OpenSim.Framework;
37using OpenSim.Framework.Console;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Servers;
40using OpenSim.Framework.Servers.HttpServer;
41using OpenSim.Grid.Framework;
42
43
44namespace OpenSim.Grid.UserServer.Modules
45{
46 public class AvatarCreationModule
47 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49
50 private UserDataBaseService m_userDataBaseService;
51 // private BaseHttpServer m_httpServer;
52 // TODO: unused: private UserConfig m_config;
53
54 private string m_inventoryServerUrl;
55 private IInterServiceInventoryServices m_inventoryService;
56
57 public AvatarCreationModule(UserDataBaseService userDataBaseService, UserConfig config, IInterServiceInventoryServices inventoryService)
58 {
59 // TODO: unused: m_config = config;
60 m_userDataBaseService = userDataBaseService;
61 m_inventoryService = inventoryService;
62 m_inventoryServerUrl = config.InventoryUrl.OriginalString;
63 }
64
65 public void Initialise(IGridServiceCore core)
66 {
67 CommandConsole console;
68 if (core.TryGet<CommandConsole>(out console))
69 {
70 console.Commands.AddCommand("userserver", false, "clone avatar",
71 "clone avatar <TemplateAvatarFirstName> <TemplateAvatarLastName> <TargetAvatarFirstName> <TargetAvatarLastName>",
72 "Clone the template avatar's inventory into a target avatar", RunCommand);
73 }
74 }
75
76 public void PostInitialise()
77 {
78
79 }
80
81 public void RegisterHandlers(BaseHttpServer httpServer)
82 {
83 }
84
85 public void RunCommand(string module, string[] cmd)
86 {
87 if ((cmd.Length == 6) && (cmd[0] == "clone") && (cmd[1] == "avatar"))
88 {
89 try
90 {
91 string tFirst = cmd[2];
92 string tLast = cmd[3];
93
94 string nFirst = cmd[4];
95 string nLast = cmd[5];
96
97 UserProfileData templateAvatar = m_userDataBaseService.GetUserProfile(tFirst, tLast);
98 UserProfileData newAvatar = m_userDataBaseService.GetUserProfile(nFirst, nLast);
99
100 if (templateAvatar == null)
101 {
102 m_log.ErrorFormat("[AvatarAppearance] Clone Avatar: Could not find template avatar {0} , {1}", tFirst, tLast);
103 return;
104 }
105
106 if (newAvatar == null)
107 {
108 m_log.ErrorFormat("[AvatarAppearance] Clone Avatar: Could not find target avatar {0} , {1}", nFirst, nLast);
109 return;
110 }
111 Guid avatar = newAvatar.ID.Guid;
112 Guid template = templateAvatar.ID.Guid;
113 CloneAvatar(avatar, template, true, true);
114
115 }
116 catch (Exception e)
117 {
118 m_log.Error("Error: " + e.ToString());
119 }
120 }
121 }
122 #region Avatar Appearance Creation
123
124 public bool CloneAvatar(Guid avatarID, Guid templateID, bool modifyPermissions, bool removeTargetsClothes)
125 {
126 m_log.InfoFormat("[AvatarAppearance] Starting to clone avatar {0} inventory to avatar {1}", templateID.ToString(), avatarID.ToString());
127 // TODO: unused: Guid bodyFolder = Guid.Empty;
128 // TODO: unused: Guid clothesFolder = Guid.Empty;
129 bool success = false;
130
131 UUID avID = new UUID(avatarID);
132 List<InventoryFolderBase> avatarInventory = m_inventoryService.GetInventorySkeleton(avID);
133 if ((avatarInventory == null) || (avatarInventory.Count == 0))
134 {
135 m_log.InfoFormat("[AvatarAppearance] No inventory found for user {0} , so creating it", avID.ToString());
136 m_inventoryService.CreateNewUserInventory(avID);
137 Thread.Sleep(5000);
138 avatarInventory = m_inventoryService.GetInventorySkeleton(avID);
139 }
140
141 if ((avatarInventory != null) && (avatarInventory.Count > 0))
142 {
143 UUID tempOwnID = new UUID(templateID);
144 AvatarAppearance appearance = m_userDataBaseService.GetUserAppearance(tempOwnID);
145
146 if (removeTargetsClothes)
147 {
148 //remove clothes and attachments from target avatar so that the end result isn't a merger of its existing clothes
149 // and the clothes from the template avatar.
150 RemoveClothesAndAttachments(avID);
151 }
152
153 List<InventoryFolderBase> templateInventory = m_inventoryService.GetInventorySkeleton(tempOwnID);
154 if ((templateInventory != null) && (templateInventory.Count != 0))
155 {
156 for (int i = 0; i < templateInventory.Count; i++)
157 {
158 if (templateInventory[i].ParentID == UUID.Zero)
159 {
160 success = CloneFolder(avatarInventory, avID, UUID.Zero, appearance, templateInventory[i], templateInventory, modifyPermissions);
161 break;
162 }
163 }
164 }
165 else
166 {
167 m_log.InfoFormat("[AvatarAppearance] Failed to find the template owner's {0} inventory", tempOwnID);
168 }
169 }
170 m_log.InfoFormat("[AvatarAppearance] finished cloning avatar with result: {0}", success);
171 return success;
172 }
173
174 private bool CloneFolder(List<InventoryFolderBase> avatarInventory, UUID avID, UUID parentFolder, AvatarAppearance appearance, InventoryFolderBase templateFolder, List<InventoryFolderBase> templateFolders, bool modifyPermissions)
175 {
176 bool success = false;
177 UUID templateFolderId = templateFolder.ID;
178 if (templateFolderId != UUID.Zero)
179 {
180 InventoryFolderBase toFolder = FindFolder(templateFolder.Name, parentFolder.Guid, avatarInventory);
181 if (toFolder == null)
182 {
183 //create new folder
184 toFolder = new InventoryFolderBase();
185 toFolder.ID = UUID.Random();
186 toFolder.Name = templateFolder.Name;
187 toFolder.Owner = avID;
188 toFolder.Type = templateFolder.Type;
189 toFolder.Version = 1;
190 toFolder.ParentID = parentFolder;
191 if (!SynchronousRestObjectRequester.MakeRequest<InventoryFolderBase, bool>(
192 "POST", m_inventoryServerUrl + "CreateFolder/", toFolder))
193 {
194 m_log.InfoFormat("[AvatarApperance] Couldn't make new folder {0} in users inventory", toFolder.Name);
195 return false;
196 }
197 else
198 {
199 // m_log.InfoFormat("made new folder {0} in users inventory", toFolder.Name);
200 }
201 }
202
203 List<InventoryItemBase> templateItems = SynchronousRestObjectRequester.MakeRequest<Guid, List<InventoryItemBase>>(
204 "POST", m_inventoryServerUrl + "GetItems/", templateFolderId.Guid);
205 if ((templateItems != null) && (templateItems.Count > 0))
206 {
207 List<ClothesAttachment> wornClothes = new List<ClothesAttachment>();
208 List<ClothesAttachment> attachedItems = new List<ClothesAttachment>();
209
210 foreach (InventoryItemBase item in templateItems)
211 {
212
213 UUID clonedItemId = CloneInventoryItem(avID, toFolder.ID, item, modifyPermissions);
214 if (clonedItemId != UUID.Zero)
215 {
216 int appearanceType = ItemIsPartOfAppearance(item, appearance);
217 if (appearanceType >= 0)
218 {
219 // UpdateAvatarAppearance(avID, appearanceType, clonedItemId, item.AssetID);
220 wornClothes.Add(new ClothesAttachment(appearanceType, clonedItemId, item.AssetID));
221 }
222
223 if (appearance != null)
224 {
225 int attachment = appearance.GetAttachpoint(item.ID);
226 if (attachment > 0)
227 {
228 //UpdateAvatarAttachment(avID, attachment, clonedItemId, item.AssetID);
229 attachedItems.Add(new ClothesAttachment(attachment, clonedItemId, item.AssetID));
230 }
231 }
232 success = true;
233 }
234 }
235
236 if ((wornClothes.Count > 0) || (attachedItems.Count > 0))
237 {
238 //Update the worn clothes and attachments
239 AvatarAppearance targetAppearance = GetAppearance(avID);
240 if (targetAppearance != null)
241 {
242 foreach (ClothesAttachment wornItem in wornClothes)
243 {
244 targetAppearance.Wearables[wornItem.Type].AssetID = wornItem.AssetID;
245 targetAppearance.Wearables[wornItem.Type].ItemID = wornItem.ItemID;
246 }
247
248 foreach (ClothesAttachment wornItem in attachedItems)
249 {
250 targetAppearance.SetAttachment(wornItem.Type, wornItem.ItemID, wornItem.AssetID);
251 }
252
253 m_userDataBaseService.UpdateUserAppearance(avID, targetAppearance);
254 wornClothes.Clear();
255 attachedItems.Clear();
256 }
257 }
258 }
259 else if ((templateItems != null) && (templateItems.Count == 0))
260 {
261 // m_log.Info("[AvatarAppearance]Folder being cloned was empty");
262 success = true;
263 }
264
265 List<InventoryFolderBase> subFolders = FindSubFolders(templateFolder.ID.Guid, templateFolders);
266 foreach (InventoryFolderBase subFolder in subFolders)
267 {
268 if (subFolder.Name.ToLower() != "trash")
269 {
270 success = CloneFolder(avatarInventory, avID, toFolder.ID, appearance, subFolder, templateFolders, modifyPermissions);
271 }
272 }
273 }
274 else
275 {
276 m_log.Info("[AvatarAppearance] Failed to find the template folder");
277 }
278 return success;
279 }
280
281 private UUID CloneInventoryItem(UUID avatarID, UUID avatarFolder, InventoryItemBase item, bool modifyPerms)
282 {
283 if (avatarFolder != UUID.Zero)
284 {
285 InventoryItemBase clonedItem = new InventoryItemBase();
286 clonedItem.Owner = avatarID;
287 clonedItem.AssetID = item.AssetID;
288 clonedItem.AssetType = item.AssetType;
289 clonedItem.BasePermissions = item.BasePermissions;
290 clonedItem.CreationDate = item.CreationDate;
291 clonedItem.CreatorId = item.CreatorId;
292 clonedItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
293 clonedItem.CurrentPermissions = item.CurrentPermissions;
294 clonedItem.Description = item.Description;
295 clonedItem.EveryOnePermissions = item.EveryOnePermissions;
296 clonedItem.Flags = item.Flags;
297 clonedItem.Folder = avatarFolder;
298 clonedItem.GroupID = item.GroupID;
299 clonedItem.GroupOwned = item.GroupOwned;
300 clonedItem.GroupPermissions = item.GroupPermissions;
301 clonedItem.ID = UUID.Random();
302 clonedItem.InvType = item.InvType;
303 clonedItem.Name = item.Name;
304 clonedItem.NextPermissions = item.NextPermissions;
305 clonedItem.SalePrice = item.SalePrice;
306 clonedItem.SaleType = item.SaleType;
307
308 if (modifyPerms)
309 {
310 ModifyPermissions(ref clonedItem);
311 }
312
313 SynchronousRestObjectRequester.MakeRequest<InventoryItemBase, bool>(
314 "POST", m_inventoryServerUrl + "AddNewItem/", clonedItem);
315
316 return clonedItem.ID;
317 }
318
319 return UUID.Zero;
320 }
321
322 // TODO: unused
323 // private void UpdateAvatarAppearance(UUID avatarID, int wearableType, UUID itemID, UUID assetID)
324 // {
325 // AvatarAppearance appearance = GetAppearance(avatarID);
326 // appearance.Wearables[wearableType].AssetID = assetID;
327 // appearance.Wearables[wearableType].ItemID = itemID;
328 // m_userDataBaseService.UpdateUserAppearance(avatarID, appearance);
329 // }
330
331 // TODO: unused
332 // private void UpdateAvatarAttachment(UUID avatarID, int attachmentPoint, UUID itemID, UUID assetID)
333 // {
334 // AvatarAppearance appearance = GetAppearance(avatarID);
335 // appearance.SetAttachment(attachmentPoint, itemID, assetID);
336 // m_userDataBaseService.UpdateUserAppearance(avatarID, appearance);
337 // }
338
339 private void RemoveClothesAndAttachments(UUID avatarID)
340 {
341 AvatarAppearance appearance = GetAppearance(avatarID);
342
343 appearance.ClearWearables();
344 appearance.ClearAttachments();
345 m_userDataBaseService.UpdateUserAppearance(avatarID, appearance);
346
347 }
348
349 private AvatarAppearance GetAppearance(UUID avatarID)
350 {
351 AvatarAppearance appearance = m_userDataBaseService.GetUserAppearance(avatarID);
352 if (appearance == null)
353 {
354 appearance = CreateDefaultAppearance(avatarID);
355 }
356 return appearance;
357 }
358
359 // TODO: unused
360 // private UUID FindFolderID(string name, List<InventoryFolderBase> folders)
361 // {
362 // foreach (InventoryFolderBase folder in folders)
363 // {
364 // if (folder.Name == name)
365 // {
366 // return folder.ID;
367 // }
368 // }
369 // return UUID.Zero;
370 // }
371
372 // TODO: unused
373 // private InventoryFolderBase FindFolder(string name, List<InventoryFolderBase> folders)
374 // {
375 // foreach (InventoryFolderBase folder in folders)
376 // {
377 // if (folder.Name == name)
378 // {
379 // return folder;
380 // }
381 // }
382 // return null;
383 // }
384
385 private InventoryFolderBase FindFolder(string name, Guid parentFolderID, List<InventoryFolderBase> folders)
386 {
387 foreach (InventoryFolderBase folder in folders)
388 {
389 if ((folder.Name == name) && (folder.ParentID.Guid == parentFolderID))
390 {
391 return folder;
392 }
393 }
394 return null;
395 }
396
397 // TODO: unused
398 // private InventoryItemBase GetItem(string itemName, List<InventoryItemBase> items)
399 // {
400 // foreach (InventoryItemBase item in items)
401 // {
402 // if (item.Name.ToLower() == itemName.ToLower())
403 // {
404 // return item;
405 // }
406 // }
407 // return null;
408 // }
409
410 private List<InventoryFolderBase> FindSubFolders(Guid parentFolderID, List<InventoryFolderBase> folders)
411 {
412 List<InventoryFolderBase> subFolders = new List<InventoryFolderBase>();
413 foreach (InventoryFolderBase folder in folders)
414 {
415 if (folder.ParentID.Guid == parentFolderID)
416 {
417 subFolders.Add(folder);
418 }
419 }
420 return subFolders;
421 }
422
423 protected virtual void ModifyPermissions(ref InventoryItemBase item)
424 {
425 // Propagate Permissions
426 item.BasePermissions = item.BasePermissions & item.NextPermissions;
427 item.CurrentPermissions = item.BasePermissions;
428 item.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions;
429 item.GroupPermissions = item.GroupPermissions & item.NextPermissions;
430
431 }
432
433 private AvatarAppearance CreateDefaultAppearance(UUID avatarId)
434 {
435 AvatarAppearance appearance = null;
436 AvatarWearable[] wearables;
437 byte[] visualParams;
438 GetDefaultAvatarAppearance(out wearables, out visualParams);
439 appearance = new AvatarAppearance(avatarId, wearables, visualParams);
440
441 return appearance;
442 }
443
444 private static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams)
445 {
446 visualParams = GetDefaultVisualParams();
447 wearables = AvatarWearable.DefaultWearables;
448 }
449
450 private static byte[] GetDefaultVisualParams()
451 {
452 byte[] visualParams;
453 visualParams = new byte[218];
454 for (int i = 0; i < 218; i++)
455 {
456 visualParams[i] = 100;
457 }
458 return visualParams;
459 }
460
461 private int ItemIsPartOfAppearance(InventoryItemBase item, AvatarAppearance appearance)
462 {
463 if (appearance != null)
464 {
465 if (appearance.BodyItem == item.ID)
466 return (int)WearableType.Shape;
467
468 if (appearance.EyesItem == item.ID)
469 return (int)WearableType.Eyes;
470
471 if (appearance.GlovesItem == item.ID)
472 return (int)WearableType.Gloves;
473
474 if (appearance.HairItem == item.ID)
475 return (int)WearableType.Hair;
476
477 if (appearance.JacketItem == item.ID)
478 return (int)WearableType.Jacket;
479
480 if (appearance.PantsItem == item.ID)
481 return (int)WearableType.Pants;
482
483 if (appearance.ShirtItem == item.ID)
484 return (int)WearableType.Shirt;
485
486 if (appearance.ShoesItem == item.ID)
487 return (int)WearableType.Shoes;
488
489 if (appearance.SkinItem == item.ID)
490 return (int)WearableType.Skin;
491
492 if (appearance.SkirtItem == item.ID)
493 return (int)WearableType.Skirt;
494
495 if (appearance.SocksItem == item.ID)
496 return (int)WearableType.Socks;
497
498 if (appearance.UnderPantsItem == item.ID)
499 return (int)WearableType.Underpants;
500
501 if (appearance.UnderShirtItem == item.ID)
502 return (int)WearableType.Undershirt;
503 }
504 return -1;
505 }
506 #endregion
507
508 public enum PermissionMask
509 {
510 None = 0,
511 Transfer = 8192,
512 Modify = 16384,
513 Copy = 32768,
514 Move = 524288,
515 Damage = 1048576,
516 All = 2147483647,
517 }
518
519 public enum WearableType
520 {
521 Shape = 0,
522 Skin = 1,
523 Hair = 2,
524 Eyes = 3,
525 Shirt = 4,
526 Pants = 5,
527 Shoes = 6,
528 Socks = 7,
529 Jacket = 8,
530 Gloves = 9,
531 Undershirt = 10,
532 Underpants = 11,
533 Skirt = 12,
534 }
535
536 public class ClothesAttachment
537 {
538 public int Type;
539 public UUID ItemID;
540 public UUID AssetID;
541
542 public ClothesAttachment(int type, UUID itemID, UUID assetID)
543 {
544 Type = type;
545 ItemID = itemID;
546 AssetID = assetID;
547 }
548 }
549 }
550} \ No newline at end of file