aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Grid/UserServer.Modules
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Grid/UserServer.Modules')
-rw-r--r--OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs499
1 files changed, 499 insertions, 0 deletions
diff --git a/OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs b/OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs
new file mode 100644
index 0000000..5e6bc85
--- /dev/null
+++ b/OpenSim/Grid/UserServer.Modules/AvatarCreationModule.cs
@@ -0,0 +1,499 @@
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 OpenSim 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 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 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 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);
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)
125 {
126 m_log.InfoFormat("[AvatarAppearance] Starting to create avatar's appearance for user {0}", avatarID.ToString());
127 Guid bodyFolder = Guid.Empty;
128 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 List<InventoryFolderBase> templateInventory = m_inventoryService.GetInventorySkeleton(tempOwnID);
147 if ((templateInventory != null) && (templateInventory.Count != 0))
148 {
149 for (int i = 0; i < templateInventory.Count; i++)
150 {
151 if (templateInventory[i].ParentID == UUID.Zero)
152 {
153 success = CloneFolder(avatarInventory, avID, UUID.Zero, appearance, templateInventory[i], templateInventory);
154 break;
155 }
156 }
157 }
158 else
159 {
160 m_log.InfoFormat("[AvatarAppearance] Failed to find the template owner's {0} inventory", tempOwnID);
161 }
162 }
163 m_log.InfoFormat("[AvatarAppearance] finished cloning avatar with result: {0}", success);
164 return success;
165 }
166
167 private void UpdateAvatarAppearance(UUID avatarID, int wearableType, UUID itemID, UUID assetID)
168 {
169 AvatarAppearance appearance = m_userDataBaseService.GetUserAppearance(avatarID);
170 if (appearance == null)
171 {
172 appearance = CreateDefaultAppearance(avatarID);
173 }
174
175 appearance.Wearables[wearableType].AssetID = assetID;
176 appearance.Wearables[wearableType].ItemID = itemID;
177
178 m_userDataBaseService.UpdateUserAppearance(avatarID, appearance);
179
180 }
181
182 private void UpdateAvatarAttachment(UUID avatarID, int attachmentPoint, UUID itemID, UUID assetID)
183 {
184 AvatarAppearance appearance = m_userDataBaseService.GetUserAppearance(avatarID);
185 if (appearance == null)
186 {
187 appearance = CreateDefaultAppearance(avatarID);
188 }
189
190 appearance.SetAttachment(attachmentPoint, itemID, assetID);
191
192 m_userDataBaseService.UpdateUserAppearance(avatarID, appearance);
193
194 }
195
196 private UUID FindFolderID(string name, List<InventoryFolderBase> folders)
197 {
198 foreach (InventoryFolderBase folder in folders)
199 {
200 if (folder.Name == name)
201 {
202 return folder.ID;
203 }
204 }
205 return UUID.Zero;
206 }
207
208 private InventoryFolderBase FindFolder(string name, List<InventoryFolderBase> folders)
209 {
210 foreach (InventoryFolderBase folder in folders)
211 {
212 if (folder.Name == name)
213 {
214 return folder;
215 }
216 }
217 return null;
218 }
219
220 private InventoryFolderBase FindFolder(string name, Guid parentFolderID, List<InventoryFolderBase> folders)
221 {
222 foreach (InventoryFolderBase folder in folders)
223 {
224 if ((folder.Name == name) && (folder.ParentID.Guid == parentFolderID))
225 {
226 return folder;
227 }
228 }
229 return null;
230 }
231
232 private InventoryItemBase GetItem(string itemName, List<InventoryItemBase> items)
233 {
234 foreach (InventoryItemBase item in items)
235 {
236 if (item.Name.ToLower() == itemName.ToLower())
237 {
238 return item;
239 }
240 }
241 return null;
242 }
243
244 private List<InventoryFolderBase> FindSubFolders(Guid parentFolderID, List<InventoryFolderBase> folders)
245 {
246 List<InventoryFolderBase> subFolders = new List<InventoryFolderBase>();
247 foreach (InventoryFolderBase folder in folders)
248 {
249 if (folder.ParentID.Guid == parentFolderID)
250 {
251 subFolders.Add(folder);
252 }
253 }
254 return subFolders;
255 }
256
257
258 private UUID CloneInventoryItem(UUID avatarID, UUID avatarFolder, InventoryItemBase item, bool modifyPerms)
259 {
260 if (avatarFolder != UUID.Zero)
261 {
262 InventoryItemBase clonedItem = new InventoryItemBase();
263 clonedItem.Owner = avatarID;
264 clonedItem.AssetID = item.AssetID;
265 clonedItem.AssetType = item.AssetType;
266 clonedItem.BasePermissions = item.BasePermissions;
267 clonedItem.CreationDate = item.CreationDate;
268 clonedItem.CreatorId = item.CreatorId;
269 clonedItem.CreatorIdAsUuid = item.CreatorIdAsUuid;
270 clonedItem.CurrentPermissions = item.CurrentPermissions;
271 clonedItem.Description = item.Description;
272 clonedItem.EveryOnePermissions = item.EveryOnePermissions;
273 clonedItem.Flags = item.Flags;
274 clonedItem.Folder = avatarFolder;
275 clonedItem.GroupID = item.GroupID;
276 clonedItem.GroupOwned = item.GroupOwned;
277 clonedItem.GroupPermissions = item.GroupPermissions;
278 clonedItem.ID = UUID.Random();
279 clonedItem.InvType = item.InvType;
280 clonedItem.Name = item.Name;
281 clonedItem.NextPermissions = item.NextPermissions;
282 clonedItem.SalePrice = item.SalePrice;
283 clonedItem.SaleType = item.SaleType;
284
285 if (modifyPerms)
286 {
287 ModifyPermissions(clonedItem);
288 }
289
290 SynchronousRestObjectRequester.MakeRequest<InventoryItemBase, bool>(
291 "POST", m_inventoryServerUrl + "AddNewItem/", clonedItem);
292
293 return clonedItem.ID;
294 }
295
296 return UUID.Zero;
297 }
298
299 private static void ModifyPermissions(InventoryItemBase clonedItem)
300 {
301 if ((clonedItem.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
302 clonedItem.CurrentPermissions |= (uint)PermissionMask.Modify;
303
304 if ((clonedItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
305 clonedItem.CurrentPermissions |= (uint)PermissionMask.Copy;
306
307 if ((clonedItem.CurrentPermissions & (uint)PermissionMask.Transfer) != 0)
308 clonedItem.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
309
310 if ((clonedItem.NextPermissions & (uint)PermissionMask.Modify) == 0)
311 clonedItem.NextPermissions |= (uint)PermissionMask.Modify;
312
313 if ((clonedItem.NextPermissions & (uint)PermissionMask.Copy) == 0)
314 clonedItem.NextPermissions |= (uint)PermissionMask.Copy;
315
316 if ((clonedItem.NextPermissions & (uint)PermissionMask.Transfer) != 0)
317 clonedItem.NextPermissions &= ~(uint)PermissionMask.Transfer;
318 }
319
320 private AvatarAppearance CreateDefaultAppearance(UUID avatarId)
321 {
322 AvatarAppearance appearance = null;
323 AvatarWearable[] wearables;
324 byte[] visualParams;
325 GetDefaultAvatarAppearance(out wearables, out visualParams);
326 appearance = new AvatarAppearance(avatarId, wearables, visualParams);
327
328 return appearance;
329 }
330
331 private static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams)
332 {
333 visualParams = GetDefaultVisualParams();
334 wearables = AvatarWearable.DefaultWearables;
335 }
336
337 private static byte[] GetDefaultVisualParams()
338 {
339 byte[] visualParams;
340 visualParams = new byte[218];
341 for (int i = 0; i < 218; i++)
342 {
343 visualParams[i] = 100;
344 }
345 return visualParams;
346 }
347 #endregion
348
349
350
351 private bool CloneFolder(List<InventoryFolderBase> avatarInventory, UUID avID, UUID parentFolder, AvatarAppearance appearance, InventoryFolderBase templateFolder, List<InventoryFolderBase> templateFolders)
352 {
353 bool success = false;
354 UUID templateFolderId = templateFolder.ID;
355 if (templateFolderId != UUID.Zero)
356 {
357 InventoryFolderBase toFolder = FindFolder(templateFolder.Name, parentFolder.Guid, avatarInventory);
358 if (toFolder == null)
359 {
360 //create new folder
361 toFolder = new InventoryFolderBase();
362 toFolder.ID = UUID.Random();
363 toFolder.Name = templateFolder.Name;
364 toFolder.Owner = avID;
365 toFolder.Type = templateFolder.Type;
366 toFolder.Version = 1;
367 toFolder.ParentID = parentFolder;
368 if (!SynchronousRestObjectRequester.MakeRequest<InventoryFolderBase, bool>(
369 "POST", m_inventoryServerUrl + "CreateFolder/", toFolder))
370 {
371 m_log.InfoFormat("[AvatarApperance] Couldn't make new folder {0} in users inventory", toFolder.Name);
372 return false;
373 }
374 else
375 {
376 // m_log.InfoFormat("made new folder {0} in users inventory", toFolder.Name);
377 }
378 }
379
380 List<InventoryItemBase> templateItems = SynchronousRestObjectRequester.MakeRequest<Guid, List<InventoryItemBase>>(
381 "POST", m_inventoryServerUrl + "GetItems/", templateFolderId.Guid);
382 if ((templateItems != null) && (templateItems.Count > 0))
383 {
384 foreach (InventoryItemBase item in templateItems)
385 {
386
387 UUID clonedItemId = CloneInventoryItem(avID, toFolder.ID, item, false);
388 if (clonedItemId != UUID.Zero)
389 {
390 int appearanceType = ItemIsPartOfAppearance(item, appearance);
391 if (appearanceType >= 0)
392 {
393 UpdateAvatarAppearance(avID, appearanceType, clonedItemId, item.AssetID);
394 }
395
396 if (appearance != null)
397 {
398 int attachment = appearance.GetAttachpoint(item.ID);
399 if (attachment > 0)
400 {
401 UpdateAvatarAttachment(avID, attachment, clonedItemId, item.AssetID);
402 }
403 }
404 success = true;
405 }
406 }
407 }
408
409 List<InventoryFolderBase> subFolders = FindSubFolders(templateFolder.ID.Guid, templateFolders);
410 foreach (InventoryFolderBase subFolder in subFolders)
411 {
412 if (subFolder.Name.ToLower() != "trash")
413 {
414 success = CloneFolder(avatarInventory, avID, toFolder.ID, appearance, subFolder, templateFolders);
415 }
416 }
417 }
418 else
419 {
420 m_log.Info("[AvatarAppearance] Failed to find the template folder");
421 }
422 return success;
423 }
424
425 private int ItemIsPartOfAppearance(InventoryItemBase item, AvatarAppearance appearance)
426 {
427 if (appearance != null)
428 {
429 if (appearance.BodyItem == item.ID)
430 return (int)WearableType.Shape;
431
432 if (appearance.EyesItem == item.ID)
433 return (int)WearableType.Eyes;
434
435 if (appearance.GlovesItem == item.ID)
436 return (int)WearableType.Gloves;
437
438 if (appearance.HairItem == item.ID)
439 return (int)WearableType.Hair;
440
441 if (appearance.JacketItem == item.ID)
442 return (int)WearableType.Jacket;
443
444 if (appearance.PantsItem == item.ID)
445 return (int)WearableType.Pants;
446
447 if (appearance.ShirtItem == item.ID)
448 return (int)WearableType.Shirt;
449
450 if (appearance.ShoesItem == item.ID)
451 return (int)WearableType.Shoes;
452
453 if (appearance.SkinItem == item.ID)
454 return (int)WearableType.Skin;
455
456 if (appearance.SkirtItem == item.ID)
457 return (int)WearableType.Skirt;
458
459 if (appearance.SocksItem == item.ID)
460 return (int)WearableType.Socks;
461
462 if (appearance.UnderPantsItem == item.ID)
463 return (int)WearableType.Underpants;
464
465 if (appearance.UnderShirtItem == item.ID)
466 return (int)WearableType.Undershirt;
467 }
468 return -1;
469 }
470
471 }
472 public enum PermissionMask
473 {
474 None = 0,
475 Transfer = 8192,
476 Modify = 16384,
477 Copy = 32768,
478 Move = 524288,
479 Damage = 1048576,
480 All = 2147483647,
481 }
482
483 public enum WearableType
484 {
485 Shape = 0,
486 Skin = 1,
487 Hair = 2,
488 Eyes = 3,
489 Shirt = 4,
490 Pants = 5,
491 Shoes = 6,
492 Socks = 7,
493 Jacket = 8,
494 Gloves = 9,
495 Undershirt = 10,
496 Underpants = 11,
497 Skirt = 12,
498 }
499}