aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs257
1 files changed, 257 insertions, 0 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
new file mode 100644
index 0000000..d458364
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -0,0 +1,257 @@
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.Collections.Generic;
29using System.Reflection;
30using log4net;
31using Nini.Config;
32using OpenMetaverse;
33using OpenSim.Framework;
34using OpenSim.Region.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.Framework.Scenes;
37
38namespace OpenSim.Region.CoreModules.Avatar.Attachments
39{
40 public class AttachmentsModule : IAttachmentsModule, IRegionModule
41 {
42 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
43
44 protected Scene m_scene = null;
45
46 public void Initialise(Scene scene, IConfigSource source)
47 {
48 scene.RegisterModuleInterface<IAttachmentsModule>(this);
49 m_scene = scene;
50 }
51
52 public void PostInitialise()
53 {
54 }
55
56 public void Close()
57 {
58 }
59
60 public string Name
61 {
62 get { return "Attachments Module"; }
63 }
64
65 public bool IsSharedModule
66 {
67 get { return false; }
68 }
69
70 public bool AttachObject(
71 IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent)
72 {
73 SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID);
74 if (group != null)
75 {
76 if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId))
77 {
78 // If the attachment point isn't the same as the one previously used
79 // set it's offset position = 0 so that it appears on the attachment point
80 // and not in a weird location somewhere unknown.
81 if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint())
82 {
83 attachPos = Vector3.Zero;
84 }
85
86 // AttachmentPt 0 means the client chose to 'wear' the attachment.
87 if (AttachmentPt == 0)
88 {
89 // Check object for stored attachment point
90 AttachmentPt = (uint)group.GetAttachmentPoint();
91 }
92
93 // if we still didn't find a suitable attachment point.......
94 if (AttachmentPt == 0)
95 {
96 // Stick it on left hand with Zero Offset from the attachment point.
97 AttachmentPt = (uint)AttachmentPoint.LeftHand;
98 attachPos = Vector3.Zero;
99 }
100
101 group.SetAttachmentPoint((byte)AttachmentPt);
102 group.AbsolutePosition = attachPos;
103
104 // Saves and gets itemID
105 UUID itemId;
106
107 if (group.GetFromItemID() == UUID.Zero)
108 {
109 m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId);
110 }
111 else
112 {
113 itemId = group.GetFromItemID();
114 }
115
116 SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group);
117
118 group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent);
119
120 // In case it is later dropped again, don't let
121 // it get cleaned up
122 group.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
123 group.HasGroupChanged = false;
124 }
125 else
126 {
127 remoteClient.SendAgentAlertMessage(
128 "You don't have sufficient permissions to attach this object", false);
129
130 return false;
131 }
132 }
133 else
134 {
135 m_log.DebugFormat("[ATTACHMENTS MODULE]: AttachObject found no such scene object {0}", objectLocalID);
136 return false;
137 }
138
139 return true;
140 }
141
142 public UUID SetAttachmentInventoryStatus(
143 SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
144 {
145 m_log.DebugFormat(
146 "[ATTACHMENTS MODULEY]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
147 remoteClient.Name, att.Name, itemID);
148
149 if (!att.IsDeleted)
150 AttachmentPt = att.RootPart.AttachmentPoint;
151
152 ScenePresence presence;
153 if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
154 {
155 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
156 item = m_scene.InventoryService.GetItem(item);
157
158 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
159 }
160
161 return att.UUID;
162 }
163
164 /// <summary>
165 /// Update the user inventory to reflect an attachment
166 /// </summary>
167 /// <param name="remoteClient"></param>
168 /// <param name="AttachmentPt"></param>
169 /// <param name="itemID"></param>
170 /// <param name="att"></param>
171 public void SetAttachmentInventoryStatus(
172 IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
173 {
174// m_log.DebugFormat(
175// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
176// att.Name, remoteClient.Name, AttachmentPt, itemID);
177
178 if (UUID.Zero == itemID)
179 {
180 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID.");
181 return;
182 }
183
184 if (0 == AttachmentPt)
185 {
186 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point.");
187 return;
188 }
189
190 if (null == att.RootPart)
191 {
192 m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment for a prim without the rootpart!");
193 return;
194 }
195
196 ScenePresence presence;
197 if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
198 {
199 // XXYY!!
200 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
201 item = m_scene.InventoryService.GetItem(item);
202 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */);
203
204 if (m_scene.AvatarFactory != null)
205 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
206 }
207 }
208
209 public void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient)
210 {
211 ScenePresence presence;
212 if (m_scene.TryGetAvatar(remoteClient.AgentId, out presence))
213 {
214 presence.Appearance.DetachAttachment(itemID);
215
216 // Save avatar attachment information
217 if (m_scene.AvatarFactory != null)
218 {
219 m_log.Debug("[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", ItemID: " + itemID);
220 m_scene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
221 }
222 }
223
224 DetachSingleAttachmentToInv(itemID, remoteClient);
225 }
226
227 // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards.
228 // To LocalId or UUID, *THAT* is the question. How now Brown UUID??
229 protected void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
230 {
231 if (itemID == UUID.Zero) // If this happened, someone made a mistake....
232 return;
233
234 // We can NOT use the dictionries here, as we are looking
235 // for an entity by the fromAssetID, which is NOT the prim UUID
236 List<EntityBase> detachEntities = m_scene.GetEntities();
237 SceneObjectGroup group;
238
239 foreach (EntityBase entity in detachEntities)
240 {
241 if (entity is SceneObjectGroup)
242 {
243 group = (SceneObjectGroup)entity;
244 if (group.GetFromItemID() == itemID)
245 {
246 m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero);
247 group.DetachToInventoryPrep();
248 m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString());
249 m_scene.UpdateKnownItem(remoteClient, group,group.GetFromItemID(), group.OwnerID);
250 m_scene.DeleteSceneObject(group, false);
251 return;
252 }
253 }
254 }
255 }
256 }
257} \ No newline at end of file