29 using System.Collections.Generic;
30 using System.Reflection;
32 using System.Threading;
38 using OpenMetaverse.Packets;
39 using OpenSim.Framework;
40 using OpenSim.Region.Framework;
41 using OpenSim.Region.Framework.Interfaces;
42 using OpenSim.Region.Framework.Scenes;
43 using OpenSim.Region.Framework.Scenes.Serialization;
44 using OpenSim.Services.Interfaces;
48 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"AttachmentsModule")]
51 #region INonSharedRegionModule
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 public int DebugLevel {
get; set; }
63 public int ThrottlePer100PrimsRezzed {
get; set; }
65 private Scene m_scene;
71 public bool Enabled {
get;
private set; }
73 public string Name {
get {
return "Attachments Module"; } }
74 public Type ReplaceableInterface {
get {
return null; } }
78 IConfig config = source.Configs[
"Attachments"];
81 Enabled = config.GetBoolean(
"Enabled",
true);
83 ThrottlePer100PrimsRezzed = config.GetInt(
"ThrottlePer100PrimsRezzed", 0);
100 m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
101 m_scene.EventManager.OnStartScript += (localID, itemID) => HandleScriptStateChange(localID,
true);
102 m_scene.EventManager.OnStopScript += (localID, itemID) => HandleScriptStateChange(localID,
false);
104 MainConsole.Instance.Commands.AddCommand(
107 "debug attachments log",
108 "debug attachments log [0|1]",
109 "Turn on attachments debug logging",
110 " <= 0 - turns off debug logging\n"
111 +
" >= 1 - turns on attachment message debug logging",
112 HandleDebugAttachmentsLog);
114 MainConsole.Instance.Commands.AddCommand(
117 "debug attachments throttle",
118 "debug attachments throttle <ms>",
119 "Turn on attachments throttling.",
120 "This requires a millisecond value. " +
121 " == 0 - disable throttling.\n"
122 +
" > 0 - sleeps for this number of milliseconds per 100 prims rezzed.",
123 HandleDebugAttachmentsThrottle);
125 MainConsole.Instance.Commands.AddCommand(
128 "debug attachments status",
129 "debug attachments status",
130 "Show current attachments debug status",
131 HandleDebugAttachmentsStatus);
137 private void HandleDebugAttachmentsLog(
string module,
string[] args)
141 if (!(args.Length == 4 &&
int.TryParse(args[3], out debugLevel)))
143 MainConsole.Instance.OutputFormat(
"Usage: debug attachments log [0|1]");
147 DebugLevel = debugLevel;
148 MainConsole.Instance.OutputFormat(
149 "Set attachments debug level to {0} in {1}", DebugLevel, m_scene.Name);
153 private void HandleDebugAttachmentsThrottle(
string module,
string[] args)
157 if (args.Length == 4 &&
int.TryParse(args[3], out ms))
159 ThrottlePer100PrimsRezzed = ms;
160 MainConsole.Instance.OutputFormat(
161 "Attachments rez throttle per 100 prims is now {0} in {1}", ThrottlePer100PrimsRezzed, m_scene.Name);
166 MainConsole.Instance.OutputFormat(
"Usage: debug attachments throttle <ms>");
169 private void HandleDebugAttachmentsStatus(
string module,
string[] args)
171 MainConsole.Instance.OutputFormat(
"Settings for {0}", m_scene.Name);
172 MainConsole.Instance.OutputFormat(
"Debug logging level: {0}", DebugLevel);
173 MainConsole.Instance.OutputFormat(
"Throttle per 100 prims: {0}ms", ThrottlePer100PrimsRezzed);
181 private void HandleScriptStateChange(uint localID,
bool started)
191 ScenePresence sp = m_scene.GetScenePresence(sog.AttachedAvatar);
193 sog.HasGroupChanged =
true;
197 sog.HasGroupChanged =
true;
207 m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
217 RemoveRegion(m_scene);
222 #region IAttachmentsModule
229 List<SceneObjectGroup> attachments = sp.GetAttachments();
230 if (attachments.Count > 0)
232 ad.AttachmentObjects =
new List<ISceneObject>();
233 ad.AttachmentObjectStates =
new List<string>();
235 sp.InTransitScriptStates.Clear();
243 ((
SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
245 ad.AttachmentObjects.Add(clone);
246 string state = sog.GetStateSnapshot();
247 ad.AttachmentObjectStates.Add(state);
248 sp.InTransitScriptStates.Add(state);
264 sp.ClearAttachments();
276 so.SetState(ad.AttachmentObjectStates[i++], m_scene);
277 m_scene.IncomingCreateObject(Vector3.Zero, so);
289 m_log.WarnFormat(
"[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID);
298 "[ATTACHMENTS MODULE]: Not doing simulator-side attachment rez for {0} in {1} as their viewer has already rezzed attachments",
299 m_scene.Name, sp.Name);
305 m_log.DebugFormat(
"[ATTACHMENTS MODULE]: Rezzing any attachments for {0} from simulator-side", sp.Name);
307 XmlDocument doc =
new XmlDocument();
308 string stateData = String.Empty;
313 m_log.DebugFormat(
"[ATTACHMENT]: Loading attachment data from attachment service");
314 stateData = attServ.Get(sp.UUID.ToString());
315 if (stateData !=
String.Empty)
319 doc.LoadXml(stateData);
325 Dictionary<UUID, string> itemData =
new Dictionary<UUID, string>();
327 XmlNodeList nodes = doc.GetElementsByTagName(
"Attachment");
330 foreach (XmlNode n
in nodes)
332 XmlElement elem = (XmlElement)n;
333 string itemID = elem.GetAttribute(
"ItemID");
334 string xml = elem.InnerXml;
336 itemData[
new UUID(itemID)] = xml;
341 List<AvatarAttachment> attachments = sp.Appearance.GetAttachments();
344 UUID[] items =
new UUID[attachments.Count];
347 items[i++] = attach.ItemID;
348 m_scene.InventoryService.GetMultipleItems(sp.UUID, items);
369 XmlDocument d = null;
371 if (itemData.TryGetValue(attach.
ItemID, out xmlData))
373 d =
new XmlDocument();
375 m_log.InfoFormat(
"[ATTACHMENT]: Found saved state for item {0}, loading it", attach.ItemID);
380 RezSingleAttachmentFromInventoryInternal(
385 UUID agentId = (sp.ControllingClient == null) ?
default(
UUID) : sp.ControllingClient.AgentId;
386 m_log.ErrorFormat(
"[ATTACHMENTS MODULE]: Unable to rez attachment with itemID {0}, assetID {1}, point {2} for {3}: {4}\n{5}",
387 attach.ItemID, attach.AssetID, attachmentPt, agentId, e.Message, e.StackTrace);
397 List<SceneObjectGroup> attachments = sp.GetAttachments();
401 "[ATTACHMENTS MODULE]: Saving for {0} attachments for {1} in {2}",
402 attachments.Count, sp.Name, m_scene.Name);
404 if (attachments.Count <= 0)
407 Dictionary<SceneObjectGroup, string> scriptStates =
new Dictionary<SceneObjectGroup, string>();
419 scriptStates[so] = PrepareScriptInstanceForSave(so,
false);
425 UpdateDetachedObject(sp, so, scriptStates[so]);
426 sp.ClearAttachments();
434 UpdateDetachedObject(sp, so,
String.Empty);
435 sp.ClearAttachments();
447 "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}",
448 m_scene.RegionInfo.RegionName, sp.Name, silent);
452 sop.Scene.DeleteSceneObject(sop, silent);
455 sp.ClearAttachments();
459 bool addToInventory,
bool append)
464 return AttachObjectInternal(sp, group, attachmentPt, silent, addToInventory,
false, append);
478 bool silent,
bool addToInventory,
bool resumeScripts,
bool append)
497 "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
498 group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());
503 Vector3 attachPos = group.AbsolutePosition;
507 attachmentPt &= 0x7f;
514 attachPos = Vector3.Zero;
521 attachPos = group.RootPart.AttachedPos;
528 attachmentPt = group.AttachmentPoint;
532 if (attachmentPt == 0)
540 if (attachmentPt == 0)
544 attachPos = Vector3.Zero;
547 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
549 if (attachments.Contains(group))
553 "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
554 group.Name, group.LocalId, sp.Name, attachmentPt);
560 while (attachments.Count >= 5)
562 if (attachments[0].FromItemID !=
UUID.Zero)
563 DetachSingleAttachmentToInv(sp, attachments[0]);
564 attachments.RemoveAt(0);
568 if (attachments.Count != 0 && !append)
573 DetachSingleAttachmentToInv(sp, g);
577 group.DetachFromBackup();
581 group.AttachmentPoint = attachmentPt;
582 group.AbsolutePosition = attachPos;
585 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, append);
587 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
593 group.CreateScriptInstances(0,
true, m_scene.DefaultScriptEngine, 4);
594 group.ResumeScripts();
598 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
607 UUID newAttachmentItemID = group.FromItemID;
608 if (newAttachmentItemID ==
UUID.Zero)
609 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
611 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
616 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt, null);
626 "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}",
633 bool alreadyOn =
false;
634 List<AvatarAttachment> existingAttachments = sp.Appearance.GetAttachments();
637 if (existingAttachment.
ItemID == itemID)
648 "[ATTACHMENTS MODULE]: Ignoring request by {0} to wear item {1} at {2} since it is already worn",
649 sp.Name, itemID, AttachmentPt);
654 bool append = (AttachmentPt & 0x80) != 0;
655 AttachmentPt &= 0x7f;
657 return RezSingleAttachmentFromInventoryInternal(sp, itemID,
UUID.Zero, AttachmentPt, append, doc);
667 "[ATTACHMENTS MODULE]: Rezzing {0} attachments from inventory for {1} in {2}",
668 rezlist.Count, sp.Name, m_scene.Name);
670 foreach (KeyValuePair<UUID, uint> rez
in rezlist)
672 RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value);
678 Vector3 pos =
new Vector3(2.5f, 0f, 0f);
680 pos += sp.AbsolutePosition;
681 DetachSingleAttachmentToGround(sp, soLocalId, pos, Quaternion.Identity);
691 "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}",
699 if (so.AttachedAvatar != sp.
UUID)
702 UUID inventoryID = so.FromItemID;
705 if (inventoryID ==
UUID.Zero)
710 "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}",
711 so.Name, so.LocalId, inventoryID);
715 if (!m_scene.Permissions.CanRezObject(
719 bool changed =
false;
720 if (inventoryID !=
UUID.Zero)
721 changed = sp.Appearance.DetachAttachment(inventoryID);
722 if (changed && m_scene.AvatarFactory != null)
723 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
725 so.RootPart.Shape.LastAttachPoint = (byte)so.AttachmentPoint;
728 so.FromItemID = UUID.Zero;
730 so.AttachedAvatar = UUID.Zero;
731 so.ClearPartAttachmentData();
735 rootPart.SetParentLocalId(0);
736 so.AbsolutePosition = absolutePos;
737 if (absoluteRot != Quaternion.Identity)
739 so.UpdateGroupRotationR(absoluteRot);
742 rootPart.RemFlag(PrimFlags.TemporaryOnRez);
746 rootPart.Rezzed = DateTime.Now;
748 m_scene.EventManager.TriggerParcelPrimCountTainted();
750 rootPart.ClearUndoState();
752 List<UUID> uuids =
new List<UUID>();
753 uuids.Add(inventoryID);
754 m_scene.InventoryService.DeleteItems(sp.UUID, uuids);
755 sp.ControllingClient.SendRemoveInventoryItem(inventoryID);
758 m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero);
762 so.HasGroupChanged =
true;
763 so.RootPart.ScheduleFullUpdate();
764 so.ScheduleGroupForTerseUpdate();
772 "[ATTACHMENTS MODULE]: Tried to detach object {0} from {1} {2} but attached avatar id was {3} in {4}",
773 so.Name, sp.Name, sp.UUID, so.AttachedAvatar, m_scene.RegionInfo.RegionName);
780 "[ATTACHMENTS MODULE]: Detaching object {0} {1} (FromItemID {2}) for {3} in {4}",
781 so.Name, so.LocalId, so.FromItemID, sp.Name, m_scene.Name);
788 string scriptedState = PrepareScriptInstanceForSave(so,
true);
795 bool changed = sp.Appearance.DetachAttachment(so.FromItemID);
796 if (changed && m_scene.AvatarFactory != null)
797 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
799 sp.RemoveAttachment(so);
800 UpdateDetachedObject(sp, so, scriptedState);
809 sog.UpdateGroupPosition(pos);
810 sog.HasGroupChanged =
true;
815 #region AttachmentModule private methods
822 client.OnRezSingleAttachmentFromInv += Client_OnRezSingleAttachmentFromInv;
823 client.OnRezMultipleAttachmentsFromInv += Client_OnRezMultipleAttachmentsFromInv;
824 client.OnObjectAttach += Client_OnObjectAttach;
825 client.OnObjectDetach += Client_OnObjectDetach;
826 client.OnDetachAttachmentIntoInv += Client_OnDetachAttachmentIntoInv;
827 client.OnObjectDrop += Client_OnObjectDrop;
835 client.OnRezSingleAttachmentFromInv -= Client_OnRezSingleAttachmentFromInv;
836 client.OnRezMultipleAttachmentsFromInv -= Client_OnRezMultipleAttachmentsFromInv;
837 client.OnObjectAttach -= Client_OnObjectAttach;
838 client.OnObjectDetach -= Client_OnObjectDetach;
839 client.OnDetachAttachmentIntoInv -= Client_OnDetachAttachmentIntoInv;
840 client.OnObjectDrop -= Client_OnObjectDrop;
858 grp.HasGroupChanged =
false;
873 "[ATTACHMENTS MODULE]: Updating asset for attachment {0}, attachpoint {1}",
874 grp.UUID, grp.AttachmentPoint);
876 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, scriptedState);
879 item = m_scene.InventoryService.GetItem(item);
884 grp.GetPartName(grp.LocalId),
885 grp.GetPartDescription(grp.LocalId),
886 (sbyte)AssetType.Object,
887 Utils.StringToBytes(sceneObjectXml),
890 if (m_invAccessModule != null)
891 m_invAccessModule.UpdateInventoryItemAsset(sp.UUID, item, asset);
896 sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
899 grp.HasGroupChanged =
false;
901 else if (DebugLevel > 0)
904 "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}",
905 grp.UUID, grp.AttachmentPoint);
921 private void AttachToAgent(
926 "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} at pt {2} pos {3} {4} in {5}",
927 so.Name, sp.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos, m_scene.Name);
930 m_scene.DeleteFromStorage(so.UUID);
931 m_scene.EventManager.TriggerParcelPrimCountTainted();
933 so.AttachedAvatar = sp.UUID;
942 part.RemoveFromPhysics();
946 so.AbsolutePosition = attachOffset;
947 so.RootPart.AttachedPos = attachOffset;
948 so.IsAttachment =
true;
949 so.RootPart.SetParentLocalId(sp.LocalId);
950 so.AttachmentPoint = attachmentpoint;
952 sp.AddAttachment(so);
960 "[ATTACHMENTS MODULE]: Killing private HUD {0} for avatars other than {1} at attachment point {2}",
961 so.Name, sp.Name, so.AttachmentPoint);
965 m_scene.ForEachClient(
968 client.SendKillObject(
new List<uint>() { so.LocalId });
974 so.IsSelected =
false;
976 so.ScheduleGroupForFullUpdate();
981 so.RootPart.RemFlag(PrimFlags.TemporaryOnRez);
992 if (m_invAccessModule == null)
997 "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
998 grp.Name, grp.LocalId, sp.Name);
1001 = m_invAccessModule.CopyToInventory(
1002 DeRezAction.TakeCopy,
1003 m_scene.InventoryService.GetFolderForType(sp.UUID, FolderType.Object).ID,
1004 new List<SceneObjectGroup> { grp },
1005 sp.ControllingClient,
true)[0];
1008 grp.FromItemID = newItem.ID;
1029 private string PrepareScriptInstanceForSave(
SceneObjectGroup grp,
bool fireDetachEvent)
1031 if (fireDetachEvent)
1033 m_scene.EventManager.TriggerOnAttach(grp.LocalId, grp.FromItemID, UUID.Zero);
1039 using (StringWriter sw =
new StringWriter())
1041 using (XmlTextWriter writer =
new XmlTextWriter(sw))
1043 grp.SaveScriptedState(writer);
1046 return sw.ToString();
1059 = sp.PresenceType != PresenceType.Npc
1060 && (m_scene.UserManagementModule == null
1061 || m_scene.UserManagementModule.IsLocalGridUser(sp.UUID));
1067 m_scene.DeleteSceneObject(so,
false,
false);
1070 so.AttachedAvatar = UUID.Zero;
1071 so.RootPart.SetParentLocalId(0);
1072 so.IsAttachment =
false;
1078 so.ForEachPart(x => { x.GroupPosition = so.RootPart.AttachedPos; });
1080 UpdateKnownItem(sp, so, scriptedState);
1084 so.RemoveScriptInstances(
true);
1089 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt,
bool append, XmlDocument doc)
1091 if (m_invAccessModule == null)
1096 if (itemID !=
UUID.Zero)
1097 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
1098 itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1,
true,
1099 false,
false, sp.
UUID,
true);
1101 objatt = m_invAccessModule.RezObject(sp.ControllingClient,
1102 null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1,
true,
1103 false,
false, sp.
UUID,
true);
1108 "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}",
1109 itemID, sp.Name, attachmentPt);
1113 else if (itemID ==
UUID.Zero)
1118 objatt.FromItemID = UUID.Random();
1123 "[ATTACHMENTS MODULE]: Rezzed single object {0} with {1} prims for attachment to {2} on point {3} in {4}",
1124 objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name);
1127 objatt.HasGroupChanged =
false;
1128 bool tainted =
false;
1142 objatt.LoadScriptState(doc);
1143 objatt.ResetOwnerChangeFlag();
1146 AttachObjectInternal(sp, objatt, attachmentPt,
false,
true,
true, append);
1151 "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}",
1152 objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace);
1155 sp.RemoveAttachment(objatt);
1156 m_scene.DeleteSceneObject(objatt,
false);
1161 objatt.HasGroupChanged =
true;
1163 if (ThrottlePer100PrimsRezzed > 0)
1165 int throttleMs = (int)Math.Round((
float)objatt.
PrimCount / 100 * ThrottlePer100PrimsRezzed);
1169 "[ATTACHMENTS MODULE]: Throttling by {0}ms after rez of {1} with {2} prims for attachment to {3} on point {4} in {5}",
1170 throttleMs, objatt.Name, objatt.PrimCount, sp.Name, attachmentPt, m_scene.Name);
1172 Thread.Sleep(throttleMs);
1191 if (
UUID.Zero == itemID)
1193 m_log.Error(
"[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID.");
1197 if (0 == AttachmentPt)
1199 m_log.Error(
"[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point.");
1204 item = m_scene.InventoryService.GetItem(item);
1208 int attFlag = append ? 0x80 : 0;
1209 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.
AssetID);
1210 if (changed && m_scene.AvatarFactory != null)
1214 "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()",
1215 sp.Name, att.Name, AttachmentPt);
1217 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
1223 #region Client Event Handlers
1225 private ISceneEntity Client_OnRezSingleAttachmentFromInv(
IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
1232 "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}",
1235 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
1240 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()",
1241 remoteClient.Name, remoteClient.AgentId);
1245 return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt);
1248 private void Client_OnRezMultipleAttachmentsFromInv(
IClientAPI remoteClient, List<KeyValuePair<UUID, uint>> rezlist)
1253 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
1255 RezMultipleAttachmentsFromInventory(sp, rezlist);
1258 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()",
1259 remoteClient.Name, remoteClient.AgentId);
1262 private void Client_OnObjectAttach(
IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt,
bool silent)
1266 "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})",
1267 objectLocalID, remoteClient.Name, AttachmentPt, silent);
1274 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
1279 "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId);
1288 if (!m_scene.Permissions.CanTakeObject(part.
UUID, remoteClient.
AgentId))
1290 remoteClient.SendAgentAlertMessage(
1291 "You don't have sufficient permissions to attach this object",
false);
1296 bool append = (AttachmentPt & 0x80) != 0;
1297 AttachmentPt &= 0x7f;
1300 if (AttachObject(sp, part.
ParentGroup, AttachmentPt,
false,
true, append))
1304 "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
1305 +
", AttachmentPoint: " + AttachmentPt);
1308 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
1313 m_log.ErrorFormat(
"[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace);
1317 private void Client_OnObjectDetach(uint objectLocalID,
IClientAPI remoteClient)
1322 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
1325 if (sp != null && group != null && group.FromItemID !=
UUID.Zero)
1326 DetachSingleAttachmentToInv(sp, group);
1329 private void Client_OnDetachAttachmentIntoInv(UUID itemID,
IClientAPI remoteClient)
1334 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
1337 List<SceneObjectGroup> attachments = sp.GetAttachments();
1343 DetachSingleAttachmentToInv(sp, group);
1350 private void Client_OnObjectDrop(uint soLocalId,
IClientAPI remoteClient)
1355 ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId);
1357 DetachSingleAttachmentToGround(sp, soLocalId);
UUID FromItemID
The item ID that this object was rezzed from, if applicable.
SceneObjectGroup RezSingleAttachmentFromInventoryInternal(IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append, XmlDocument doc)
IClientAPI ControllingClient
bool HasPrivateAttachmentPoint
If this scene object has an attachment point then indicate whether there is a point where attachments...
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void DeleteAttachmentsFromScene(IScenePresence sp, bool silent)
Delete all the presence's attachments from the scene This is done when a root agent leaves/is demoted...
OpenSim.Server.Handlers.Simulation.Utils Utils
bool HasGroupChanged
This indicates whether the object has changed such that it needs to be repersisted to permenant stora...
string Name
Returns the full name of the agent/avatar represented by this client
void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos)
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool addToInventory, bool append)
Attach an object to an avatar.
void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId)
Detach the given item to the ground.
void UnsubscribeFromClientEvents(IClientAPI client)
void RemoveAttachment(SceneObjectGroup gobj)
PresenceType
Indicate the type of ScenePresence.
bool IsActive
True if the client is active (sending and receiving new UDP messages). False if the client is being c...
Asset class. All Assets are reference by this class or a class derived from this class ...
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
Object AttachmentsSyncLock
The AttachmentsModule synchronizes on this to avoid race conditions between commands to add and remov...
void CopyAttachments(AgentData ad, IScenePresence sp)
Copy attachment data from an AgentData structure into a ScenePresence.
List< SceneObjectGroup > GetAttachments()
The scene objects attached to this avatar.
int PrimCount
Number of prims in this group
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
void CopyAttachments(IScenePresence sp, AgentData ad)
Copy attachment data from a ScenePresence into the AgentData structure for transmission to another si...
List< ISceneObject > AttachmentObjects
ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
Rez an attachment from user inventory and change inventory status to match.
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
uint AttachmentPoint
Attachment point of this scene object to an avatar.
Inventory Item - contains all the properties associated with an individual inventory piece...
AvatarAppearance Appearance
Avatar appearance data.
void SubscribeToClientEvents(IClientAPI client)
PhysicsActor PhysActor
The representation of this part in the physics scene.
bool IsNPC(UUID agentID, Scene scene)
Check if the agent is an NPC.
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
Interactive OpenSim region server
SceneObjectGroup ParentGroup
IClientAPI ControllingClient
void DetachSingleAttachmentToInv(IScenePresence sp, SceneObjectGroup so)
Detach the given attachment so that it remains in the user's inventory.
void DeRezAttachments(IScenePresence sp)
Derez the attachements for a scene presence that is closing.
int GetSittingAvatarsCount()
Gets the number of sitting avatars.
UUID AttachedAvatar
The avatar to which this scene object is attached.
void RezMultipleAttachmentsFromInventory(IScenePresence sp, List< KeyValuePair< UUID, uint >> rezlist)
Rez multiple attachments from a user's inventory
void RezAttachments(IScenePresence sp)
RezAttachments. This should only be called upon login on the first region. Attachment rezzings on cro...
void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId, Vector3 absolutePos, Quaternion absoluteRot)
Detach the given item to the ground at the specified coordinates & rotation
bool IsAttachment
Is this scene object acting as an attachment?
PresenceType PresenceType
What type of presence is this? User, NPC, etc.
ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt, XmlDocument doc)