diff options
Diffstat (limited to 'OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs | 632 |
1 files changed, 0 insertions, 632 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs deleted file mode 100644 index 3334e81..0000000 --- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs +++ /dev/null | |||
@@ -1,632 +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 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 | |||
28 | using System.Collections.Generic; | ||
29 | using System.Threading; | ||
30 | using OpenMetaverse; | ||
31 | using OpenMetaverse.Packets; | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Framework.Communications; | ||
34 | using OpenSim.Framework.Communications.Cache; | ||
35 | |||
36 | namespace OpenSim.Region.Environment.Scenes | ||
37 | { | ||
38 | public partial class Scene | ||
39 | { | ||
40 | protected void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, | ||
41 | UUID fromID, bool fromAgent, bool broadcast) | ||
42 | { | ||
43 | OSChatMessage args = new OSChatMessage(); | ||
44 | |||
45 | args.Message = Utils.BytesToString(message); | ||
46 | args.Channel = channel; | ||
47 | args.Type = type; | ||
48 | args.Position = fromPos; | ||
49 | args.SenderUUID = fromID; | ||
50 | args.Scene = this; | ||
51 | |||
52 | if (fromAgent) | ||
53 | { | ||
54 | ScenePresence user = GetScenePresence(fromID); | ||
55 | if (user != null) | ||
56 | args.Sender = user.ControllingClient; | ||
57 | } | ||
58 | else | ||
59 | { | ||
60 | SceneObjectPart obj = GetSceneObjectPart(fromID); | ||
61 | args.SenderObject = obj; | ||
62 | } | ||
63 | |||
64 | args.From = fromName; | ||
65 | //args. | ||
66 | |||
67 | if (broadcast) | ||
68 | EventManager.TriggerOnChatBroadcast(this, args); | ||
69 | else | ||
70 | EventManager.TriggerOnChatFromWorld(this, args); | ||
71 | |||
72 | } | ||
73 | /// <summary> | ||
74 | /// | ||
75 | /// </summary> | ||
76 | /// <param name="message"></param> | ||
77 | /// <param name="type"></param> | ||
78 | /// <param name="fromPos"></param> | ||
79 | /// <param name="fromName"></param> | ||
80 | /// <param name="fromAgentID"></param> | ||
81 | public void SimChat(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, | ||
82 | UUID fromID, bool fromAgent) | ||
83 | { | ||
84 | SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, false); | ||
85 | } | ||
86 | |||
87 | /// <summary> | ||
88 | /// | ||
89 | /// </summary> | ||
90 | /// <param name="message"></param> | ||
91 | /// <param name="type"></param> | ||
92 | /// <param name="fromPos"></param> | ||
93 | /// <param name="fromName"></param> | ||
94 | /// <param name="fromAgentID"></param> | ||
95 | public void SimChatBroadcast(byte[] message, ChatTypeEnum type, int channel, Vector3 fromPos, string fromName, | ||
96 | UUID fromID, bool fromAgent) | ||
97 | { | ||
98 | SimChat(message, type, channel, fromPos, fromName, fromID, fromAgent, true); | ||
99 | } | ||
100 | |||
101 | /// <summary> | ||
102 | /// Invoked when the client selects a prim. | ||
103 | /// </summary> | ||
104 | /// <param name="primLocalID"></param> | ||
105 | /// <param name="remoteClient"></param> | ||
106 | public void SelectPrim(uint primLocalID, IClientAPI remoteClient) | ||
107 | { | ||
108 | List<EntityBase> EntityList = GetEntities(); | ||
109 | |||
110 | foreach (EntityBase ent in EntityList) | ||
111 | { | ||
112 | if (ent is SceneObjectGroup) | ||
113 | { | ||
114 | if (((SceneObjectGroup) ent).LocalId == primLocalID) | ||
115 | { | ||
116 | ((SceneObjectGroup) ent).GetProperties(remoteClient); | ||
117 | ((SceneObjectGroup) ent).IsSelected = true; | ||
118 | // A prim is only tainted if it's allowed to be edited by the person clicking it. | ||
119 | if (Permissions.CanEditObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId) | ||
120 | || Permissions.CanMoveObject(((SceneObjectGroup)ent).UUID, remoteClient.AgentId)) | ||
121 | { | ||
122 | EventManager.TriggerParcelPrimCountTainted(); | ||
123 | } | ||
124 | break; | ||
125 | } | ||
126 | else | ||
127 | { | ||
128 | // We also need to check the children of this prim as they | ||
129 | // can be selected as well and send property information | ||
130 | bool foundPrim = false; | ||
131 | foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children) | ||
132 | { | ||
133 | if (child.Value.LocalId == primLocalID) | ||
134 | { | ||
135 | child.Value.GetProperties(remoteClient); | ||
136 | foundPrim = true; | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | if (foundPrim) break; | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | /// <summary> | ||
147 | /// Handle the deselection of a prim from the client. | ||
148 | /// </summary> | ||
149 | /// <param name="primLocalID"></param> | ||
150 | /// <param name="remoteClient"></param> | ||
151 | public void DeselectPrim(uint primLocalID, IClientAPI remoteClient) | ||
152 | { | ||
153 | SceneObjectPart part = GetSceneObjectPart(primLocalID); | ||
154 | if (part == null) | ||
155 | return; | ||
156 | |||
157 | // The prim is in the process of being deleted. | ||
158 | if (null == part.ParentGroup.RootPart) | ||
159 | return; | ||
160 | |||
161 | // A deselect packet contains all the local prims being deselected. However, since selection is still | ||
162 | // group based we only want the root prim to trigger a full update - otherwise on objects with many prims | ||
163 | // we end up sending many duplicate ObjectUpdates | ||
164 | if (part.ParentGroup.RootPart.LocalId != part.LocalId) | ||
165 | return; | ||
166 | |||
167 | bool isAttachment = false; | ||
168 | |||
169 | // This is wrong, wrong, wrong. Selection should not be | ||
170 | // handled by group, but by prim. Legacy cruft. | ||
171 | // TODO: Make selection flagging per prim! | ||
172 | // | ||
173 | part.ParentGroup.IsSelected = false; | ||
174 | |||
175 | if (part.ParentGroup.IsAttachment) | ||
176 | isAttachment = true; | ||
177 | else | ||
178 | part.ParentGroup.ScheduleGroupForFullUpdate(); | ||
179 | |||
180 | // If it's not an attachment, and we are allowed to move it, | ||
181 | // then we might have done so. If we moved across a parcel | ||
182 | // boundary, we will need to recount prims on the parcels. | ||
183 | // For attachments, that makes no sense. | ||
184 | // | ||
185 | if (!isAttachment) | ||
186 | { | ||
187 | if (Permissions.CanEditObject( | ||
188 | part.UUID, remoteClient.AgentId) | ||
189 | || Permissions.CanMoveObject( | ||
190 | part.UUID, remoteClient.AgentId)) | ||
191 | EventManager.TriggerParcelPrimCountTainted(); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | public virtual void ProcessMoneyTransferRequest(UUID source, UUID destination, int amount, | ||
196 | int transactiontype, string description) | ||
197 | { | ||
198 | EventManager.MoneyTransferArgs args = new EventManager.MoneyTransferArgs(source, destination, amount, | ||
199 | transactiontype, description); | ||
200 | |||
201 | EventManager.TriggerMoneyTransfer(this, args); | ||
202 | } | ||
203 | |||
204 | public virtual void ProcessParcelBuy(UUID agentId, UUID groupId, bool final, bool groupOwned, | ||
205 | bool removeContribution, int parcelLocalID, int parcelArea, int parcelPrice, bool authenticated) | ||
206 | { | ||
207 | EventManager.LandBuyArgs args = new EventManager.LandBuyArgs(agentId, groupId, final, groupOwned, | ||
208 | removeContribution, parcelLocalID, parcelArea, | ||
209 | parcelPrice, authenticated); | ||
210 | |||
211 | // First, allow all validators a stab at it | ||
212 | m_eventManager.TriggerValidateLandBuy(this, args); | ||
213 | |||
214 | // Then, check validation and transfer | ||
215 | m_eventManager.TriggerLandBuy(this, args); | ||
216 | } | ||
217 | |||
218 | public virtual void ProcessObjectGrab(uint localID, Vector3 offsetPos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) | ||
219 | { | ||
220 | List<EntityBase> EntityList = GetEntities(); | ||
221 | |||
222 | SurfaceTouchEventArgs surfaceArg = null; | ||
223 | if (surfaceArgs != null && surfaceArgs.Count > 0) | ||
224 | surfaceArg = surfaceArgs[0]; | ||
225 | |||
226 | foreach (EntityBase ent in EntityList) | ||
227 | { | ||
228 | if (ent is SceneObjectGroup) | ||
229 | { | ||
230 | SceneObjectGroup obj = ent as SceneObjectGroup; | ||
231 | if (obj != null) | ||
232 | { | ||
233 | // Is this prim part of the group | ||
234 | if (obj.HasChildPrim(localID)) | ||
235 | { | ||
236 | // Currently only grab/touch for the single prim | ||
237 | // the client handles rez correctly | ||
238 | obj.ObjectGrabHandler(localID, offsetPos, remoteClient); | ||
239 | |||
240 | SceneObjectPart part = obj.GetChildPart(localID); | ||
241 | |||
242 | // If the touched prim handles touches, deliver it | ||
243 | // If not, deliver to root prim | ||
244 | if ((part.ScriptEvents & scriptEvents.touch_start) != 0) | ||
245 | EventManager.TriggerObjectGrab(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); | ||
246 | else | ||
247 | EventManager.TriggerObjectGrab(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); | ||
248 | |||
249 | return; | ||
250 | } | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | |||
256 | public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient) | ||
257 | { | ||
258 | List<EntityBase> EntityList = GetEntities(); | ||
259 | |||
260 | foreach (EntityBase ent in EntityList) | ||
261 | { | ||
262 | if (ent is SceneObjectGroup) | ||
263 | { | ||
264 | SceneObjectGroup obj = ent as SceneObjectGroup; | ||
265 | |||
266 | // Is this prim part of the group | ||
267 | if (obj.HasChildPrim(localID)) | ||
268 | { | ||
269 | SceneObjectPart part=obj.GetChildPart(localID); | ||
270 | if (part != null) | ||
271 | { | ||
272 | // If the touched prim handles touches, deliver it | ||
273 | // If not, deliver to root prim | ||
274 | if ((part.ScriptEvents & scriptEvents.touch_end) != 0) | ||
275 | EventManager.TriggerObjectDeGrab(part.LocalId, 0, remoteClient); | ||
276 | else | ||
277 | EventManager.TriggerObjectDeGrab(obj.RootPart.LocalId, part.LocalId, remoteClient); | ||
278 | |||
279 | return; | ||
280 | } | ||
281 | return; | ||
282 | } | ||
283 | } | ||
284 | } | ||
285 | } | ||
286 | |||
287 | public void ProcessAvatarPickerRequest(IClientAPI client, UUID avatarID, UUID RequestID, string query) | ||
288 | { | ||
289 | //EventManager.TriggerAvatarPickerRequest(); | ||
290 | |||
291 | List<AvatarPickerAvatar> AvatarResponses = new List<AvatarPickerAvatar>(); | ||
292 | AvatarResponses = m_sceneGridService.GenerateAgentPickerRequestResponse(RequestID, query); | ||
293 | |||
294 | AvatarPickerReplyPacket replyPacket = (AvatarPickerReplyPacket) PacketPool.Instance.GetPacket(PacketType.AvatarPickerReply); | ||
295 | // TODO: don't create new blocks if recycling an old packet | ||
296 | |||
297 | AvatarPickerReplyPacket.DataBlock[] searchData = | ||
298 | new AvatarPickerReplyPacket.DataBlock[AvatarResponses.Count]; | ||
299 | AvatarPickerReplyPacket.AgentDataBlock agentData = new AvatarPickerReplyPacket.AgentDataBlock(); | ||
300 | |||
301 | agentData.AgentID = avatarID; | ||
302 | agentData.QueryID = RequestID; | ||
303 | replyPacket.AgentData = agentData; | ||
304 | //byte[] bytes = new byte[AvatarResponses.Count*32]; | ||
305 | |||
306 | int i = 0; | ||
307 | foreach (AvatarPickerAvatar item in AvatarResponses) | ||
308 | { | ||
309 | UUID translatedIDtem = item.AvatarID; | ||
310 | searchData[i] = new AvatarPickerReplyPacket.DataBlock(); | ||
311 | searchData[i].AvatarID = translatedIDtem; | ||
312 | searchData[i].FirstName = Utils.StringToBytes((string) item.firstName); | ||
313 | searchData[i].LastName = Utils.StringToBytes((string) item.lastName); | ||
314 | i++; | ||
315 | } | ||
316 | if (AvatarResponses.Count == 0) | ||
317 | { | ||
318 | searchData = new AvatarPickerReplyPacket.DataBlock[0]; | ||
319 | } | ||
320 | replyPacket.Data = searchData; | ||
321 | |||
322 | AvatarPickerReplyAgentDataArgs agent_data = new AvatarPickerReplyAgentDataArgs(); | ||
323 | agent_data.AgentID = replyPacket.AgentData.AgentID; | ||
324 | agent_data.QueryID = replyPacket.AgentData.QueryID; | ||
325 | |||
326 | List<AvatarPickerReplyDataArgs> data_args = new List<AvatarPickerReplyDataArgs>(); | ||
327 | for (i = 0; i < replyPacket.Data.Length; i++) | ||
328 | { | ||
329 | AvatarPickerReplyDataArgs data_arg = new AvatarPickerReplyDataArgs(); | ||
330 | data_arg.AvatarID = replyPacket.Data[i].AvatarID; | ||
331 | data_arg.FirstName = replyPacket.Data[i].FirstName; | ||
332 | data_arg.LastName = replyPacket.Data[i].LastName; | ||
333 | data_args.Add(data_arg); | ||
334 | } | ||
335 | client.SendAvatarPickerReply(agent_data, data_args); | ||
336 | } | ||
337 | |||
338 | public void ProcessScriptReset(IClientAPI remoteClient, UUID objectID, | ||
339 | UUID itemID) | ||
340 | { | ||
341 | SceneObjectPart part=GetSceneObjectPart(objectID); | ||
342 | if (part == null) | ||
343 | return; | ||
344 | |||
345 | if (Permissions.CanResetScript(objectID, itemID, remoteClient.AgentId)) | ||
346 | { | ||
347 | EventManager.TriggerScriptReset(part.LocalId, itemID); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | /// <summary> | ||
352 | /// Handle a fetch inventory request from the client | ||
353 | /// </summary> | ||
354 | /// <param name="remoteClient"></param> | ||
355 | /// <param name="itemID"></param> | ||
356 | /// <param name="ownerID"></param> | ||
357 | public void HandleFetchInventory(IClientAPI remoteClient, UUID itemID, UUID ownerID) | ||
358 | { | ||
359 | if (ownerID == CommsManager.UserProfileCacheService.LibraryRoot.Owner) | ||
360 | { | ||
361 | //Console.WriteLine("request info for library item"); | ||
362 | return; | ||
363 | } | ||
364 | |||
365 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
366 | |||
367 | if (null == userProfile) | ||
368 | { | ||
369 | m_log.ErrorFormat( | ||
370 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
371 | remoteClient.Name, remoteClient.AgentId); | ||
372 | return; | ||
373 | } | ||
374 | |||
375 | if (userProfile.HasReceivedInventory) | ||
376 | { | ||
377 | InventoryItemBase item = null; | ||
378 | if (userProfile.RootFolder == null) | ||
379 | m_log.ErrorFormat( | ||
380 | "[AGENT INVENTORY]: User {0} {1} does not have a root folder.", | ||
381 | remoteClient.Name, remoteClient.AgentId); | ||
382 | else | ||
383 | item = userProfile.RootFolder.FindItem(itemID); | ||
384 | |||
385 | if (item != null) | ||
386 | { | ||
387 | remoteClient.SendInventoryItemDetails(ownerID, item); | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | |||
392 | /// <summary> | ||
393 | /// Tell the client about the various child items and folders contained in the requested folder. | ||
394 | /// </summary> | ||
395 | /// <param name="remoteClient"></param> | ||
396 | /// <param name="folderID"></param> | ||
397 | /// <param name="ownerID"></param> | ||
398 | /// <param name="fetchFolders"></param> | ||
399 | /// <param name="fetchItems"></param> | ||
400 | /// <param name="sortOrder"></param> | ||
401 | public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID, | ||
402 | bool fetchFolders, bool fetchItems, int sortOrder) | ||
403 | { | ||
404 | // FIXME MAYBE: We're not handling sortOrder! | ||
405 | |||
406 | // TODO: This code for looking in the folder for the library should be folded back into the | ||
407 | // CachedUserInfo so that this class doesn't have to know the details (and so that multiple libraries, etc. | ||
408 | // can be handled transparently). | ||
409 | InventoryFolderImpl fold = null; | ||
410 | if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null) | ||
411 | { | ||
412 | remoteClient.SendInventoryFolderDetails( | ||
413 | fold.Owner, folderID, fold.RequestListOfItems(), | ||
414 | fold.RequestListOfFolders(), fetchFolders, fetchItems); | ||
415 | return; | ||
416 | } | ||
417 | |||
418 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
419 | |||
420 | if (null == userProfile) | ||
421 | { | ||
422 | m_log.ErrorFormat( | ||
423 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
424 | remoteClient.Name, remoteClient.AgentId); | ||
425 | return; | ||
426 | } | ||
427 | |||
428 | userProfile.SendInventoryDecendents(remoteClient, folderID, fetchFolders, fetchItems); | ||
429 | } | ||
430 | |||
431 | /// <summary> | ||
432 | /// Handle the caps inventory descendents fetch. | ||
433 | /// | ||
434 | /// Since the folder structure is sent to the client on login, I believe we only need to handle items. | ||
435 | /// </summary> | ||
436 | /// <param name="agentID"></param> | ||
437 | /// <param name="folderID"></param> | ||
438 | /// <param name="ownerID"></param> | ||
439 | /// <param name="fetchFolders"></param> | ||
440 | /// <param name="fetchItems"></param> | ||
441 | /// <param name="sortOrder"></param> | ||
442 | /// <returns>null if the inventory look up failed</returns> | ||
443 | public List<InventoryItemBase> HandleFetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, | ||
444 | bool fetchFolders, bool fetchItems, int sortOrder) | ||
445 | { | ||
446 | // m_log.DebugFormat( | ||
447 | // "[INVENTORY CACHE]: Fetching folders ({0}), items ({1}) from {2} for agent {3}", | ||
448 | // fetchFolders, fetchItems, folderID, agentID); | ||
449 | |||
450 | // FIXME MAYBE: We're not handling sortOrder! | ||
451 | |||
452 | // TODO: This code for looking in the folder for the library should be folded back into the | ||
453 | // CachedUserInfo so that this class doesn't have to know the details (and so that multiple libraries, etc. | ||
454 | // can be handled transparently). | ||
455 | InventoryFolderImpl fold; | ||
456 | if ((fold = CommsManager.UserProfileCacheService.LibraryRoot.FindFolder(folderID)) != null) | ||
457 | { | ||
458 | return fold.RequestListOfItems(); | ||
459 | } | ||
460 | |||
461 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(agentID); | ||
462 | |||
463 | if (null == userProfile) | ||
464 | { | ||
465 | m_log.ErrorFormat("[AGENT INVENTORY]: Could not find user profile for {0}", agentID); | ||
466 | return null; | ||
467 | } | ||
468 | |||
469 | // XXX: When a client crosses into a scene, their entire inventory is fetched | ||
470 | // asynchronously. If the client makes a request before the inventory is received, we need | ||
471 | // to give the inventory a chance to come in. | ||
472 | // | ||
473 | // This is a crude way of dealing with that by retrying the lookup. It's not quite as bad | ||
474 | // in CAPS as doing this with the udp request, since here it won't hold up other packets. | ||
475 | // In fact, here we'll be generous and try for longer. | ||
476 | if (!userProfile.HasReceivedInventory) | ||
477 | { | ||
478 | int attempts = 0; | ||
479 | while (attempts++ < 30) | ||
480 | { | ||
481 | m_log.DebugFormat( | ||
482 | "[INVENTORY CACHE]: Poll number {0} for inventory items in folder {1} for user {2}", | ||
483 | attempts, folderID, agentID); | ||
484 | |||
485 | Thread.Sleep(2000); | ||
486 | |||
487 | if (userProfile.HasReceivedInventory) | ||
488 | { | ||
489 | break; | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | |||
494 | if (userProfile.HasReceivedInventory) | ||
495 | { | ||
496 | if ((fold = userProfile.RootFolder.FindFolder(folderID)) != null) | ||
497 | { | ||
498 | return fold.RequestListOfItems(); | ||
499 | } | ||
500 | else | ||
501 | { | ||
502 | m_log.WarnFormat( | ||
503 | "[AGENT INVENTORY]: Could not find folder {0} requested by user {1}", | ||
504 | folderID, agentID); | ||
505 | return null; | ||
506 | } | ||
507 | } | ||
508 | else | ||
509 | { | ||
510 | m_log.ErrorFormat("[INVENTORY CACHE]: Could not find root folder for user {0}", agentID); | ||
511 | return null; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | /// <summary> | ||
516 | /// Handle an inventory folder creation request from the client. | ||
517 | /// </summary> | ||
518 | /// <param name="remoteClient"></param> | ||
519 | /// <param name="folderID"></param> | ||
520 | /// <param name="folderType"></param> | ||
521 | /// <param name="folderName"></param> | ||
522 | /// <param name="parentID"></param> | ||
523 | public void HandleCreateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort folderType, | ||
524 | string folderName, UUID parentID) | ||
525 | { | ||
526 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
527 | |||
528 | if (null == userProfile) | ||
529 | { | ||
530 | m_log.ErrorFormat( | ||
531 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
532 | remoteClient.Name, remoteClient.AgentId); | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | if (!userProfile.CreateFolder(folderName, folderID, folderType, parentID)) | ||
537 | { | ||
538 | m_log.ErrorFormat( | ||
539 | "[AGENT INVENTORY]: Failed to move create folder for user {0} {1}", | ||
540 | remoteClient.Name, remoteClient.AgentId); | ||
541 | } | ||
542 | } | ||
543 | |||
544 | /// <summary> | ||
545 | /// Handle a client request to update the inventory folder | ||
546 | /// </summary> | ||
547 | /// | ||
548 | /// FIXME: We call add new inventory folder because in the data layer, we happen to use an SQL REPLACE | ||
549 | /// so this will work to rename an existing folder. Needless to say, to rely on this is very confusing, | ||
550 | /// and needs to be changed. | ||
551 | /// | ||
552 | /// <param name="remoteClient"></param> | ||
553 | /// <param name="folderID"></param> | ||
554 | /// <param name="type"></param> | ||
555 | /// <param name="name"></param> | ||
556 | /// <param name="parentID"></param> | ||
557 | public void HandleUpdateInventoryFolder(IClientAPI remoteClient, UUID folderID, ushort type, string name, | ||
558 | UUID parentID) | ||
559 | { | ||
560 | // m_log.DebugFormat( | ||
561 | // "[AGENT INVENTORY]: Updating inventory folder {0} {1} for {2} {3}", folderID, name, remoteClient.Name, remoteClient.AgentId); | ||
562 | |||
563 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
564 | |||
565 | if (null == userProfile) | ||
566 | { | ||
567 | m_log.ErrorFormat( | ||
568 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
569 | remoteClient.Name, remoteClient.AgentId); | ||
570 | return; | ||
571 | } | ||
572 | |||
573 | if (!userProfile.UpdateFolder(name, folderID, type, parentID)) | ||
574 | { | ||
575 | m_log.ErrorFormat( | ||
576 | "[AGENT INVENTORY]: Failed to update folder for user {0} {1}", | ||
577 | remoteClient.Name, remoteClient.AgentId); | ||
578 | } | ||
579 | } | ||
580 | |||
581 | /// <summary> | ||
582 | /// Handle an inventory folder move request from the client. | ||
583 | /// </summary> | ||
584 | /// <param name="remoteClient"></param> | ||
585 | /// <param name="folderID"></param> | ||
586 | /// <param name="parentID"></param> | ||
587 | public void HandleMoveInventoryFolder(IClientAPI remoteClient, UUID folderID, UUID parentID) | ||
588 | { | ||
589 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
590 | |||
591 | if (null == userProfile) | ||
592 | { | ||
593 | m_log.ErrorFormat( | ||
594 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
595 | remoteClient.Name, remoteClient.AgentId); | ||
596 | return; | ||
597 | } | ||
598 | |||
599 | if (!userProfile.MoveFolder(folderID, parentID)) | ||
600 | { | ||
601 | m_log.ErrorFormat( | ||
602 | "[AGENT INVENTORY]: Failed to move folder {0} to {1} for user {2}", | ||
603 | folderID, parentID, remoteClient.Name); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | /// <summary> | ||
608 | /// This should delete all the items and folders in the given directory. | ||
609 | /// </summary> | ||
610 | /// <param name="remoteClient"></param> | ||
611 | /// <param name="folderID"></param> | ||
612 | public void HandlePurgeInventoryDescendents(IClientAPI remoteClient, UUID folderID) | ||
613 | { | ||
614 | CachedUserInfo userProfile = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); | ||
615 | |||
616 | if (null == userProfile) | ||
617 | { | ||
618 | m_log.ErrorFormat( | ||
619 | "[AGENT INVENTORY]: Could not find user profile for {0} {1}", | ||
620 | remoteClient.Name, remoteClient.AgentId); | ||
621 | return; | ||
622 | } | ||
623 | |||
624 | if (!userProfile.PurgeFolder(folderID)) | ||
625 | { | ||
626 | m_log.ErrorFormat( | ||
627 | "[AGENT INVENTORY]: Failed to purge folder for user {0} {1}", | ||
628 | remoteClient.Name, remoteClient.AgentId); | ||
629 | } | ||
630 | } | ||
631 | } | ||
632 | } | ||